Reversing : The Hacker's Guide to Reverse Engineering

(ff) #1

Relocations are important for several reasons. First of all, they’re the reason
why there are never absolute addresses in executable headers, only in code.
Whenever you have a pointer inside the executable header, it’ll always be in
the form of a relative virtual address (RVA). An RVA is just an offset into the file.
When the file is loaded and is assigned a virtual address, the loader calculates
real virtual addresses out of RVAs by adding the module’s base address
(where it was loaded) to an RVA.


Image Sections


An executable image is divided into individual sections in which the file’s con-
tents are stored. Sections are needed because different areas in the file are
treated differently by the memory manager when a module is loaded. A com-
mon division is to have a code section (also called a text section) containing the
executable’s code and a data section containing the executable’s data. In load
time, the memory manager sets the access rights on memory pages in the dif-
ferent sections based on their settings in the section header. This determines
whether a given section is readable, writable, or executable.
The code section contains the executable’s code, and the data sections con-
tain the executable’s initialized data, which means that they contain the con-
tents of any initialized variable defined anywhere in the program. Consider
for example the following global variable definition:


char szMessage[] = “Welcome to my program!”;

Regardless of where such a line is placed within a C/C++ program (inside
or outside a function), the compiler will need to store the string somewhere in
the executable. This is considered initialized data. The string and the variable
that point to it (szMessage) will both be stored in an initialized data section.


Section Alignment


Because individual sections often have different access settings defined in the
executable header, and because the memory manager must apply these access
settings when an executable image is loaded, sections must typically be page-
aligned when an executable is loaded into memory. On the other hand, it
would be wasteful to actually align executables to a page boundary on disk—
that would make them significantly bigger than they need to be.
Because of this, the PE header has two different kinds of alignment fields:
Section alignment and file alignment. Section alignment is how sections are
aligned when the executable is loaded in memory and file alignment is how
sections are aligned inside the file, on disk. Alignment is important when
accessing the file because it causes some interesting phenomena. The problem


Windows Fundamentals 95
Free download pdf