Reverse Engineering for Beginners

(avery) #1

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


.hidden __dso_handle

But it does not create a separate function for this, each destructor is passed to atexit(), one by one.


51.4.2 std::list


This is the well-known doubly-linked list: each element has two pointers, to the previous and next elements.


This implies that the memory footprint is enlarged by 2wordsfor each element (8 bytes in 32-bit environment or 16 bytes
in 64-bit).


C++ STL just adds the “next” and “previous” pointers to the existing structure of the type that you want to unite in a list.


Let’s work out an example with a simple 2-variable structure that we want to store in a list.


Although the C++ standard [ISO13] does not say how to implement it, both MSVC’s and GCC’s implementations are straight-
forward and similar, so here is only one source code for both:


#include <stdio.h>
#include
#include


struct a
{
int x;
int y;
};


struct List_node
{
struct List_node _Next;
struct List_node
_Prev;
int x;
int y;
};


void dump_List_node (struct List_node *n)
{
printf ("ptr=0x%p _Next=0x%p _Prev=0x%p x=%d y=%d\n",
n, n->_Next, n->_Prev, n->x, n->y);
};


void dump_List_vals (struct List_node n)
{
struct List_node
current=n;


for (;;)
{
dump_List_node (current);
current=current->_Next;
if (current==n) // end
break;
};
};


void dump_List_val (unsigned int a)
{
#ifdef _MSC_VER
// GCC implementation does not have "size" field
printf ("_Myhead=0x%p, _Mysize=%d\n", a[0], a[1]);
#endif
dump_List_vals ((struct List_node
)a[0]);
};


int main()
{
std::list l;


printf ("* empty list:\n");
dump_List_val((unsigned int*)(void*)&l);
Free download pdf