首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Windbg型铸件

Windbg型铸件
EN

Stack Overflow用户
提问于 2014-11-20 21:40:11
回答 1查看 3.6K关注 0票数 3

我想在命令窗口中将子类的对象类型转换为WinDbg中的父类。

示例类

代码语言:javascript
复制
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++数字和运算符下面显示,我可以在WinDbg命令窗口中完成以下类型设置:

代码语言:javascript
复制
dynamic_cast <type>(Value) 
static_cast <type>(Value) 
reinterpret_cast <type>(Value) 
const_cast <type>(Value)
(type) Value

因此,我将输入Windbg命令窗口:

代码语言:javascript
复制
?? (type) Value

起作用的是

代码语言:javascript
复制
?? (char)a
?? static_cast<char>(a)

其中a是整数。

不起作用的是

代码语言:javascript
复制
?? (parent)chld
?? static_cast<parent>(chld)
?? static_cast<mod!parent>(chld)

其中chld是类子对象,子继承类父级。

对象示例:

代码语言:javascript
复制
child chld;

返回的错误是

在“”处键入冲突错误

如果我做了一个x mod!*,我会得到一个巨大的列表,在这个列表中

代码语言:javascript
复制
MOD!parent
MOD!child

如果我做了一个?? chld,那么这个对象就会被转储到屏幕上。

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

?? chld.childattr++,所以我真的很想做?? ((parent)chld).parentattr++

风车帮手说:

C++表达式中的符号 在C++表达式中,每个符号都根据其类型进行解释。根据符号所引用的内容,可以将其解释为整数、数据结构、函数指针、或任何其他数据类型。如果在C++表达式中使用不对应于C++数据类型(如未修改的模块名称)的符号,则会发生语法错误。

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

我进行了大量的搜索,但没有找到任何结果,如果有人能为我指明正确的方向,这样我就可以读到为什么应该或不应该这样做,或者我需要做些什么才能成功,甚至为什么这不是我应该从WinDbg得到的东西。

编辑:以添加代码示例。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-11-22 04:15:02

代码、代码片段或在其他机器中某种程度上可重复的任何内容都可以提供更健壮和清晰的答案,而不是枯燥的理论问题。

我将您的问题解释为可以将pe头转储为_eprocess结构的类型。

如果是这样的话,你可以这样做

代码语言:javascript
复制
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中使用。

代码语言:javascript
复制
:\>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;
}

编译、链接和执行以显示输出

代码语言:javascript
复制
:\>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 `

将其加载到windbg下,并逐步升级到printf,以便所有局部变量都被正确初始化。

代码语言:javascript
复制
:\>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评估器评估所有局部变量

代码语言:javascript
复制
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

单独检查

代码语言:javascript
复制
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>

可能导致解决方案的一系列问题和答案

我们想显示什么?

代码语言:javascript
复制
a pointer to a class

类的类型是什么?

代码语言:javascript
复制
somefoo

以便在c++表达式计算器中显示指向某某页脚的指针。

代码语言:javascript
复制
?? (somefoo *) should be used

指针需要一个计算为地址的地址或表达式。

lilsis”、“爸爸”、“a both”等是masm和c++求值器中都可以解释的表达式。

所以为了避免歧义,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

所以完整的表达式将是?? (somefoo *) @@(someotherfoo)

注意,@@ only足以指示masm表达式,但为了进一步避免歧义,指定表达式计算器、explicitly like @@masm( , @@c++(等是一个好习惯。

看到下面的单机了吗?在类指针上返回地址和??返回类型

代码语言:javascript
复制
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>

这不仅适用于类,也适用于types displayed with dt

下面以nt!_eprocess为例对不同的场景进行操作。

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

代码语言:javascript
复制
Type conflict error at ')->ImageFileName'

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

代码语言:javascript
复制
unsigned char [16] 0x86305f14
0x6b 'k'

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

代码语言:javascript
复制
char * 0x86305f14
 "kd.exe"

lkd>?((nt!_EPROCESS *) nt)->ImageFileName

代码语言:javascript
复制
Couldn't resolve error at 'nt)->ImageFileName'

lkd>?((nt!_EPROCESS *) @@(nt))->ImageFileName

代码语言:javascript
复制
char * 0x804d7174
 ""

??#FIELD_OFFSET(nt!_EPROCESS,ImageFileName)

代码语言:javascript
复制
long 0n372

lkd>?0n372

代码语言:javascript
复制
Evaluate expression: 372 = 00000174

lkd>?@@c++(#FIELD_OFFSET(nt!_EPROCESS,ImageFileName)) + nt

代码语言:javascript
复制
Evaluate expression: -2142408332 = 804d7174

lkd> ??@@c++(#FIELD_OFFSET(nt!_EPROCESS,ImageFileName)) + nt

代码语言:javascript
复制
Couldn't resolve error at 'nt'

lkd> ??@@c++(#FIELD_OFFSET(nt!_EPROCESS,ImageFileName)) + @@(nt)

代码语言:javascript
复制
unsigned int64 0xffffffff`804d7174
lkd> 
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27050080

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档