Please sit on the right half of the room
--->
$ man <tool name>
...
$ xxd <filename> $ file <filename>
$ strings <filename>
$ nm -D <filename>
$ readelf <filename>
$ objdump -d -M intel --disassemble=<name>
How do multiple source files become a single executable?
ELF file formats:
How do multiple source files become a single executable?
ELF file formats:
Linker links objects with shared libraries.
This separation allows the operating system to implement file-system restrictions and similar security measures
$ man <tool name>
...
$ strace <filename> $ ltrace <filename>
To quickly understand an executable's behavior, we can monitor these library and system calls
strace will capture system calls, and ltrace will capture library calls
Argument Passing: How are arguments passed between functions? On the stack? In registers? Which registers?
Return Values: How are values returned from functions? On the stack? In registers? Which registers?
API vs. ABI
Why must we save registers?
int *foo(c,d) {
char e;
void *yeet = malloc(sizeof(c)*d);
/* Stop! */
return (int *)yeet;
}
int main(int argc, char *argv[]) {
int a = 5;
int b = 7;
char *bar = foo(a,b);
return 0;
}
foo:
push ebp
mov ebp, esp
sub esp, 8 ;make room
mov ecx, [ebp + 4] ;get c
mov edx, [ebp + 8] ;get d
mov eax, 4 ;sizeof(int)
mul edx ;sizeof(int)*d
push eax ;arg to malloc
call malloc
add esp, 4 ;clean up arg
mov [esp], eax ;store in yeet
add esp, 8 ;clean up locals
pop ebp
ret
main:
push ebp
mov ebp, esp
push 5 ;a
push 7 ;b
sub esp, 4 ;bar
mov eax, [esp + 4] ;get b
mov ebx, [esp + 8] ;get a
push ebx ;d
push eax ;c
call foo
add esp, 8 ;clean up args
mov [esp], eax ;store in bar
add esp, 12 ;clean up locals
mov eax, 0 ;return 0
pop ebp
ret
Text
Feature | x86 | x86_64 | ARM |
---|---|---|---|
Name | cdecl, stdcall | System V, Microsoft x64 | AAPCS64 |
Arguments | Pushed onto stack (reverse order) | First 6 arguments in registers: RDI, RSI, RDX, RCX, R8, R9 (others on stack) | First 8 arguments in registers: X0-X7 (others on stack) |
Return Value | EAX (integers) ST0 (floating point) |
RAX (integers) XMM0 (floating point) |
X0 |
Stack Alignment | 4-byte aligned | 16-byte aligned | 16-byte aligned |
Stack Growth | Downward | Downward | Downward |
Caller-Saved Registers | Others | RAX, RCX, RDX, R8, R9, R10, R11 | X19–X28, FP (frame pointer), LR (link register) |
Callee-Saved Registers | EBX, EBP, ESI, EDI | RBX, RBP, RDI, RSI, RSP, R12, R13, R14, and R15, XMM0–XMM5 | X0–X7, X9–X18 |
sum_two_numbers:
push ebp ; Save base pointer
mov ebp, esp ; Set stack frame
mov eax, [ebp+8] ; Get first argument (from stack)
mov ebx, [ebp+12] ; Get second argument (from stack)
add eax, ebx ; Compute the sum
pop ebp ; Restore base pointer
ret ; Return to the caller
_start:
push dword 5 ; Push the second argument (5) on the stack
push dword 10 ; Push the first argument (10) on the stack
call sum_two_numbers ; Call the function to sum 10 and 5
add esp, 8 ; Clean up the stack (remove arguments)
; Print result using printf
push eax ; Push result (in EAX) to the stack for printf
push msg ; Push message format string for printf
call printf ; Call printf
add esp, 8 ; Clean up the stack (remove arguments)
; Exit program
mov eax, 1 ; Syscall number for exit
xor ebx, ebx ; Exit code 0
int 0x80 ; Call kernel
sum_two_numbers:
mov rax, rdi ; First argument (in RDI)
add rax, rsi ; Second argument (in RSI)
ret ; Return result in RAX
_start:
mov rdi, 10 ; Move first argument (10) into RDI
mov rsi, 5 ; Move second argument (5) into RSI
call sum_two_numbers ; Call the function to sum 10 and 5
; Print result using printf
mov rsi, rax ; Move result (in RAX) to RSI for printf
mov rdi, msg ; Move message format string to RDI
xor rax, rax ; Clear RAX (for printf's variadic convention)
call printf ; Call printf
; Exit program
mov rax, 60 ; Syscall number for exit (in 64-bit)
xor rdi, rdi ; Exit code 0
syscall ; Call kernel
GDB but with enhancements for reverse engineering
run or r | Start program execution. |
---|---|
break or b <location>
|
Set a breakpoint at a function or line number. |
nexti or ni
|
Step over the current instruction (do not step into functions). |
stepi or si
|
Step into the current instruction or function. |
print or p <expr>
|
Print the value of an expression or variable. |
context |
Display a detailed context view (registers, stack, source, etc.). |
heap chunks |
Display all heap chunks in memory. |
info registers or i r
|
Show the values of all CPU registers. |
disassemble or disas
|
Disassemble the current function. |
x/<n><fmt> <address> |
Examine memory at the given address. |
gef memory |
Display memory mappings of the process. |