[ebp+14]is nonzero. If it is, the function is treating it as a pointer, writing a
single byte containing 0 (because we know EBXis going to be zero at this point)
into the address pointed by it. It would appear that the fourth parameter is a
pointer to some Boolean that’s used for notifying the caller of the function’s
success or failure.
Let’s proceed to look at what happens when the callback returns a non-
NULLvalue. It’s not difficult to see that this code is initializing the header of
the newly allocated element, using the callback’s return value as the address.
Before we try to figure out the details of this initialization, let’s pause for a sec-
ond and try to realize what this tells us about the callback function we just
observed. It looks as if the purpose of the callback function was to allocate
memory for the newly created element. We know this because EBXnow con-
tains the return value from the callback, and it’s definitely being used as a
pointer to a new element that’s currently being initialized. With this informa-
tion, let’s try to define this callback.
typedef NODE * ( _stdcall * TABLE_ALLOCATE_ELEMENT) (
TABLE *pTable,
ULONG ElementSize
);
How did I know that the second parameter is the element’s size? It’s simple.
This is a value that was passed along from the caller of RtlInsertElement
GenericTableinto RtlRealInsertElementWorker, was incremented by
24, and was finally fed into TABLE_ALLOCATE_ELEMENT. Clearly the applica-
tion calling RtlInsertElementGenericTableis supplying the size of this
element, and the function is adding 24 because that’s the length of the node’s
header. Because of this we now also know that the third parameter passed into
RtlRealInsertElementWorkeris the user-supplied element length. We’ve
also found out that the fourth parameter is an optional pointer into some
Boolean that contains the outcome of this function. Let’s correct the original
prototype.
UNKNOWN RtlRealInsertElementWorker(
TABLE *pTable,
PVOID ElementData,
ULONG ElementSize,
BOOLEAN *pResult OPTIONAL,
NODE *pNode,
ULONG SearchResult
);
You may notice that we’ve been accumulating quite a bit of information on the
parameters that RtlInsertElementGenericTabletakes. We’re now ready
to start looking at the prototype for RtlInsertElementGenericTable.
Beyond the Documentation 183