We can also define the external library functions that the program will be using. This list is described under a separate sections called the Import section. There are various sections that can be supported by a compiler. An example of these extended sections include the resource section, which contains data such as icons and images.
With the a basic picture of a what a program is structured, let see how our program was written. The first line, format PE CONSOLE, indicates that the program will be compiled as a Windows PE executable file and built to run on the console, better known in Windows as Command Prompt.
The next line, entry start, means that the program will start running code located at the start label. The name of the label can be changed as desired by the programmer. The next line, include '%include%\win32a.inc', will add declarations from the FASM library file win32a.inc. The declared functions expected are for calling the printf and
ExitProcess API functions discussed in the idata section.
There are three sections built in this program: the data, code, and idata sections. The section names here are labeled as .data, .code, and .idata. The permissions for each section are also indicated as either readable, writeable, and executable. The data section is where integers and text strings are placed and listed using the define byte (db) instruction. The code section is where lines of instruction code are executed. The idata section is where imported API functions are declared.
On the next line, we see that the data section is defined as a writeable section:
section '.data' data readable writeable
The program's .data section contains two constant variables, message and msgformat.
Both text strings are ASCIIZ (ASCII-Zero) strings, which means that they are terminated with a zero (0) byte. These variables are defined with the db instruction:
message db 'Hello World!',0 msgformat db '%s',0
The next line defines the code section. It is defined with read and execute permissions:
section '.code' code readable executable
It is in the .code section where the start: label is and where our code is. Label names are prefixed with a colon character.
In C programming, printf is a function commonly used to print out messages to the console using the C syntax, as follows:
int printf ( const char * format, ... );
The first parameter is the message containing format specifiers. The second parameter contains the actual data that fills up the format specifiers. In assembly language
perspective, the printf function is an API function that is in the msvcrt library. An API function is set up by placing the arguments in the memory stack space before calling a function. If your program is built in C, a function that requires 3 parameters (for
example, myfunction(arg1, arg2, arg3)) will have the following as an equivalent in assembly language:
push <arg3>
push <arg2>
For a 32-bit address space, the push instruction is used to write a DWORD (32 bits) of data on the top of the stack. The address of the top of the stack is stored in the ESP register. When a push instruction is executed, the ESP decreases by 4. If the argument is a text string or a data buffer, the address is push-ed to the stack. If the argument is a number value, the value is directly push-ed to the stack.
Following the same API calling structure, with two arguments, our program called printf in this manner:
push message push msgformat call [printf]
In the data section, the addresses, labeled as message and msgformat, are pushed to the stack as a setup before calling the printf function. Addresses are usually placed in square brackets, []. As discussed previously, the value at the address is used instead. The printf is actually a label that is the local address in the program declared in the .idata section.
[printf] then means that we are using the address of the printf API function from the msvcrt library. Thus, call [printf] will execute the printf function from the msvcrt library.
The same goes for ExitProcess. ExitProcess is a kernel32 function that terminates the running process. It requires a single parameter, which is the exit code. An exit code of 0 means that the program will terminate without any errors:
push 0
call [ExitProcess]
In C syntax, this code is equivalent to ExitProcess(0), which terminates the program with a success result defined with zero.
The program's .idata section contains external functions and is set with read and write permissions:
section '.idata' import data readable writeable
In the following code snippet, there are two portions. The first part indicates which library files the functions are located in. The library command is used to set the libraries
required, and uses the syntax library <library name>, <library file>. A
Once the libraries are declared, specific API functions are indicated using
the import command. The syntax is import <library name>, <function name>,
<function name in library file>. Two external API functions are imported here, kernel32's ExitProcess and msvcrt's printf:
import kernel32, ExitProcess, 'ExitProcess' import msvcrt, printf, 'printf'
A annotated version of the program can be found at https://github.com/
PacktPublishing/Mastering-Reverse-Engineering/blob/master/ch3/FASM%20commented.
txt
The library of API functions can be found in the MSDN library (https://msdn.microsoft.
com/en-us/library), which also has an offline version packaged in the Visual Studio installer. It contains detailed information about what the API function is for and how to use it. The online version looks like the following: