繁体   English   中英

如何从对象/类中找到第一个字段?

[英]How to find the first field from an object/class?

早上好,在本文中 ,我正在寻找一种在转储中查找CString条目的方法,但我仍然是:-)
根据Windbg的x /2结果中提到的第一个字段,似乎可以找到与对象相关的条目。 对于具有虚拟方法的对象,这似乎是__vptr字段(与*vftable' __vptr条目相对应),并且我认为对于CString类的特定情况,此问题很容易。

在源代码( C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Tools\\MSVC\\<version>\\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

这使我想知道是否可以使用上述条目之一作为对象第一个字段的候选对象。 我已经发现在windbgx /2 *!ATL::CStringT*命令中存在一个条目,以scalar deleting destructor'结尾,但是我不知道是否可以将其用作“第一个字段”候选人。

Ps如果您想知道“但是为什么不尝试一下呢?”,则存在一个问题,即我的转储文件中存在的CStringT对象包含很多奇怪的字符,这使得很难查看我是否在做正确的东西,看到奇怪但正确的字符,或者如果我正在查看虚假结果。

提前致谢

看来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;
}

将生成的可执行文件放入Windbg中,并以world作为参数开头。

放个血压然后走

0:000> bp ConsoleApplication1!SayHello
0:000> bl
     0 e Disable Clear  x86 00000000`01041420     0001 (0001)  0:**** ConsoleApplication1!SayHello
0:000> g

BP被击中; 只需跨过一次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"

CString只有一个字段,其名称为m_pszData ,并且只是一个指针:

0:000:x86> dx -r1 ((ConsoleApplication1!char *)0x1224e20)
((ConsoleApplication1!char *)0x1224e20)                 : 0x1224e20 : "world" [Type: char *]

本地var上的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实例,因为它们只是指向数据的指针。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM