Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

block a pointer to pNodeis stored in offset +0 at the new entry. This indicates
that offset +0 in the node header contains a pointer to the parent element. You
can now properly define the node header data structure.


struct NODE
{
NODE *ParentNode;
NODE *RightChild;
NODE *LeftChild;
LIST_ENTRY LLEntry;
ULONG Unknown;
};

Copying the Element


After allocating the new node and attaching it to pNode, you reach an inter-
esting sequence that is actually quite common and is one that you’re probably
going to see quite often while reversing IA-32 assembly language code. Let’s
take a look.


7C924E52 MOV ESI,DWORD PTR [EBP+C]
7C924E55 MOV ECX,EDI
7C924E57 MOV EAX,ECX
7C924E59 SHR ECX,2
7C924E5C LEA EDI,DWORD PTR [EBX+18]
7C924E5F REP MOVS DWORD PTR ES:[EDI],DWORD PTR [ESI]
7C924E61 MOV ECX,EAX
7C924E63 AND ECX,3
7C924E66 REP MOVS BYTE PTR ES:[EDI],BYTE PTR [ESI]

This code loads ESIwith ElementData, EDIwith the end of the new
node’s header, ECXwith ElementSize * 4, and starts copying the element
data, 4 bytes at a time. Notice that there are two copying sequences. The first is
for 4-byte chunks, and the second checks whether there are any bytes left to be
copied, and copies those (notice how the first MOVStakes DWORD PTRargu-
ments and the second takes BYTE PTRoperands).
I say that this is a common sequence because this is a classic memcpyimple-
mentation. In fact, it is very likely that the source code contained a memcpycall
and that the compiler simply implemented it as an intrinsic function (intrinsic
functions are briefly discussed in Chapter 7).


Splaying the Table


Let’s proceed to the next code sequence. Notice that there are two different
paths that could have gotten us to this point. One is through the path I have
just covered in which the callback is called and the structure is initialized, and


Beyond the Documentation 185
Free download pdf