简体   繁体   中英

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 :-)
It seems possible to find object related entries, based on the first field as mentioned in Windbg's x /2 result. 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.

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:

#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.

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.

Thanks in advance

It seems that CString just encapsulate a pointer and doesn't have have any virtual methods, so no 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.

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; just step once to pass over 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. Used here to see the cstring local var:

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:

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

sizeof operator on the local var gives only 4:

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

Confirmed with 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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