Die Casting Windbg
I would like to inject the object type of the child class into the parent class in WinDbg in the command window.
Examples of classes
class parent
{
public:
int a;
int b;
parent(){ a = 10; b = 10; }
parent(int c) : a(a){}
};
class child : public parent
{
public:
int a;
int b;
child(){ a = 20; b = 20; }
child(int d) : b(d){}
};
I am using Windbg and I was reading the help file. It shows in C ++ Numbers and Operators that I can do the following input types from a WinDbg window:
dynamic_cast <type>(Value)
static_cast <type>(Value)
reinterpret_cast <type>(Value)
const_cast <type>(Value)
(type) Value
So, I would print the Windbg command prompt window:
?? (type) Value
What works
?? (char)a
?? static_cast<char>(a)
where a is int.
What does not work
?? (parent)chld
?? static_cast<parent>(chld)
?? static_cast<mod!parent>(chld)
where chld is an object of class child and child, inherits from the parent class.
Object example:
child chld;
Returned error:
Enter conflict error in '<EOL>'
If I do x mod!*
, I get a giant list, on this list
MOD!parent
MOD!child
If I do ?? chld
, then the object gets reset to the screen just fine.
Why would I like to do this? Well you can do
?? chld.childattr++
and so I would really like to do ?? ((parent)chld).parentattr++
Windbg helper says:
Symbols in C ++ Expressions
In a C ++ expression, each character is interpreted according to its type. Depending on what the symbol is pointing to, it can be interpreted as an integer, data structure, function pointer, or any other data type . If you use a character that does not match the C ++ data type (for example, the name of an unmodified module) in a C ++ expression, a syntax error occurs.
So I see no reason why I shouldn't have to inject the object type into parent data.
I searched a lot and it really didn't work out if someone could point me in the right direction so that I can read why this should or should not work, or maybe what I need to do to be successful or even why is this not what I should expect from WinDbg.
Edited: To add sample code.
code, snippet, or anything reproducible to some extent on other machines can provide more reliable and clear answers instead of dry theoretical questions
I am interpreting your question as a type that can be compiled as a _proprocess structure
if so you can do something like this
lkd> ?? (char *)@$proc->ImageFileName
char * 0x866be194
"windbg.exe"
lkd> lm m windbg
start end module name
01000000 01097000 windbg (pdb symbols)
lkd> db windbg l10
01000000 4d 5a 90 00 03 00 00 00-04 00 00 00 ff ff 00 00 MZ..............
lkd> da windbg+4e
0100004e "This program cannot be run in DO"
0100006e "S mode....$"
lkd> ?? (char *)((nt!_EPROCESS *) @@masm(windbg - 174+4e) )->ImageFileName
char * 0x0100004e
"This program cannot be run in DOS mode....$"
although still at a loss this is an edit in response to an edited question
complete source to pass your parent class slightly modified to exclude undefined warning and output error, and use the inner main function
:\>type parchiltst.cpp
#include <stdio.h>
class parent
{
public:
int a;
int b;
parent(){ a = 35; b = 28; }
parent(int c) : a(c){}
};
class child : public parent
{
public:
int a;
int b;
child(){ a = 20; b = 20; }
child(int d) : b(d){}
};
int main (void) {
parent par,papa,mama,gramp;
child chill,bigbro,lilsis,crybab;
par.a=70;par.b=65;chill.a=4;chill.b=8;
gramp=parent(par); papa=parent(); mama=parent(1234);
bigbro=child(chill);lilsis=child();crybab=child(5678);
printf("%d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
chill.a,chill.b,gramp.a,gramp.b,papa.a,papa.b,mama.a,mama.b,
bigbro.a,bigbro.b,lilsis.a,lilsis.b,crybab.a,crybab.b);
return 0;
}
compiled, linked and executed to show the output
:\>cl /Zi /nologo /W4 /analyze parchiltst.cpp /link /RELEASE
parchiltst.cpp
:\>parchiltst.exe
4 8 70 65 35 28 1234 0 4 8 20 20 196608 5678 `
load it under windbg and go to printf so that all locals are properly initialized
:\>cdb parchiltst.exe
0:000> g main
parchiltst!main:
00401000 55 push ebp
0:000> dv -V -t -i
prv local 0013ff18 @ebp-0x60 class child lilsis = class child
prv local 0013ff28 @ebp-0x50 class parent par = class parent
prv local 0013ff30 @ebp-0x48 class parent gramp = class parent
prv local 0013ff38 @ebp-0x40 class parent papa = class parent
prv local 0013ff40 @ebp-0x38 class parent mama = class parent
prv local 0013ff48 @ebp-0x30 class child chill = class child
prv local 0013ff58 @ebp-0x20 class child bigbro = class child
prv local 0013ff68 @ebp-0x10 class child crybab = class child
0:000> .lines
Line number information will be loaded
0:000> l+*
0:000> p
> 19: parent par,papa,mama,gramp;
0:000>
> 20: child chill,bigbro,lilsis,crybab;
0:000>
> 21: par.a=70;par.b=65;chill.a=4;chill.b=8;
0:000>
> 22: gramp=parent(par); papa=parent(); mama=parent(1234);
0:000>
> 23: bigbro=child(chill);lilsis=child();crybab=child(5678);
0:000>
> 26: bigbro.a,bigbro.b,lilsis.a,lilsis.b,crybab.a,crybab.b);
evaluating all locales with the C ++ exp analyzer
0:000> !for_each_local "?? @#Local"
class child
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n4
+0x00c b : 0n8
class child
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n4
+0x00c b : 0n8
class child
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n2090270496
+0x00c b : 0n5678
class parent
+0x000 a : 0n70
+0x004 b : 0n65
class child
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n20
+0x00c b : 0n20
class parent
+0x000 a : 0n1234
+0x004 b : 0n0
class parent
+0x000 a : 0n35
+0x004 b : 0n28
class parent
+0x000 a : 0n70
+0x004 b : 0n65
check individually
0:000> ?? ((child *) @@masm(mama))->a
int 0n35
0:000> ?? ((parent *) @@masm(mama))->a
int 0n1234
0:000> ?? ((parent *) @@masm(papa))->a
int 0n35
0:000> ?? ((child *) @@masm(papa))->a
int 0n1234
0:000> ?? ((child *) @@masm(lilsis))->a
int 0n20
0:000> ?? ((parent *) @@masm(lilsis))->a
int 0n35
0:000> ?? ((parent *) @@masm(lilsis))
class parent * 0x0013ff18
+0x000 a : 0n35
+0x004 b : 0n28
0:000> ?? ((child *) @@masm(lilsis))
class child * 0x0013ff18
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n20
+0x00c b : 0n20
0:000> ?? ((child *) @@masm(mama))
class child * 0x0013ff40
+0x000 a : 0n1234
+0x004 b : 0n0
+0x008 a : 0n35
+0x00c b : 0n28
0:000> ?? ((parent *) @@masm(mama))
class parent * 0x0013ff40
+0x000 a : 0n1234
+0x004 b : 0n0
0:000>
a trail of questions and answers that can lead to solutions
what do we want to display?
a pointer to a class
what type of class
somefoo
to map a pointer to somefoo in the evaluation of a c ++ expression
?? (somefoo *) should be used
a pointer needs an address or an expression that evaluates to an address
lilsis, papa, somefoo, etc. are expressions that can be interpreted for both masm evaluators and C ++
to avoid ambiguity, we need to explicitly state that lilsis etc needs to be evaluated as masm expression not as c++ expression because ?? tries to interpret lilsis , somefoo as c++ expression
therefore the full expression would be?? (somefoo *) @@(someotherfoo)
notice is @@ only
sufficient to indicate the expression masm, but to avoid ambiguity it is a good habit to indicate the evaluations of expressions explicitly like @@masm( , @@c++(
, etc.
see below single? by class pointer returns address and a? return the type
0:000> ? mama
Evaluate expression: 1310528 = 0013ff40
0:000> ?? mama
class parent
+0x000 a : 0n1234
+0x004 b : 0n0
0:000> ?? lilsis
class child
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n20
+0x00c b : 0n20
0:000> ? lilsis
Evaluate expression: 1310488 = 0013ff18
0:000> ?? @@(mama)
unsigned int64 0x13ff40
0:000> ?? @@masm(mama)
unsigned int64 0x13ff40
0:000> ?? @@c++(mama)
class parent
+0x000 a : 0n1234
+0x004 b : 0n0
0:000> ?? @@c++(crybab)
class child
+0x000 a : 0n35
+0x004 b : 0n28
+0x008 a : 0n2090270496
+0x00c b : 0n5678
0:000>
this applies not only to the class but also to types displayed with dt
nt! _prorocess is processed below for different scenarios as an example
lkd> ?? ((nt! _EPROCESS) @ $ proc) โ ImageFileName
Type conflict error at ')->ImageFileName'
lkd> ?? ((nt! _EPROCESS *) @ $ proc) โ ImageFileName
unsigned char [16] 0x86305f14
0x6b 'k'
lkd> ?? (char *) ((nt! _EPROCESS *) @ $ proc) โ ImageFileName
char * 0x86305f14
"kd.exe"
lkd> ?? (char *) ((nt! _EPROCESS *) nt) โ ImageFileName
Couldn't resolve error at 'nt)->ImageFileName'
lkd> ?? (char *) ((nt! _EPROCESS *) @@ (nt)) โ ImageFileName
char * 0x804d7174
""
?? #FIELD_OFFSET (nt! _EPROCESS, ImageFileName)
long 0n372
lkd>? 0n372
Evaluate expression: 372 = 00000174
lkd>? @@ C ++ (# FIELD_OFFSET (nt! _EPROCESS, ImageFileName)) + nt
Evaluate expression: -2142408332 = 804d7174
lkd> ?? @@ C ++ (# FIELD_OFFSET (nt! _EPROCESS, ImageFileName)) + nt
Couldn't resolve error at 'nt'
lkd> ?? @@ C ++ (# FIELD_OFFSET (nt! _EPROCESS, ImageFileName)) + @@ (nt)
unsigned int64 0xffffffff`804d7174
lkd>