Add the rest of university notes
This commit is contained in:
366 files changed
+9844
-110
No files matched your search
@@ -0,0 +1,232 @@
|
||||
# Disassembler
|
||||
|
||||
> Sucessful reverse engineers do not evaluate each instruction individually unless they must. The process is too tedious.
|
||||
|
||||
### Global vs Local Variables
|
||||
|
||||
*Globbal 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
|
||||
|
||||

|
||||
|
||||
### 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
|
||||
```
|
||||
|
||||

|
||||
|
||||
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 from 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));
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
|
||||

|
||||
|
||||
### 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
|
||||
|
||||

|
||||
|
||||
##### 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
|
||||
|
||||

|
||||
|
||||
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.
|
||||
Reference in new issue
Block a user