I'm debugging a x86 program (written in C++ / VS2012 / statically linked) in WinDbg and I have its object files. My point of interest is this function:
static bool isValidToken(const std::string& token)
This function receives a string token to validate a client.
I want to be able to test it inside the debugger, but to do so I would have to create an std::string so I could do the command: .call isValidToken(<addr_of_string>).
Dumping and manipulating std::string inside WinDbg is relatively easy, but is it possible to create it?
I'm able to hijack other strings and change it so I can test, but it obviously crashes the program sometimes. I'm trying to find a static constructor for the class but it's really hard because it's heavily based on templates.
By debugging a test program in Visual Studio (suggested by @cdonts in the comments) I could find the constructor prototype for std::string. It is shown in the command that follows.
Back to WinDbg I issued the following command to find symbols with that signature (note that * is used as wildcard to replace spaces):
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>*>
Found the following constructors:
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...> *)
I ommited some parts of the prototypes, but the one that interests us is:
6d0c2666 Manager!std::basic_string<...PROTOTYPE...> (char *)
This one only takes a char * as argument. It is used to initialize the newly created string, and it's really easy to provide. So, the steps to do the job are:
Allocate memory for the object ( std::string ). We use 1000 because it's the minimum allocation size:
0:047> .dvalloc 1000
Allocated 1000 bytes starting at 03fe0000
Allocate a buffer for the char * parameter:
0:047> .dvalloc 1000
Allocated 1000 bytes starting at 03ff0000
We can initialize the buffer with:
0:047> ea 0x03ff0000 "my string here"
Place a .call command passing two parameters: The first one is the address of the memory we allocated for the object itself, that actually happens to be a this argument, because the funcion uses thiscall calling convention (WinDbg knows it and places it in ecx). The second one is the char * parameter for the constructor:
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
After that we have a good std::string object (at 0x03fe0000) to work with, containing the text "my string here".
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With