如果我在64位.Net进程转储的已知内存地址处有System.Int32,如何在windbg中的条件或表达式中引用其数据?例如:
? poi(000000ba2e4de938) == 0n27
显示为0而不是1,即使我知道该地址的值为27(dt int 000000ba2e4de938
显示0n27)。它正在这样做,因为它在我试图访问的值之后拾取了32个垃圾位,因为它会抓取指针大小的数据。
有没有办法获取特定大小的数据才能在表达式中使用?到目前为止,我只找到了转储数据的方法,但没有在表达式或条件中使用它。
答案 0 :(得分:2)
简答:使用dwo(...)
表示32位,qwo(...)
表示64位,poi(...)
表示体系结构相关的大小。
答案很长:
让我们先看一下带有SOS的Int32:
0:014> .symfix
0:014> .reload
0:014> .loadby sos clr
0:006> !name2ee *!System.Int32
Module: 000007feecab1000
Assembly: mscorlib.dll
Token: 00000000020000f0
MethodTable: 000007feed1603d0
EEClass: 000007feecb71810
Name: System.Int32
[...]
0:006> !dumpheap -mt 000007feed1603d0
Address MT Size
00000000028376d8 000007feed1603d0 24
0:006> !do 00000000028376d8
Name: System.Int32
MethodTable: 000007feed1603d0
EEClass: 000007feecb71810
Size: 24(0x18) bytes
File: C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
MT Field Offset Type VT Attr Value Name
000007feed1603d0 400055f 8 System.Int32 1 instance 8868 m_value
从该输出中,您可以看到Int32的值(m_value
)位于对象的地址+偏移量为8。
Int32的长度是32位,所以我们需要dd
(转储DWORD)来查看内存:
0:006> dd 00000000028376d8+8 L1
00000000`028376e0 000022a4
将其转换为十进制,它将是SOS之前显示的内容:
0:006> ? 22a4
Evaluate expression: 8868 = 00000000`000022a4
要在条件中使用它,请使用dwo
(DWORD大小)而不是poi
(指针大小,64位为qwo
):
0:006> ? dwo(00000000028376d8+8)
Evaluate expression: 8868 = 00000000`000022a4