POSTED BY GAURAV BAPLAWAT ON OCT 9, 2011 continuing...
Introduction to Memory and
Stacks:
There are three main sections of
memory:
1. Stack Section - Where the stack is located, stores local variables and
function arguments.
2. Data Section - Where the heap is located, stores static and dynamic
variables.
3. Code Section - Where the actual program instructions are located.
The stack section starts at the high memory addresses and grows downwards,
towards the lower memory addresses; conversely, the data section (heap) starts
at the lower memory addresses and grows upwards, towards the high memory
addresses. Therefore, the stack and the heap grow towards each other as more
variables are placed in each of those sections. I have shown that in below
Figure..
High Memory Addresses (0xFFFFFFFF)
---------------------- <-----Bottom of the stack
|
|
|
| |
| Stack | | Stack
grows down
|
| v
|
|
|---------------------| <----Top of the stack (ESP points here)
|
|
|
|
|
|
|
|
|
|
|---------------------| <----Top of the heap
|
|
|
| ^
| Heap |
| Heap grows up
|
| |
|
|
|---------------------| <-----Bottom of the heap
|
|
| Instructions |
|
|
|
|
-----------------------
Low Memory Addresses (0x00000000)
Some
Essential Assembly Instructions for Reverse Engineering:
Instruction
|
Example
|
Description
|
push
|
push eax
|
Pushes the value stored in EAX
onto the stack
|
pop
|
pop eax
|
Pops a value off of the stack and
stores it in EAX
|
call
|
call 0x08abcdef
|
Calls a function located at
0x08abcdef
|
mov
|
mov eax,0x5
|
Moves the value of 5 into the EAX
register
|
sub
|
sub eax,0x4
|
Subtracts 4 from the value in the
EAX register
|
add
|
add eax,0x1
|
Adds 1 to the value in the EAX
register
|
inc
|
inc eax
|
Increases the value stored in EAX
by one
|
dec
|
dec eax
|
Decreases the value stored in EAX
by one
|
cmp
|
cmp eax,edx
|
Compare values in EAX and EDX; if
equal set the zero flag* to 1
|
test
|
test eax,edx
|
Performs an AND operation on the
values in EAX and EDX; if the result is zero, sets the zero flag to 1
|
jmp
|
jmp 0x08abcde
|
Jump to the instruction located at
0x08abcde
|
jnz
|
jnz 0x08ffff01
|
Jump if the zero flag is set to 1
|
jne
|
jne 0x08ffff01
|
Jump to 0x08ffff01 if a comparison
is not equal
|
and
|
and eax,ebx
|
Performs a bit wise AND operation
on the values stored in EAX and EBX; the result is saved in EAX
|
or
|
or eax,ebx
|
Performs a bit wise OR operation
on the values stored in EAX and EBX; the result is saved in EAX
|
xor
|
xor eax,eax
|
Performs a bit wise XOR operation
on the values stored in EAX and EBX; the result is saved in EAX
|
leave
|
leave
|
Remove data from the stack before
returning
|
ret
|
ret
|
Return to a parent function
|
nop
|
nop
|
No operation (a 'do nothing'
instruction)
|
*The zero flag (ZF) is a 1 bit
indicator which records the result of a cmp or test instruction
Each instruction performs one specific task, and can deal directly with
registers, memory addresses, and the contents thereof. It is easiest to
understand exactly what these functions are used for when seen in the context
of a simple hello world program and try
to relate assembly language with high level language such as C language.
Here is simple C program that
displays Hello World:
int main(int argc, char *argv[])
{
printf("Hello
World!\n");
return 0; }
Save this program as helloworld.c and compile it with 'gcc -o helloworld
helloworld.c'; run the resulting binary and it should print "Hello
World!" on the screen and exit. Ahhah... It looks quite simple. Now let's
look how it will look in assembly language.
0x8048384 push
ebp
<--- Save the EBP
value on the stack
0x8048385 mov ebp,esp
<--- Create a new
EBP value for this function
0x8048387 sub
esp,0x8
<---Allocate 8
bytes on the stack for local variables
0x804838a and
esp,0xfffffff0 <---Clear the last byte of the ESP register
0x804838d mov eax,0x0
<---Place a zero in
the EAX register
0x8048392 sub
esp,eax
<---Subtract EAX
(0) from the value in ESP
0x8048394 mov DWORD PTR
[esp],0x80484c4 <---Place our argument for the printf() (at address
0x08048384) onto the stack
0x804839b call 0x80482b0
<_init+56>
<---Call printf()
0x80483a0 mov
eax,0x0
<---Put our return
value (0) into EAX
0x80483a5
leave
<---Clean up the
local variables and restore the EBP value
0x80483a6
ret
<---Pop the saved
EIP value back into the EIP register
As you can easily figure out these
instructions are similar to that of C program. You can easily note that flow of
program is same. Off course it will be same as its a assembly code of same
binary (exe) obtained from executing above C program.
I hope you all like it. We will
continue our discussion tomorrow where i will explain how to analyze assembly
language codes for those binaries whose high level source code we don't have.
A quick tip for all users how to
learn assembly language better... Pick a already made code and generate
its binary or exe file and now obtains the assembly code of that binary and try
to relate assembly code with high language code. I guarantee that will surely
help you to understand better as I always used to do understand things like
these ways only.
Hope You Like it keep commenting Thanks...
|