Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
struct TABLE
{
PVOID Unknown1;
LIST_ENTRY *LLHead;
LIST_ENTRY *SomeEntry;
LIST_ENTRY *LastElementFound;
ULONG LastElementIndex;
ULONG NumberOfElements;
ULONG Unknown1;
ULONG Unknown2;
ULONG Unknown3;
ULONG Unknown4;
};

Listing 5.3 The contents of the TABLEdata structure, based on what has been learned so
far.

PVOID stdcall MyRtlGetElementGenericTable(TABLE *Table, ULONG
ElementToGet)
{
ULONG TotalElementCount = Table->NumberOfElements;
LIST_ENTRY *ElementFound = Table->LastElementFound;
ULONG LastElementFound = Table->LastElementIndex;
ULONG AdjustedElementToGet = ElementToGet + 1;

if (ElementToGet == -1 || AdjustedElementToGet > TotalElementCount)
return 0;

// If the element is the last element found, we just return it.
if (AdjustedElementToGet != LastIndexFound)
{
// If the element isn’t LastElementFound, go search for it:
if (LastIndexFound > AdjustedElementToGet)
{
// The element is located somewhere between the first element and
// the LastElementIndex. Let’s determine which direction would
// get us there the fastest.
ULONG HalfWayFromLastFound = LastIndexFound / 2;
if (AdjustedElementToGet > HalfWayFromLastFound)
{
// We start at LastElementFound (because we’re closer to it) and
// move backward toward the beginning of the list.
ULONG ElementsToGo = LastIndexFound - AdjustedElementToGet;

while(ElementsToGo--)
ElementFound = ElementFound->Blink;

Listing 5.4 A source-code level reconstruction of RtlGetElementGenericTable.

166 Chapter 5

Free download pdf