简体   繁体   English

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

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

Good morning, In this post , I was looking for a way to find CString entries within a dump, and I still am :-) 早上好,在本文中 ,我正在寻找一种在转储中查找CString条目的方法,但我仍然是:-)
It seems possible to find object related entries, based on the first field as mentioned in Windbg's x /2 result. 根据Windbg的x /2结果中提到的第一个字段,似乎可以找到与对象相关的条目。 For objects who have virtual methods, this seems to be the __vptr field (which corresponds with *vftable' entries), and I'd thought this question to be easy for the particular case of the CString class. 对于具有虚拟方法的对象,这似乎是__vptr字段(与*vftable' __vptr条目相对应),并且我认为对于CString类的特定情况,此问题很容易。

In the source code ( C:\\Program Files (x86)\\Microsoft Visual Studio\\2017\\Professional\\VC\\Tools\\MSVC\\<version>\\crt\\src\\vcruntime\\undname.cxx ), I've found following entry: 在源代码( 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

This makes me wonder if I could use one of the mentioned entries as candidates for the first field of an object. 这使我想知道是否可以使用上述条目之一作为对象第一个字段的候选对象。 I already have found out that there exists an entry in windbg 's x /2 *!ATL::CStringT* command, ending by scalar deleting destructor' , but I don't know if I could use this as a "first field" candidate. 我已经发现在windbgx /2 *!ATL::CStringT*命令中存在一个条目,以scalar deleting destructor'结尾,但是我不知道是否可以将其用作“第一个字段”候选人。

Ps In case you wonder "But why don't you just try it?", there is the issue that the CStringT objects, present in my dumpfiles, contain quite some strange characters, which makes it very difficult to see if I'm doing the right thing and see strange but correct characters, or if I'm looking at bogus results. Ps如果您想知道“但是为什么不尝试一下呢?”,则存在一个问题,即我的转储文件中存在的CStringT对象包含很多奇怪的字符,这使得很难查看我是否在做正确的东西,看到奇怪但正确的字符,或者如果我正在查看虚假结果。

Thanks in advance 提前致谢

It seems that CString just encapsulate a pointer and doesn't have have any virtual methods, so no vtable. 看来CString只是封装了一个指针,没有任何虚方法,因此没有vtable。

Here's a little example: 这是一个小例子:

#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;
}

Put the resulting executable in Windbg and started with world as parameter. 将生成的可执行文件放入Windbg中,并以world作为参数开头。

put a BP and go 放个血压然后走

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

BP is hit; BP被击中; just step once to pass over cstring local var init: 只需跨过一次cstring local var init:

Breakpoint 0 hit
ConsoleApplication1!SayHello:
01041420 55              push    ebp
0:000:x86> p

You can use the dt command (display type) to see what fields are in a type. 您可以使用dt命令(显示类型)查看类型中的字段。 Used here to see the cstring local var: 在这里用来查看cstring本地变量:

0:000:x86> dt cstring
Local var @ 0x114f944 Type ATL::CStringT<char,ATL::StrTraitATL<char,ATL::ChTraitsCRT<char> > >
   +0x000 m_pszData        : 0x01224e20  "world"

There's only one field in a CString , its name is m_pszData and it's just a pointer: CString只有一个字段,其名称为m_pszData ,并且只是一个指针:

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

sizeof operator on the local var gives only 4: 本地var上的sizeof运算符仅给出4:

0:000:x86> ?? sizeof(cstring)
unsigned int 4

Confirmed with da : da确认:

0:000:x86> dp cstring L4
0114f944  01224e20 3ec0fed1 0114f998 01042bf1

0:000:x86> da 01224e20 
01224e20  "world"

You won't be able to find CString instances in a dump as they are just pointers to data. 您将无法在转储中找到CString实例,因为它们只是指向数据的指针。

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

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