Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Create std::string inside debugger

Tags:

c++

windbg

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.

like image 502
karliwson Avatar asked Jul 01 '26 22:07

karliwson


1 Answers

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:

  1. 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
    
  2. 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"
    
  3. 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".

like image 164
karliwson Avatar answered Jul 03 '26 11:07

karliwson



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!