The last two instructions in the current chunk perform another check on that
same parameter, except that this time the code is using EBX, which as you
might recall is the incremented version of EDI. Here EBXis compared against
EDX, and the program jumps to ntdll.7C962559if EBXis greater. Notice that
the jump target address, ntdll.7C962559, is the same as the address of the
previous conditional jump. This is a strong indication that the two jumps are
part of what was a single compound conditional statement in the source code.
They are just two conditions tested within a single conditional statement.
Another interesting and informative hint you find here is the fact that the
conditional jump instruction used is JA(jump if above), which uses the carry
flag (CF). This indicates that EBXand EDXare both treated as unsigned values.
If they were signed, the compiler would have used JG, which is the signed ver-
sion of the instruction. For more information on signed and unsigned condi-
tional codes refer to Appendix A.
If you try to put the pieces together, you’ll discover that this last condition
actually reveals an interesting piece of information about the second parameter
passed to this function. Recall that EDXwas loaded from offset +14 in the struc-
ture, and that this is the member that stores the total number of elements in the
table. This indicates that the second parameter passed to RtlGetElement
GenericTableis an index into the table. These last two instructions simply
confirm that it is a valid index by comparing it against the total number of ele-
ments. This also sheds some light on why the index was incremented. It was
done in order to properly compare the two, because the index is probably zero-
based, and the total element count is certainly not. Now that you understand
these two conditions and know that they both originated in the same conditional
statement, you can safely assume that the validation done on the index parame-
ter was done in one line and that the source code was probably something like
the following:
ULONG AdjustedElementToGet = ElementToGet + 1;
if (ElementToGet == 0xffffffff ||
AdjustedElementToGet > Table->TotalElements)
return 0;
How can you tell whether ElementToGet + 1was calculated within the
ifstatement or if it was calculated into a variable first? You don’t really know
for sure, but when you look at all the references to EBXin Listing 5.2 you can
see that the value ElementToGet + 1is being used repeatedly throughout
the function. This suggests that the value was calculated once into a local vari-
able and that this variable was used in later references to the incremented
value. The compiler has apparently assigned EBXto store this particular local
variable rather than place it on the stack.
On the other hand, it is also possible that the source code contained multiple
copies of the statement ElementToGet + 1, and that the compiler simply
Beyond the Documentation 157