Reverse Engineering for Beginners

(avery) #1

CHAPTER 51. C++ CHAPTER 51. C++


* The reason you want _M_data pointing to the character %array and
* not the _Rep is so that the debugger can see the string
* contents. (Probably we should add a non-inline member to get
* the _Rep for the debugger to use, so users can check the actual
* string length.)

basic_string.h source code


We consider this in our example:


Listing 51.22: example for GCC

#include
#include <stdio.h>


struct std_string
{
size_t length;
size_t capacity;
size_t refcount;
};


void dump_std_string(std::string s)
{
char p1=(char*)&s; // GCC type checking workaround
struct std_string
p2=(struct std_string*)(p1-sizeof(struct std_string));
printf ("[%s] size:%d capacity:%d\n", p1, p2->length, p2->capacity);
};


int main()
{
std::string s1="short string";
std::string s2="string longer that 16 bytes";


dump_std_string(s1);
dump_std_string(s2);

// GCC type checking workaround:
printf ("%s\n", *(char*)&s1);
printf ("%s\n",
(char**)&s2);
};


A trickery has to be used to imitate the mistake we already have seen above because GCC has stronger type checking,
nevertheless, printf() works here without c_str() as well.


A more complex example


#include
#include <stdio.h>


int main()
{
std::string s1="Hello, ";
std::string s2="world!\n";
std::string s3=s1+s2;


printf ("%s\n", s3.c_str());
}


Listing 51.23: MSVC 2012

$SG39512 DB 'Hello, ', 00H
$SG39514 DB 'world!', 0aH, 00H
$SG39581 DB '%s', 0aH, 00H


_s2$ = -72 ; size = 24
_s3$ = -48 ; size = 24
_s1$ = -24 ; size = 24

Free download pdf