我正在 WinDbg 中调试一个 x86 程序(用 C++/VS2012/静态链接编写),我有它的目标文件。我的兴趣点是这个功能:
static bool isValidToken(const std::string& token)
Run Code Online (Sandbox Code Playgroud)
此函数接收字符串令牌以验证客户端。
我希望能够在调试器中测试它,但要这样做,我必须创建一个std::string这样我才能执行命令:.call isValidToken(<addr_of_string>).
std::string在 WinDbg 中转储和操作相对容易,但是否可以创建它?
我能够劫持其他字符串并更改它以便我可以测试,但它显然有时会使程序崩溃。我正在尝试为该类找到一个静态构造函数,但这真的很难,因为它在很大程度上基于模板。
通过在 Visual Studio 中调试测试程序(由@cdonts在评论中建议),我可以找到std::string. 它显示在后面的命令中。
回到 WinDbg,我发出以下命令来查找具有该签名的符号(注意*用作通配符来替换空格):
0:047> x Manager!std::basic_string<char,std::char_traits<char>,std::allocator<char>*>::basic_string<char,std::char_traits<char>,std::allocator<char>*>
Run Code Online (Sandbox Code Playgroud)
找到以下构造函数:
6e36bf96 Manager!std::basic_string<...PROTOTYPE...> (char *, char *)
6e67fa65 Manager!std::basic_string<...PROTOTYPE...> (class std::basic_string<...PROTOTYPE...> *, int, int)
6d519218 Manager!std::basic_string<...PROTOTYPE...> (class std::_String_const_iterator<...PROTOTYPE...>)
6d54c745 Manager!std::basic_string<...PROTOTYPE...> (char *, unsigned int)
6d0c2666 Manager!std::basic_string<...PROTOTYPE...> (char *)
6d1f2a43 Manager!std::basic_string<...PROTOTYPE...> (class std::basic_string<...PROTOTYPE...> *)
6d151eb8 Manager!std::basic_string<...PROTOTYPE...> (class std::basic_string<...PROTOTYPE...> *)
Run Code Online (Sandbox Code Playgroud)
我省略了原型的某些部分,但我们感兴趣的是:
6d0c2666 Manager!std::basic_string<...PROTOTYPE...> (char *)
Run Code Online (Sandbox Code Playgroud)
这个只需要一个char *作为参数。它用于初始化新创建的字符串,并且非常容易提供。因此,完成这项工作的步骤是:
为对象 ( std::string)分配内存。我们使用 1000 因为它是最小分配大小:
0:047> .dvalloc 1000
Allocated 1000 bytes starting at 03fe0000
Run Code Online (Sandbox Code Playgroud)为char *参数分配一个缓冲区:
0:047> .dvalloc 1000
Allocated 1000 bytes starting at 03ff0000
Run Code Online (Sandbox Code Playgroud)
我们可以使用以下方法初始化缓冲区:
0:047> ea 0x03ff0000 "my string here"
Run Code Online (Sandbox Code Playgroud)放置一个.call传递两个参数的命令:第一个是我们为对象本身分配的内存地址,它实际上恰好是一个this参数,因为函数使用thiscall调用约定(WinDbg 知道它并将其放入ecx)。第二个是char *构造函数的参数:
0:048> .call 6d0c2666(0x03fe0000, 0x03ff0000)
Thread is set up for call, 'g' will execute.
WARNING: This can have serious side-effects,
including deadlocks and corruption of the debuggee.
0:048> g
Run Code Online (Sandbox Code Playgroud)之后,我们有一个很好的std::string对象 (at 0x03fe0000) 可以使用,其中包含文本"my string here"。