Доброе утро,
В эта почта, Я искал способ найти 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
объекты, присутствующие в моих дамп-файлах, содержат довольно странные символы, из-за чего очень трудно увидеть, правильно ли я поступаю, и увидеть странные, но правильные символы, или я смотрю на поддельные результаты.
заранее спасибо
Кажется, что 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
экземпляры в дампе, так как они просто указатели на данные.
Других решений пока нет …