Archive for May 8th, 2008

New WinDbg Release 6.9.3.113

Thursday, May 8th, 2008

As always you can quickly get it through WinDbg Quick Links page:

http://www.windbg.org

- Dmitry Vostokov @ DumpAnalysis.org -

STL and WinDbg

Thursday, May 8th, 2008

Some applications are written using Standard Template Library and it is good that there is !stl WinDbg extension which works with a few types from Plauger’s STL implementation used in Visual C++ CRT library:

0:000> !stl
!stl [options] <varname>
  stl [options] <varname> - dumps an STL variable
  stl [options] -n <type-name> <address>
             currently works with string, wstring
             vector<string>, vector<wstring>
             list<string>, vector<wstring>
             (and pointer varieties therein)
   [options]
       -n <type-name> The name of the type. If the
               type has spaces, surround with
               parentheses ().
       -v      verbose output
       -V      extremely verbose output

If we have public symbols and know variable names we can simply dump their values, for example:

0:000> dv /i /V
prv local  @ecx @ecx            this = 0x0012fbdc
prv local  0012fbf8 @ebp-0x2c   MyName = class std::basic_string<char,std::char_traits<char>,std::allocator<char> >

0:000> !stl MyName
[da 0x12fbfc]
0012fbfc  "COMPANY__NAME"

We can also supply full STL type name:

0:000> !stl -n (std::basic_string<char,std::char_traits<char>,std::allocator<char> >) 0012fbf8
[da 0x12fbfc]
0012fbfc  "COMPANY__NAME"

Let’s dump this string type internal structure to be able to recognize it later in raw data:

0:000> dt -r -n std::basic_string<char,std::char_traits<char>,std::allocator<char> > 0012fbf8
application!std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x000 _Alval           : std::allocator<char>
   =00400000 npos             : 0x905a4d
   +0×004 _Bx              : std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
      +0×000 _Buf             : [16]  “COMPANY__NAME”

      +0×000 _Ptr             : 0×43415250  “”
   +0×014 _Mysize          : 0xd
   +0×018 _Myres           : 0xf

We see that for short strings less than 16 bytes std::basic_string<char> data starts from offset +4 and followed by the actual string size and its reserved size:

0:000> dd 0012fbf8
0012fbf8  00000000 43415250 45434954 53504d5f
0012fc08  41bf00
33 0000000d 0000000f 41bf3b72
0012fc18  0012fc6c 0046107b 00000000 0012fc78
0012fc28  0041a441 00000000 41bf3b2e 00ed6380
0012fc38  00000003 00ed6128 00ed6128 00f41b00
0012fc48  00ed6128 41bf3b3e 0012fc3c 00000000
0012fc58  0000000f 00f41b98 00f469a0 00000000
0012fc68  014487c8 0012fcfc 00463fdd 00000002

For bigger strings implementation starts with a pointer from offset +4 to the actual string data and then followed by 12 bytes of garbage and then by the actual string size and its reserved size:

0:000> dt -r -n std::basic_string<char,std::char_traits<char>,std::allocator<char> >
application!std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x000 _Alval           : std::allocator<char>
   =00400000 npos             : Uint4B
   +0×004 _Bx              : std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
      +0×000 _Buf             : [16] Char
      +0×000 _Ptr             : Ptr32 Char
   +0×014 _Mysize          : Uint4B
   +0×018 _Myres           : Uint4B

0:000> dt -r -n std::basic_string<char,std::char_traits<char>,std::allocator<char> > 0012ff08
application!std::basic_string<char,std::char_traits<char>,std::allocator<char> >
   +0x000 _Alval           : std::allocator<char>
   =00400000 npos             : 0x905a4d
   +0×004 _Bx              : std::basic_string<char,std::char_traits<char>,std::allocator<char> >::_Bxty
      +0×000 _Buf             : [16]  “???”
      +0×000 _Ptr             : 0×00ed4ba0  “/h /c:100 /enum”
   +0×014 _Mysize          : 0×10
   +0×018 _Myres           : 0×1f

In such cases dpa or dpu commands help to show this additional dereference:

0:000> dpa 0012ff08
0012ff08  00ed2f90 "."
0012ff0c  00ed4ba0 “/h /c:100 /enum”
0012ff10  41eafd01
0012ff14  0012ffc0 “…”
0012ff18  0045890a “……U..SVWUj”

0012ff1c  00000010
0012ff20  0000001f

0012ff24  41bf3996
0012ff28  0012ffc0 “…”
0012ff2c  0044b528 “.E..}.”
0012ff30  00400000 “MZ.”

SDbgExt has commands to interrogate additional STL types.  

- Dmitry Vostokov @ DumpAnalysis.org -