Как найти первое поле из объекта / класса?

Доброе утро,
В эта почта, Я искал способ найти CString записи в дампе, а я до сих пор 🙂
Кажется возможным найти записи, относящиеся к объекту, на основе первого поля, упомянутого в Windbg. x /2 результат. Для объектов, которые имеют виртуальные методы, это, кажется, __vptr поле (которое соответствует *vftable' записи), и я думал, что этот вопрос будет легким для частного случая 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

Это заставляет меня задуматься, могу ли я использовать одну из упомянутых записей в качестве кандидатов на первое поле объекта. Я уже узнал, что существует запись в windbg«s x /2 *!ATL::CStringT* команда, заканчивающаяся scalar deleting destructor', но я не знаю, смогу ли я использовать это как «первое поле» кандидата.

Постскриптум В случае, если вы задаетесь вопросом «Но почему бы вам просто не попробовать?», Есть проблема в том, что CStringT объекты, присутствующие в моих дамп-файлах, содержат довольно странные символы, из-за чего очень трудно увидеть, правильно ли я поступаю, и увидеть странные, но правильные символы, или я смотрю на поддельные результаты.

заранее спасибо

0

Решение

Кажется, что 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

БП поражен; просто шаг один раз, чтобы пройти cstring локальный 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 *]

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 экземпляры в дампе, так как они просто указатели на данные.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]