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的意思:(要点:-)