Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

create sequences of instructions that perform different operations based on dif-
ferent input values, and so on.
In IA-32 code, flags are a basic tool for creating conditional code. There are
arithmetic instructions that test operands for certain conditions and set proces-
sor flags based on their values. Then there are instructions that read these flags
and perform different operations depending on the values loaded into the
flags. One popular group of instructions that act based on flag values is the
Jcc (Conditional Jump) instructions, which test for certain flag values
(depending on the specific instruction invoked) and jump to a specified code
address if the flags are set according to the specific conditional code specified.
Let’s look at an example to see how it is possible to create a conditional state-
ment like the ones we’re used to seeing in high-level languages using flags.
Say you have a variable that was called bSuccessin the high-level language,
and that you have code that tests whether it is false. The code might look like
this:


if (bSuccess == FALSE) return 0;

What would this line look like in assembly language? It is not generally pos-
sible to test a variable’s value and act on that value in a single instruction—
most instructions are too primitive for that. Instead, we must test the value of
bSuccess(which will probably be loaded into a register first), set some flags
that record whether it is zero or not, and invoke a conditional branch instruc-
tion that will test the necessary flags and branch if they indicate that the
operand handled in the most recent instruction was zero (this is indicated by
the Zero Flag,ZF). Otherwise the processor will just proceed to execute the
instruction that follows the branch instruction. Alternatively, the compiler
might reverse the condition and branch if bSuccessis nonzero. There are
many factors that determine whether compilers reverse conditions or not. This
topic is discussed in depth in Appendix A.


Instruction Format


Before we start discussing individual assembly language instructions, I’d like
to introduce the basic layout of IA-32 instructions. Instructions usually consist
of an opcode (operation code), and one or two operands. The opcode is an
instruction name such as MOV, and the operands are the “parameters” that
the instruction receives (some instructions have no operands). Naturally, each
instruction requires different operands because they each perform a different
task. Operands represent data that is handled by the specific instruction (just
like parameters passed to a function), and in assembly language, data comes in
three basic forms:


Low-Level Software 47
Free download pdf