Function Call Convention
Content
Intel Architecture
Memory Layout Buffer Overflow
C Arrays
BoF Exploit
Assembler
Remote Exploit
Shellcode
Exploit Mitigations
Function Calls
Debugging Defeat Exploit Mitigations
Slide 2
Function Call Convention
Function call convention:
How functions work
Program-metadata on the stack
Stack based buffer overflow:
Overwrite program-metadata on the stack
Slide 3
x32 Memory Layout
0xc0000000
0xbfffffff
Stack
Heap
Code
0x0804800
0x0000000
Slide 4
Stacks
How do they work?
Stack
push pop
Slide 6
Stack
0x10000
0x00010
push pop
Slide 7
Stack
push 0x1
push 0x2
push 0x3
pop
push 0x4
Slide 8
Stack
push 0x1 0x01
push 0x2
push 0x3
pop
push 0x4
Slide 9
Stack
push 0x1 0x01
push 0x2 0x02
push 0x3
pop
push 0x4
Slide 10
Stack
push 0x1 0x01
push 0x2 0x02
0x03
push 0x3
pop
push 0x4
Slide 11
Stack
push 0x1 0x01
push 0x2 0x02
push 0x3
pop
push 0x4
Slide 12
Stack
push 0x1 0x01
push 0x2 0x02
0x04
push 0x3
pop
push 0x4
Slide 13
Stack on intel
Intel stack registers:
ESP: Stack Pointer
EBP: (Stack-) Base Pointer
EBP 0x01 0x1000
EBP = 0x1000 0x02 0x0FFC
ESP = 0x0FF8 0x04 0x0FF8
ESP
push pop
Slide 14
Stack in computers
Stack is using process memory as basis
CPU instruction support (because stack is so useful)
Note:
CPU instructions like push/pop are just for ease of use
The “stack values” can be accessed (read, write) like every other memory address
You can point the stack (ebp, esp) to wherever in the memory you want
There’s usually just ONE stack per process (thread)
Slide 15
x32 Call Convention
Functions and the Stack
x32 Call Convention
What is a function?
Self contained subroutine
Re-usable
Can be called from anywhere
After function is finished: Jump to the calling function
(calee)
Slide 17
x32 Call Convention
void main(void) {
int blubb = 0;
foobar(blubb);
return;
}
void foobar (int arg1) {
char compass1[];
char compass2[];
}
Slide 18
x32 Call Convention
What does the function foobar() need?
Function Argument:
blubb
Local variables
Compass1
Compass2
And: Address of next instruction in main()
&return
Slide 19
x32 Call Convention
Saved IP (&__libc_start) SIP
Stack Frame
Saved Frame Pointer SFP
<main>
Local Variables <main> blubb
Argument for <foobar> &blubb
Saved IP (&return) SIP
Stack Frame
Saved Frame Pointer SFP
<foobar>
compass1
Local Variables <foobar>
compass2
push pop
Slide 20
x32 Call Convention
void main(void) {
Pointer
int blubb = 0;
foobar(&blubb);
&blubb
return;
SIP
} Pointer SFP
compass1
void foobar(int *arg1) {
char compass1[]; compass2
char compass2[];
} allocate push pop
Slide 21
x32 Call Convention
Saved IP (&__libc_start) SIP
Stack Frame
Saved Frame Pointer SFP
<main>
Local Variables <main> blubb
Argument for <foobar> &blubb
Saved IP (&return) SIP (&return)
Stack Frame
Saved Frame Pointer SFP
<foobar>
compass1
Local Variables <foobar>
compass2
push pop
Slide 22
x32 Call Convention
SIP: Stored Instruction Pointer
Copy of EIP
Points to the address where control flow continues after
end of function
(return, ret)
Usually points into the code section
Slide 23
x32 Call Convention
SBP: Stored Base Pointer
Copy of EBP
Every function has its own little stack frame
Stack frame is where local variables, function arguments
etc. are
A function should only access its own stack frame
Most of the function epilogue and prologue handle
setting up and removing the stack frame
Note: It is not 100% necessary to completely understand
it - but you will see it in the disassembly of every function
Note: You can compile programs without using SBP (ASM
will be a bit harder to read)
Slide 24
x32 Call Convention
Attention! Assembler ahead!
AT&T vs Intel syntax
Intel syntax:
mov eax,1
mov ebx,0ffh
int 80h
AT&T syntax:
movl $1,%eax
movl $0xff,%ebx
int $0x80
Don’t hang me if I messed this up somewhere
Slide 25
x32 Call Convention
In ASM:
call 0x11223344 <&foobar>
push EIP
jmp 0x11223344
<function code> (0x11223344)
ret
pop eip
Slide 26
x32 Call Convention
In ASM:
call 0x11223344 <&foobar>
push EIP
jmp 0x11223344
mov ebp, esp
<function code>
mov esp, ebp
ret
pop eip
Slide 27
x32 Call Convention
In ASM:
call 0x11223344 <&foobar>
push EIP Prolog
jmp 0x11223344
mov ebp, esp
<function code> Function
mov esp, ebp
ret Epilog
pop eip
Slide 28
x32 Call Convention
Buffer writes go up
0xFFFF
arg1
SIP
SFP
compass1
compass2
0x0100
Stack grows down
push pop
Slide 29
x32 Call Convention
Recap:
User data is on the stack
Also: important stuff is on the stack (Instruction Pointer, SIP)
Stack grows down
Writes go up
Slide 30
x32 Call Convention Details
x32 Call Convention Details
int add(int x, int y) {
int sum;
sum = x + y;
return sum;
}
Slide 32
x32 Call Convention Details
c = add(3, 4) push 4 push 4
push 3 push 3
call add push EIP
jmp add
C ASM ASM, detailed
Slide 33
x32 Call Convention Details
add():
push 4 push ebp
push 3 mov ebp, esp,
push EIP sub esp, 0x10
jmp add
mov eax, DWORD PTR [ebp + 0xc]
mov edx, DWORD PTR [ebp + 0x8]
add eax, edx
mov DWORD PTR [ebp – 0x04], eax
mov eax, DWORD PTR [ebp – 0x04]
leave
ret
Slide 34
x32 Call Convention Details
add():
push 4 push ebp
push 3 mov ebp, esp,
push EIP sub esp, 0x10
jmp add
mov eax, DWORD PTR [ebp + 0xc]
mov edx, DWORD PTR [ebp + 0x8]
add eax, edx
mov DWORD PTR [ebp – 0x04], eax
mov eax, DWORD PTR [ebp – 0x04]
mov esp, ebp ; leave
pop ebp ; leave
ret
Slide 35
x32 Call Convention Details
add():
push 4 push ebp
push 3 mov ebp, esp,
push EIP sub esp, 0x10
jmp add
mov eax, DWORD PTR [ebp + 0xc]
mov edx, DWORD PTR [ebp + 0x8]
add eax, edx
mov DWORD PTR [ebp – 0x04], eax
mov eax, DWORD PTR [ebp – 0x04]
mov esp, ebp ; leave
pop ebp ; leave
pop eip ; ret
Slide 36
x32 Call Convention Details
add():
push 4 push ebp
push 3 mov ebp, esp,
push EIP sub esp, 0x10
jmp add
mov esp, ebp ; leave
pop ebp ; leave
pop eip ; ret
Slide 37
Function Prolog
x32 Call Convention - Function Prolog
…
push 4
EBP SIP
push 3 SFP
call add
ESP c
From:
<main>
…
Slide 39
x32 Call Convention - Function Prolog
…
push 4
EBP SIP
push 3 SFP
call add
ESP c
From:
<main>
… 4
Slide 40
x32 Call Convention - Function Prolog
…
push 4
EBP SIP
push 3 SFP
call add
ESP c
From:
<main>
… 4
EIP 3
Slide 41
x32 Call Convention - Function Prolog
…
push 4
EBP SIP
push 3 SFP
call add
ESP c
From:
<main>
… 4
EIP 3
SIP (= EIP)
push ebp
mov ebp, esp
sub esp, 0x10
mov esp, ebp
pop ebp
pop eip
Slide 42
x32 Call Convention - Function Prolog
…
push 4
EBP SIP
push 3 SFP
call add
ESP c
From:
<main>
… 4
EIP 3
SIP (= old EIP)
push ebp
mov ebp, esp
sub esp, 0x10
mov esp, ebp
pop ebp
pop eip
Slide 43
x32 Call Convention - Function Prolog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp
3
pop eip
SIP
From:
<add>
Slide 44
x32 Call Convention - Function Prolog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp
3
pop eip
SIP
SBP (=old EBP)
From:
<add>
Slide 45
x32 Call Convention - Function Prolog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp
3
pop eip
SIP
SBP
From:
<add>
Slide 46
x32 Call Convention - Function Prolog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp
3
pop eip
SIP
SBP
From:
<add>
Slide 47
Execute Function
x32 Call Convention - Execute Function
EBP SIP
SFP
From:
c
<main>
mov eax, DWORD PTR [ebp + 0xc] 4 EBP+0xc
mov edx, DWORD PTR [ebp + 0x8] 3 EBP+0x8
add eax, edx
SIP
mov DWORD PTR [ebp – 0x04], eax
SBP
mov eax, DWORD PTR [ebp – 0x04]
sum EBP-0x04 From:
<add>
Slide 49
Function Epilog
x32 Call Convention - Function Epilog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp
3
pop eip
SIP
SBP
From:
<add>
Slide 51
x32 Call Convention - Function Epilog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp
3
pop eip
SIP
SBP
From:
<add>
Slide 52
x32 Call Convention - Function Epilog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp EIP 3
pop eip
SIP
SBP
Slide 53
x32 Call Convention - Function Epilog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp EIP 3
pop eip
SIP
SBP
push 4
push 3
push EIP
jmp add
…
Slide 54
x32 Call Convention - Function Epilog
push ebp
mov ebp, esp
EBP SIP
sub esp, 0x10 SFP
ESP c
From:
<main>
mov esp, ebp 4
pop ebp EIP 3
pop eip
push 4
push 3
push EIP
jmp add
…
Slide 55
x32 Call Convention - Function Calling
call <addr> =
push EIP
jmp <addr>
leave =
mov esp, ebp
pop ebp
ret =
pop eip
Slide 56
x32 Call Convention - Function Calling
Why “leave”?
Opposite of “enter”
“enter”:
push ebp
mov ebp, esp
sub esp, imm
Why no “enter” used?
enter:
8 cycle latency
10-20 micro ops
call <addr>; mov ebp, esp; sub esp, imm:
3 cycles latency
4-6 micro ops
Slide 57
x32 Call Convention - Function Calling
Recap:
When a function is called:
EIP is pushed on the stack (=SIP)
(“call” is doing implicit “push EIP”)
At the end of the function:
SIP is recovered into EIP
(“ret” is doing implicit “pop EIP”)
Slide 58
Accessing the Stack
Accessing the stack: triple view
SIP 0x1014
EBP SFP 0x1010
c 0x100C
4 0x1008
ESP 3 0x1004
0x1000
A) push 0x1
B) mov [ebp-0x10], 0x1
C) mov eax, 0x1000
mov [eax], 0x1
Slide 60
Function Calls in x64
x32 Call Convention - Function Call in x64
Differences between x32 and x64 function calls:
Arguments are in registers (not on stack)
RDI, RSI, RDX, R8, R9
Slide 62
x32 Call Convention - Function Call in x64
Differences between x32 and x64 function calls
Different ASM commands doing the same thing
callq (call)
leaveq (leave)
retq (ret)
Slide 63
x32 Call Convention - Function Call in x64
Some random x64 architecture facts:
The stack should stay 8-byte aligned at all times
An n-byte item should start at an address divisible by n
E.g. 64 bit number: 8 bytes, can be at 0x00, 0x08, 0x10, 0x18, …
%rsp points to the lowest occupied stack location
not the next one to use!
Slide 64
Function Call Convention Cheat Sheet
x32 Parameter Syscall nr in
x32 userspace stack
x32 syscalls ebx, ecx, edx, esi, edi, ebp eax
x64 Parameter Syscall nr in
x64 userspace rdi, rsi, rdx, rcx, r8, r9
x64 syscall rdi, rsi, rdx, r10, r8, r9 rax
http://stackoverflow.com/questions/2535989/what-are-the-calling-conventions-for-unix-linux-system-calls-on-x86-64
Slide 65
EBP Cheat Sheet
SIP
SFP
c
EBP+0x0C 4 (argument 2)
EBP+0x08 3 (argument 1)
EBP+0x04 SIP
EBP SBP
EBP-0x04 sum (local var)
(local buffer)
ESP EBP-0x50
Slide 66
EBP Cheat Sheet
Slide 67
Outro
Further questions
Can you implement push/pop in ASM? (without actually using push/pop)
Slide 69
Answers
Pseudocode:
# EAX is the new ESP
push <data>:
sub eax, 4
mov (%eax), <data>
pop <register>:
mov <register>, (%eax)
add eax, 4
Slide 70