Files
2026-10-04 15:24:17 +01:00

231 lines
5.3 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Disassembler
> Sucessful reverse engineers do not evaluate each instruction individually unless they must. The process is too tedious.
### Global vs Local Variables
*Global variables* can be accessed and used by any function in the program.
*Local variables* can be accessed only by the function in which they are defined.
Both types of variables are declared similarly in `c` but completely differently in assembly.
> **Global** variables are referenced by **memory addresses**
>
> **Local** variables are referenced by **stack addresses**
### Recognising if Statements
In IDA, branches will be represented as such:
```c
int x = 1;
int y = 2;
if (x == y){
printf("x equals y\n");
} else {
printf("x does not equals y\n");
}
```
```assembly
00401006 mov [ebp+var_8], 1
0040100D mov [ebp+var_4], 2
00401014 mov eax, [ebp+var_8]
00401017 cmp eax, [ebp+var_4]
0040101A jnz short loc_40102B
0040101C push offset aXEqualsY_ ; "x equals y.\n"
00401021 call printf
00401026 add esp, 4
00401029 jmp short loc_401038
0040102B loc_40102B:
0040102B push offset aXIsNotEqualToY ; "x is not equal to y.\n"
00401030 call printf
```
Here the instruction `jnz` on line 5 causes the branch. A `cmp` is done between `ebp+var_8` (y) and `ebp+var_4`(x). If the values are not equal, then we jump to “x is not equal to y”
This is what that looks like in IDA
![1646766562.png](img/1646766562.png)
### Recognising Loops
##### Finding for loops
For loops have 4 basic components:
1. initialisation
2. comparison
3. execution instructions
4. increment/decrement
```c
int i;
for (i=0; i<100; i++)
{
printf("i equals %d\n", i);
}
```
```assembly
mov [ebp+var_4], 0 ; INITIALISATION
jmp short loc_401016
loc_40100D:
mov eax, [ebp+var_4] ; INCREMENT START
add eax, 1
mov [ebp+var_4], eax ; INCREMENT STOP
loc_401016:
cmp [ebp+var_4], 64h ; COMPARISON
jge short loc_40102F ; COMPARISON
mov ecx, [ebp+var_4]
push ecx
push offset aID ; "i equals %d\n"
call printf
add esp, 8
jmp short loc_40100D ; UNCONDITIONAL JUMP
```
![1646766968.png](img/1646766968.png)
Note: the box on the bottom right is the function’s epilogue
##### Finding While Loops
While loops look similar to for loops in assembly, but are easier to understand.
```c
int status = 0;
int result = 0;
while (status == 0)
{
result = performAction();
status = checkResult(result);
}
```
The assembly for this code will look similar to before; however, it lacks the *increment* section.
```assembly
mov [ebp+var_4], 0
mov [ebp+var_8], 0
loc_401044:
cmp [ebp+var_4], 0
jnz short loc_401063 ; CONDITIONAL JUMP
call performAction
mov [ebp+var_8], eax
mov eax, [ebp+var_8]
push eax
call checkResult
add esp, 4
mov [ebp+var_4], eax
jmp short loc_401044 ; UNCONDITIONAL JUMP
```
A conditional jump occurs on line 5 and an unconditional jump at line 13, but the only way for this code to stop executing repeatedly is for that conditional jump to occur.
#### Understanding Function Call Conventions
Function call conventions govern:
- The order in which parameters are placed on the stack or in registers
- Whether the caller or callee is responsible for cleaning up the stack
Calling convention depends on the compiler used
```c
int adder(int a, int b)
{
return a+b;
}
void main()
{
int x=1;
int y=2;
printf("adder(1,2): %d", adder(x,y));
}
```
![1646767431.png](img/1646767431.png)
### Switch Statements
Switch statements are compiled in two different ways: if style or using jump tables
```c
switch(i)
{
case 1:
printf("i = %d", i+1);
break;
case 2:
printf("i = %d", i+2);
break;
case 3:
printf("i = %d", i+3);
break;
default:
break;
}
```
##### If Style
![1646767721.png](img/1646767721.png)
##### Jump Table
This example is usually found with large contiguous `switch` statements. The compiler optimises the code to avoid needing to make so many comparisons
![1646767841.png](img/1646767841.png)
This assembly uses a jump table which defines offsets to additional memory locations. The switch variable (stored in `ecx`) is used as an index into the jump table.
`edx` is multiplied by 4 and added to the base of the jump table to determine which case code block to jump to.
It is multiplied by 4 because each entry in the jump table is an address that is 4 bytes in size.
### Disassembling Arrays
```c
int b[5] = {123, 87, 487, 7, 978};
void main()
{
int i;
int a[5];
for(i = 0; i<5; i++)
{
a[i] = i;
b[i] = i;
}
}
```
In assembly, arrays are accessed using a base address as a starting point. The size of each element is not always obvious, but can be determined by seeing how the array is being indexed.
```assembly
00401006 mov [ebp+var_18], 0
0040100D jmp short loc_401018
0040100F loc_40100F:
0040100F mov eax, [ebp+var_18]
00401012 add eax, 1
00401015 mov [ebp+var_18], eax
00401018 loc_401018:
00401018 cmp [ebp+var_18], 5
0040101C jge short loc_401037
0040101E mov ecx, [ebp+var_18]
00401021 mov edx, [ebp+var_18]
00401024 mov [ebp+ecx*4+var_14], edx ; LOCAL
00401028 mov eax, [ebp+var_18]
0040102B mov ecx, [ebp+var_18]
0040102E mov dword_40A000[ecx*4], eax ; GLOBAL
00401035 jmp short loc_40100F
```
In both cases `ecx` is used as the index, which is multiplied by 4 to account for the size of the elements. This is added onto the base address of the array to access the proper array element.