Skip to content

Creating Exploits

Creating Exploits

  • Complex Instruction Set Computing (CISC)
  • x86 and x86-64 use little-endian format

https://syscalls.mebeim.net/?table=x86/64/x64/latest

Call types

cdecl:
- Arguments pushed on the stack in reverse order. (right to left)
- EAX, ECX, and EDX are saved before the call execution
- Others registers are saved in the function
- This cleans up its own stack before returning

syscall:
- EAX, ECX, and EDX are not saved before call
- arguments are pushed right to left

stdcall:
- Arguments pushed on the stack in reverse order. (right to left)
- EAX, ECX, and EDX are saved before the call execution
- Return values are stored in the EAX register.
- The Callie cleans up the stack

__fastcall:
- Uses ECX and EDX, then stack for arguments passed from right to left.
- The MS version uses RCX, RDX, R8 and R9 then the stack
- The Callie cleans up the stack

__vectorcall:
- Large Vector types passed as registers

__thiscall
- ECX is a pointer to the this variable
- Arguments are pushed on to the stack in reverse order.
- The top of the stack is the first argument
- The Callie cleans up the stack

Default Linux and OSX Argument and return Values

x86 32-bit function x64 64-bit function Arm 32-bit function Arm 64-bit function
Arg 1 [ebp-32] or [esp] RDI
Arg 2 [ebp-28] or [esp+4] RSI
Arg 3 [ebp-24] or [esp+8] RDX
Arg 4 [ebp-20] or [esp+12] R10
Arg 5 [ebp-16] or [esp+16] R8
Arg 6 [ebp-12] or [esp+20] R9
Arg 7 [ebp-8] or [esp+24] [ebp-8] or [esp]
Arg 8 [ebp-4] or [esp+28] [ebp-4] or [esp+4]

Linux Syscall

List of Syscall Argument registers for Comp Architectures

x86 and x64:

32-bit syscall 64-bit syscall
instruction int $0x80 syscall
syscall number EAX (execve = 0xb) RAX, (execve = 0x3b)
1-6 Args EBX ECX EDX ESI EDI EBP RDI RSI RDX R10 R8 R9
6+ Args EBX points to list in mem Forbidden

x86 Instructions

  • ret = pop rip

Stack

Here is how the stack is laid out in a function.

        ________________
ESP -> | .              |
       | .              |
       | .              |
       |________________|
       | Callee saved   |
       |  Registers     |
       | EBX, ESI & EDI |
       |   (as needed)  |
       |________________|
       | temporary      |
       | storage        |
       |________________|
       | local var #2   | [EBP - 8]
       |________________|
       | local var #1   | [EBP - 4]
       |________________|
EBP -> | Caller's EBP   |
       |________________|
       | Return Address | [EBP + 4]
       |________________|
       | Argument #1    | [EBP + 8]
       |________________|
       | Argument #2    | [EBP + 12] 
       |________________|
       | Argument #3    | [EBP + 16] 
       |________________|
       | Caller saved   |
       |  registers     |
       | EAX, ECX & EDX |
       | (as needed)    |
       |________________|

Stack pointer is stored on the stack and is overwritten with stack buffer overflow.

File tables

.dtors: destructor function table
.ctors: constructor function table
.got: global offset table
.plt: procedure linkage table

Shellcode

NOP sled can be hidden with @CABHKIJ. This is because these are the following instructions for this in order do not change the values of the registers.

inc eax 0x40 @
inc ebx 0x43 C
inc ecx 0x41 A
inc edx 0x42 B
dec eax 0x48 H
dec ebx 0x4B K
dec ecx 0x49 I
dec edx 0x4A J

Tools:
Shellcode in Golang