and EDIcontains the distance between the cached element and the element
that you’re looking for.
Search Loop 4
There is one other significant search case that hasn’t been covered yet. Remem-
ber how before we got into the first backward-searching loop we tested for a
case where the index was lower than LastIndexFound / 2? Let’s see what
the function does when we get there:
7C96251B TEST EBX,EBX
7C96251D LEA EAX,DWORD PTR [ECX+4]
7C962520 JE SHORT ntdll.7C96254E
7C962522 MOV EDX,EBX
7C962524 DEC EDX
7C962525 MOV EAX,DWORD PTR [EAX]
7C962527 JNZ SHORT ntdll.7C962524
7C962529 JMP SHORT ntdll.7C96254E
This sequence starts with the element at offset +4 in the root data structure,
which is the one we’ve previously defined as the last element in the list. It then
starts looping on elements using offset +0 in each element’s header. Offset +0 has
just been established as the element’s NextElement pointer, so what’s going
on? How could we possibly be going forward from the last element in the list? It
seems that we must revise our definition of offset +4 in the root data structure a
little bit. It is not really the last element in the list, but it is the head of a circular
linked list. The term circular means that the NextElementpointer in the last ele-
ment of the list points back to the beginning and that the PrevElementpointer
in the first element points to the last element.
Because in this case the index is lower than LastIndexFound / 2, it would
just be inefficient to start our search from the last element found. Instead, we
start the search from the first element in the list and move forward until
we find the right element.
Reconstructing the Source Code
This concludes the detailed analysis of RtlGetElementGenericTable. It is
not a trivial function, and it includes several slightly confusing control flow
constructs and some data structure manipulation. Just to demonstrate the
power of reversing and just how accurate the analysis is, I’ve attempted to
reconstruct the source code of that function, along with a tentative declaration
of what must be inside the TABLEdata structure. Listing 5.3 shows what you
currently know about the TABLEdata structure. Listing 5.4 contains my recon-
structed source code for RtlGetElementGenericTable.
Beyond the Documentation 165