optimized the code by automatically declaring a temporary variable to store
the value instead of computing it each time it is needed. This is another case
where you just don’t know—this information was lost during the compilation
process.
Let’s proceed to the next code sequence:
7C962501 CMP ESI,EBX
7C962503 JE SHORT ntdll.7C962554
7C962505 JBE SHORT ntdll.7C96252B
7C962507 MOV EDX,ESI
7C962509 SHR EDX,1
7C96250B CMP EBX,EDX
7C96250D JBE SHORT ntdll.7C96251B
7C96250F SUB ESI,EBX
7C962511 JE SHORT ntdll.7C96254E
This section starts out by comparing ESI(which was taken earlier from offset
+10 at the table structure) against EBX. This exposes the fact that offset +10 also
points to some kind of an index into the table (because it is compared against
EBX, which you know is an index into the table), but you don’t know exactly
what that index is. If ESI == EBX, the code jumps to ntdll.7C962554, and if
ESI <= EBX, it goes to ntdll.7C96252B. It is not clear at this point why the
second jump uses JBEeven though the operands couldn’t be equal at this point
or the first jump would have been taken.
Let’s first explore what happens in ntdll.7C962554:
7C962554 ADD EAX,0C
7C962557 JMP SHORT ntdll.7C96255B
This code does EAX = EAX + 12, and unconditionally jumps to ntdll.
7C96255B. If you go back to Listing 5.2, you can see that ntdll.7C96255Bis
right near the end of the function, so the preceding code snippet simply returns
EAX+ 12 to the caller. Recall that EAXwas loaded earlier from the table structure
at offset +C, and that while dissecting RtlInitializeGenericTable, you
were working under the assumption that offsets +4, +8, and +C are all pointers
into the same three-pointer data structure (they were all initialized to point at
offset +4). At this point one, of these pointers is incremented by 12 and returned
to the caller. This is a powerful hint about the structure of the generic tables. Let’s
examine the hints one by one:
■■ You know that there is a group of three pointers starting in offset +4 in
the root data structure.
■■ You know that each one of these pointers point into another group of
three pointers. Initially, they all point to themselves, but you can safely
assume that this changes later on when the table is filled.
158 Chapter 5