C++ 如何从对象/类中查找第一个字段?
早上好, 在中,我一直在寻找一种在转储中查找C++ 如何从对象/类中查找第一个字段?,c++,windbg,dump,pykd,C++,Windbg,Dump,Pykd,早上好, 在中,我一直在寻找一种在转储中查找CString条目的方法,现在仍然是:-) 根据Windbg的x/2结果中提到的第一个字段,似乎可以找到与对象相关的条目。对于具有虚拟方法的对象,这似乎是\uu vptr字段(对应于*vftable'条目),我认为对于CString类的特定情况,这个问题很容易解决 在源代码(C:\ProgramFiles(x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\\crt\src\vcru
CString
条目的方法,现在仍然是:-)根据Windbg的
x/2
结果中提到的第一个字段,似乎可以找到与对象相关的条目。对于具有虚拟方法的对象,这似乎是\uu vptr
字段(对应于*vftable'
条目),我认为对于CString
类的特定情况,这个问题很容易解决
在源代码(C:\ProgramFiles(x86)\Microsoft Visual Studio\2017\Professional\VC\Tools\MSVC\\crt\src\vcruntime\undname.cxx
)中,我找到了以下条目:
#if ( !NO_COMPILER_NAMES )
"`vftable'", <--- vftable: the one I'm working with
"`vbtable'",
"`vcall'",
"`typeof'",
"`local static guard'",
"`string'",
"`vbase destructor'",
"`vector deleting destructor'",
"`default constructor closure'",
"`scalar deleting destructor'",
"`vector constructor iterator'",
"`vector destructor iterator'",
"`vector vbase constructor iterator'",
"`virtual displacement map'",
"`eh vector constructor iterator'",
"`eh vector destructor iterator'",
"`eh vector vbase constructor iterator'",
"`copy constructor closure'",
"`udt returning'",
"`EH", //eh initialized struct
"`RTTI", //rtti initialized struct
"`local vftable'",
"`local vftable constructor closure'",
#endif // !NO_COMPILER_NAMES
#如果(!没有编译器名称)
“`vftable'”似乎CString
只是封装了一个指针,没有任何虚方法,所以没有vtable
这里有一个小例子:
#include <atlstr.h>
void SayHello(CHAR* arg)
{
CStringA cstring = arg;
CStringA message = "Hello " + cstring + "!";
printf("message: %s", (LPCSTR)message);
}
int main(int argc, CHAR** argv)
{
if (argc < 2)
return -1;
SayHello(argv[1]);
return 0;
}
英国石油公司被击中;只需步骤一次,即可通过cstring
local var init:
Breakpoint 0 hit
ConsoleApplication1!SayHello:
01041420 55 push ebp
0:000:x86> p
您可以使用dt
命令(显示类型)查看类型中的字段。
此处用于查看cstring
本地变量:
0:000:x86> dt cstring
Local var @ 0x114f944 Type ATL::CStringT<char,ATL::StrTraitATL<char,ATL::ChTraitsCRT<char> > >
+0x000 m_pszData : 0x01224e20 "world"
本地变量上的sizeof
运算符仅给出4:
0:000:x86> ?? sizeof(cstring)
unsigned int 4
用da
确认:
0:000:x86> dp cstring L4
0114f944 01224e20 3ec0fed1 0114f998 01042bf1
0:000:x86> da 01224e20
01224e20 "world"
您将无法在转储中找到CString
实例,因为它们只是指向数据的指针。似乎CString
只是封装了一个指针,没有任何虚拟方法,因此没有vtable
这里有一个小例子:
#include <atlstr.h>
void SayHello(CHAR* arg)
{
CStringA cstring = arg;
CStringA message = "Hello " + cstring + "!";
printf("message: %s", (LPCSTR)message);
}
int main(int argc, CHAR** argv)
{
if (argc < 2)
return -1;
SayHello(argv[1]);
return 0;
}
英国石油公司被击中;只需步骤一次,即可通过cstring
local var init:
Breakpoint 0 hit
ConsoleApplication1!SayHello:
01041420 55 push ebp
0:000:x86> p
您可以使用dt
命令(显示类型)查看类型中的字段。
此处用于查看cstring
本地变量:
0:000:x86> dt cstring
Local var @ 0x114f944 Type ATL::CStringT<char,ATL::StrTraitATL<char,ATL::ChTraitsCRT<char> > >
+0x000 m_pszData : 0x01224e20 "world"
本地变量上的sizeof
运算符仅给出4:
0:000:x86> ?? sizeof(cstring)
unsigned int 4
用da
确认:
0:000:x86> dp cstring L4
0114f944 01224e20 3ec0fed1 0114f998 01042bf1
0:000:x86> da 01224e20
01224e20 "world"
您将无法在转储中找到CString
实例,因为它们只是指向数据的指针。谢谢您的回答,Neitsa。在处理虚拟方法时,编译器似乎确实添加了关键字vftable
,而在其他情况下默认不添加任何内容。您知道Windows编译器的任何设置在其他情况下可能会添加其他内容吗?@Dominique我不知道,除了RTTI信息,如果代码是使用开关编译的(它会在vtable中添加指向元信息的指针)。这是非常罕见的:(同时,我找到了源代码,关于<代码> vfTabe< /Cord>条目,其中其他条目似乎也存在,但我不知道是否可以使用。抱歉,我花了几天时间才意识到TL,DR的意思:-(点::)谢谢你的回答,Neitsa。看起来编译器在处理虚拟方法时确实添加了关键字vftable
,在其他情况下默认不添加任何内容。你知道Windows编译器的任何设置在其他情况下可能会添加其他内容吗?@Dominique我不知道,除了RTTI信息,如果cODE是用开关编译的(它在VTABLE中添加了一个指向元信息的指针)。这是非常罕见的:(同时,我找到了源代码,关于那个<代码> vfTabe< /Cord>条目,其他条目似乎也存在,但是我不知道我是否可以使用它。抱歉,我花了几天时间才意识到TL,DR的意思:(要点:-)