Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1
If you try to translate stack usage to a high-level perspective, you will see
that the stack can be used for a number of different things:
■■ Temporarily saved register values: The stack is frequently used for
temporarily saving the value of a register and then restoring the saved
value to that register. This can be used in a variety of situations—when
a procedure has been called that needs to make use of certain registers.
In such cases, the procedure might need to preserve the values of regis-
ters to ensure that it doesn’t corrupt any registers used by its callers.
■■ Local variables: It is a common practice to use the stack for storing
local variables that don’t fit into the processor’s registers, or for vari-
ables that must be stored in RAM (there is a variety of reasons why that
is needed, such as when we want to call a function and have it write a
value into a local variable defined in the current function). It should be
noted that when dealing with local variables data is not pushed and
popped onto the stack, but instead the stack is accessed using offsets,
like a data structure. Again, this will all be demonstrated once you enter
the real reversing sessions, in the second part of this book.
■■ Function parameters and return addresses: The stack is used for imple-
menting function calls. In a function call, the caller almost always
passes parameters to the callee and is responsible for storing the current
instruction pointer so that execution can proceed from its current posi-
tion once the callee completes. The stack is used for storing both para-
meters and the instruction pointer for each procedure call.

Heaps

A heap is a managed memory region that allows for the dynamic allocation of
variable-sized blocks of memory in runtime. A program simply requests a
block of a certain size and receives a pointer to the newly allocated block
(assuming that enough memory is available). Heaps are managed either by
software libraries that are shipped alongside programs or by the operating
system.
Heaps are typically used for variable-sized objects that are used by the pro-
gram or for objects that are too big to be placed on the stack. For reversers,
locating heaps in memory and properly identifying heap allocation and free-
ing routines can be helpful, because it contributes to the overall understanding
of the program’s data layout. For instance, if you see a call to what you know
is a heap allocation routine, you can follow the flow of the procedure’s return
value throughout the program and see what is done with the allocated block,
and so on. Also, having accurate size information on heap-allocated objects
(block size is always passed as a parameter to the heap allocation routine) is
another small hint towards program comprehension.

42 Chapter 2

Free download pdf