C++ Windbg型铸造

C++ Windbg型铸造,c++,windbg,C++,Windbg,我想在命令窗口中键入将子类的对象强制转换为WinDbg中的父类 示例类 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

我想在命令窗口中键入将子类的对象强制转换为WinDbg中的父类

示例类

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){}
};
我正在使用Windbg,我正在阅读帮助文件。它显示在C++数字和运算符下,我可以从WEBBG命令窗口执行以下类型的转换:

dynamic_cast <type>(Value) 
static_cast <type>(Value) 
reinterpret_cast <type>(Value) 
const_cast <type>(Value)
(type) Value
?? (type) Value
有效的是

?? (char)a
?? static_cast<char>(a)
返回的错误是

“”处的类型冲突错误

如果我做一个
xmod*我得到一个巨大的列表,列表中有

MOD!parent
MOD!child
如果我做一个
??chld
然后对象会很好地转储到屏幕上

我为什么要这么做?嗯,你能行

??chld.childattr++
所以我想实际执行
??((父)chld.parentattr++

windbg帮助说明:

<> C++表达式中的符号

在C++表达式中,每个符号根据其类型来解释。根据符号所指的内容,它可能被解释为整数、数据结构、函数指针、或任何其他数据类型。如果使用与C++表达式中的C++数据类型(如未修改的模块名)不符的符号,则会出现语法错误。

因此,我认为没有理由不能将对象类型强制转换为父数据类型

我做了很多搜索,但没有找到任何真正的答案,如果有人能给我指出正确的方向,这样我就可以了解为什么这样做应该或不应该有效,或者我需要做什么才能成功,甚至为什么这不是我应该从WinDbg期待的事情


编辑:添加代码示例。

代码、代码片段或任何在其他机器上某种程度上可复制的东西可以提供更可靠、更清晰的答案,而不是枯燥的理论问题

我认为您的问题属于pe头是否可以作为_eprocess结构转储的类型

如果是这样,你可以做这样的事情

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....$"
尽管仍然不知所措,但这篇编辑是对编辑后的问题的回应

演练的完整源代码 您的父类稍加修改,以消除未引用的参数警告和输出歧义,并在main函数中使用

:\>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;
}
在windbg下加载它,并逐步升级到printf,以便所有本地 已正确初始化

:\>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);
<>用C++ Exp评估器< /P>评价所有本地人
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
单独检查

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 pointer to a class
课程类型是什么

somefoo
?? (somefoo *) should be used

<强>以便在C++表达式计算器< /强>

中显示指向某个Fooo的指针
somefoo
?? (somefoo *) should be used
指针需要地址或计算结果为地址的表达式

somefoo
?? (somefoo *) should be used

<强> LILSIS、PAPA、FANFO等是MASM和C++评价者>/P>中都可以解释的表达式。 为了避免歧义<代码>,我们需要明确地指出LILSIS等需要被评估为MASM表达式而不是C++表达式,因为?试图解释LILSIS,作为C++表达式<代码> > BR> 那么完整的表达式将是

??(somefoo*)@@(someotherfoo)

注意
@@only
足以指示masm表达式,但为了进一步避免歧义,最好明确指定表达式计算器
,如@masm(,@@c++)(

请参见下文,一个单一的?on类指针返回一个地址,一个?返回类型

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>
这不仅适用于类,也适用于使用dt显示的
类型

nt!\u下面以不同场景的电子流程为例进行操作

lkd>??((nt!_EPROCESS)@$proc)->ImageFileName

Type conflict error at ')->ImageFileName'
unsigned char [16] 0x86305f14
0x6b 'k'
char * 0x86305f14
 "kd.exe"
Couldn't resolve error at 'nt)->ImageFileName'
char * 0x804d7174
 ""
long 0n372
lkd>??((nt!_EPROCESS*)@$proc)->ImageFileName

Type conflict error at ')->ImageFileName'
unsigned char [16] 0x86305f14
0x6b 'k'
char * 0x86305f14
 "kd.exe"
Couldn't resolve error at 'nt)->ImageFileName'
char * 0x804d7174
 ""
long 0n372
lkd>??(字符*)((nt!\u电子处理*)@$proc)->ImageFileName

Type conflict error at ')->ImageFileName'
unsigned char [16] 0x86305f14
0x6b 'k'
char * 0x86305f14
 "kd.exe"
Couldn't resolve error at 'nt)->ImageFileName'
char * 0x804d7174
 ""
long 0n372
lkd>??(char*)((nt!\u EPROCESS*)nt)->ImageFileName

Type conflict error at ')->ImageFileName'
unsigned char [16] 0x86305f14
0x6b 'k'
char * 0x86305f14
 "kd.exe"
Couldn't resolve error at 'nt)->ImageFileName'
char * 0x804d7174
 ""
long 0n372
lkd>??(字符*)((nt!\u电子处理*)@@(nt))->ImageFileName

Type conflict error at ')->ImageFileName'
unsigned char [16] 0x86305f14
0x6b 'k'
char * 0x86305f14
 "kd.exe"
Couldn't resolve error at 'nt)->ImageFileName'
char * 0x804d7174
 ""
long 0n372
字段偏移量(nt!\u EPROCESS,ImageFileName)

lkd>?0n372

Evaluate expression: 372 = 00000174
lkd>?@@c++(字段偏移量(nt!\U EPROCESS,ImageFileName))+nt

Evaluate expression: -2142408332 = 804d7174
Couldn't resolve error at 'nt'
unsigned int64 0xffffffff`804d7174
lkd> 
lkd>??@@c++(字段偏移量(nt!\U EPROCESS,ImageFileName))+nt

Evaluate expression: -2142408332 = 804d7174
Couldn't resolve error at 'nt'
unsigned int64 0xffffffff`804d7174
lkd> 
lkd>??@@c++(字段偏移量(nt!\U电子进程,图像文件名))++(nt)


我理解这个问题的方法是:它是用内置数据类型工作的,而不是C++自定义类。是的,Thomas W.在我所要求的是正确的。我将编辑这个问题并添加示例。谢谢你的回应。Babb.增加了一点可重复的编辑到我原来的答案。看看它是否帮助感谢Babb,?(Prime*)@ @ Masm(CHLD)。这正是我想要的。感谢blabb跟进并发布带有源代码的酷示例。