Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
(which is the beginning of the loop) for as long as ESI != 0. What does this
loop do? Remember that EAXis the third pointer from the three-pointer group
in the root data structure, and that you’re currently working under the
assumption that each element starts with the same three-pointer structure.
This loop really supports that assumption, because it takes offset +4 in what
we believe is some element from the list and treats it as another pointer. Not
definite proof, but substantial evidence that +4 is the second in a series of three
pointers that precede each element in a generic table.
Apparently the earlier subtraction of EBXfrom ESIprovided the exact num-
ber of elements you need to traverse in order to get from EAXto the element you
are looking for (remember, you already know ESIis the index of the element
pointed to by EAX). The question now is, in which direction are you moving rel-
ative to EAX? Are you going toward lower-indexed elements or higher-indexed
elements? The answer is simple, because you’ve already compared ESIwith
EBXand branched out for cases where ESI ≤EBX, so you know that in this par-
ticular case ESI > EBX. This tells you that by taking each element’s offset +4
you are moving toward the lower-indexed elements in the table.
Recall that earlier I mentioned that the programmer must have really
wanted to double-check cases where ESI < EBX? This loop clarifies that
issue. If you ever got into this loop in a case where ESI ≤ EBX, ESIwould
immediately become a negative number because it is decremented at the very
beginning. This would cause the loop to run unchecked until it either ran into
an invalid pointer and crashed or (if the elements point back to each other in a
loop) until ESIwent back to zero again. In a 32-bit machine this would take
4,294,967,296 iterations, which may sound like a lot, but today’s high-speed
processors might actually complete this many iterations so quickly that if it
happened rarely the programmer might actually miss it! This is why from a
programmer’s perspective crashing the program is sometimes better than let-
ting it keep on running with the problem—it simplifies the program’s stabi-
lization process.
When our loop ends the code takes an unconditional jump to ntdll
.7C96254E. Let’s see what happens there.

7C96254E MOV DWORD PTR [ECX+C],EAX
7C962551 MOV DWORD PTR [ECX+10],EBX

Well, very interesting indeed. Here, you can get a clear view on what offsets
+C and +10 in the root data structure contain. It appears that this is some kind
of an optimization for quickly searching and traversing the table. Offset +C
receives the pointer to the element you’ve been looking for (the one you’ve
reached by going through the loop), and offset +10 receives that element’s
index. Clearly the reason this is done is so that repeated calls to this function

162 Chapter 5

Free download pdf