- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我想在命令窗口的 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++ 数字和运算符下显示我可以从 WinDbg 命令窗口执行以下类型转换:
dynamic_cast <type>(Value)
static_cast <type>(Value)
reinterpret_cast <type>(Value)
const_cast <type>(Value)
(type) Value
所以我会在 Windbg 命令窗口中输入:
?? (type) Value
有效的是
?? (char)a
?? static_cast<char>(a)
a 是一个整数。
没用的是
?? (parent)chld
?? static_cast<parent>(chld)
?? static_cast<mod!parent>(chld)
chld 是子类的对象,子类继承父类。
对象示例:
child chld;
返回的错误是
Type conflict error at '<EOL>'
如果我执行 x mod!*
我会得到一个巨大的列表,该列表中有
MOD!parent
MOD!child
如果我做一个 ?? chld
然后对象就会被转储到屏幕上。
我为什么要这样做?好吧,你可以做到
?? chld.childattr++
所以我真的想做 ?? ((parent)chld).parentattr++
windbg 帮助说:
Symbols in C++ Expressions
In a C++ expression, each symbol is interpreted according to its type. Depending on what the symbol refers to, it might be interpreted as an integer, a data structure, a function pointer, or any other data type. If you use a symbol that does not correspond to a C++ data type (such as an unmodified module name) within a C++ expression, a syntax error occurs.
所以我认为没有理由不能将对象类型转换为父数据类型。
我做了很多搜索,但没有真正找到答案,如果有人能给我指出正确的方向,这样我就可以了解为什么这应该或不应该起作用,或者我需要做什么才能成功甚至为什么这不是我对 WinDbg 的期望。
已编辑:添加代码示例。
最佳答案
代码、片段或任何在其他机器上在某种程度上可重现的东西都可以提供更稳健和清晰的答案,而不是枯燥的理论问题
我将你的问题解释为 can pe header be dumped as _eprocess structure
如果是这样你可以做这样的事情
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;
}
编译、链接和执行以显示输出
:\>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 以便所有本地人已正确初始化
:\>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 计算器计算所有局部变量
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
因此在 C++ 表达式计算器中显示指向 somefoo 的指针
?? (somefoo *) should be used
指针需要一个地址或计算结果为地址的表达式
lilsis、papa、somefoo 等是可以在 masm 和 c++ 求值器中解释的表达式
所以为了避免歧义我们需要明确声明 lilsis 等需要被评估为 masm 表达式而不是 c++ 表达式,因为 ??尝试将 lilsis 和 somefoo 解释为 C++ 表达式
所以完整的表达式将是 ?? (somefoo *) @@(someotherfoo)
注意 @@ only
足以指示 masm 表达式,但为了进一步避免歧义,明确指定表达式求值器 是一个好习惯,如 @@masm( , @@c++(
等等
看下面单?在类指针上返回一个地址和一个??返回类型
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!_eprocess为例
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
会怎样>? 0n372
Evaluate expression: 372 = 00000174
会怎样>? @@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>
关于c++ - Windbg类型类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27050080/
我正在尝试分析一些小型故障转储。我使用的是 Windows 10 Pro Build 1607 和 WinDbg 10.0.14321.1024。我的符号文件路径设置为 SRV*C:\SymCache
我正在尝试追踪谁在进行特定大小的分配,我尝试使用用户模式堆栈跟踪数据库 (gflags +ust),但由于 FPO,我无法看到整个堆栈。因此,我想在 RtlAllocateHeap 达到我正在寻找的分
是否可以搜索整个可执行内存空间以找到调用特定方法的所有位置?例如,我想从调用 MyApplcation!MyFunction 的位置查找所有函数。使用“s”命令搜索特定的 optcode 不是一个选项
我在我的程序中遇到了一个 stackoverflow 异常,它可能来自第三方库 microsoft.sharepoint.client.runtime.dll。 使用 adplus 创建故障转储,我面
是否有任何扩展命令可以这样做?我只想包含所有参数的整个命令行。 最佳答案 命令行参数等信息存储在 PEB 中(进程环境块)。 您可以找到 a list of common commands here.
在 OllyDbg 中,它允许你运行直到返回,例如你遇到了 ret或 leave操作说明。 WinDbg 支持吗?我在菜单中没有找到这样的功能。 最佳答案 如果您想在返回之前停止,可以使用pt .如果
我正在尝试使用 d* 命令评估 WindDbg 中调用堆栈的内容。我知道我要转储的数据的地址是 [ebp+8] .但是,当使用此命令时,WinDbg 以 8 字节偏移量在 ebp 处转储数据。我想转储
有没有办法告诉 WinDbg 忽略由 DebugBreak function 引起的程序断点? 最佳答案 看看 Controlling Exceptions and Events MSDN 上的页面。
我尝试在 c# 应用程序的源代码中使用 WinDbg 设置断点,但没有成功。 当我使用 WinDbg 时,有没有办法在托管应用程序的源代码处设置断点? 复制步骤如下: 1.制作一个简单的c#应用程序
我正在尝试使用 WinDBG 检查可执行文件的程序集,但我很难找到它。我想在程序的第一条指令处设置断点,但是当我尝试手动执行此操作(使用模块的地址)时,WinDBG 告诉我它“无法在该位置插入断点”,
我正在逆向一个 win32 应用程序。 问题: 调试程序时。我发现计数器曾经跳转到地址 0x0043D4A0。 (这是一个函数入口点)。 0043D4A0 51 P
作为驱动程序开发人员,WinDbg 是我最好的 friend 之一。 现在从 Windows 8 开始,我安装了新的 WDK 并想使用它的新 WinDbg。它具有一些不错的功能,例如通过网络进行远程调
我需要调试在 Windows 上运行的正在运行的程序。它有时会因“内存访问冲突”而崩溃。 使用 windbg(无法使用 IDE)我附加到正在运行的进程(这是程序不得停止的要求) 命令行是 windbg
我正在调查 WinDBG 中的 Windows 转储文件。我可以通过命令 .frame 切换调用堆栈帧,但我发现寄存器始终包含最后一个上下文。我的意思是,是否可以恢复属于非顶级调用堆栈帧的特定调用堆栈
我正在调试一个模块,该模块只有 .exe 和 .pdb,没有私有(private)符号。 在调试 session 期间,我需要检查内部结构。显然这个结构不会出现在 PDB 中,因为它是私有(priva
Intel Power Gadget该工具无法在我的系统上运行,我正试图找出原因。它是运行 Window 8.1 x64 的 Core i7-720QM。 AIDA64 可以很好地读取 CPU 温度,
我在程序中遇到访问冲突。 Windbg 显示程序正在尝试读取 0x09015000 .它在地址旁边显示问号 ( ?? )。我的问题是,这些问号表示什么。它们是否意味着从未分配过内存位置,即它不受任何物
如何将命令窗口的内容直接保存到日志文件中而不在WinDbg的命令窗口显示这些内容? 最佳答案 假设您还不知道这一点,您可以使用 -log{o|a} windbg command line选项来指定您希
我使用的是 WinDBG 6.12.0002.633 X86。 我遇到了命令行调试器 CDB 的问题,它没有显示与 k 的 WinDBG 相同的结果。和 kL命令。 在 WinDBG 中,k命令正确显
我正在开发一个 32 位应用程序,它有时会导致某些 64 位 Windows 7 机器崩溃。我使用 Sysinternals 的 ProcDump 实用程序生成了崩溃的转储文件。 (我使用了命令“pr
我是一名优秀的程序员,十分优秀!