Skip to content

Binary Analysis and Exploitation

Registers and Memory Layout

# Registers (x64)

RegisterLow 32-bitsLow 16-bitsLow 8-bitsNotes
%rax%eax%ax%ala function's return value, caller-saved
%rdi%edi%di%dil1st argument of a function, caller-saved
%rsi%esi%si%sil2nd argument of a function, caller-saved
%rdx%edx%dx%dl3rd argument of a function, caller-saved
%rcx%ecx%cx%cl4th argument of a function, caller-saved
%r8%r8d%r8w%r8b5th argument of a function, caller-saved
%r9%r9d%r9w%r9b6th argument of a function, caller-saved
%r10%r10d%r10w%r10btemporary register, caller-saved
%r11%r11d%r11w%r11btemporary register, caller-saved
%rbp%ebp%bp%bplbase pointer, pointing to the base of the current stack frame, callee-saved
%rsp%esp%sp%splstack pointer, pointing to the topmost element in the stack, callee-saved
%rbx%ebx%bx%bllocal variable, callee-saved
%r12%r12d%r12w%r12blocal variable, callee-saved
%r13%r13d%r13w%r13blocal variable, callee-saved
%r14%r14d%r14w%r14blocal variable, callee-saved
%r15%r15d%r15w%r15blocal variable, callee-saved
%ripinstruction pointer

# Memory Layout

memory layout

# Stack Frame Layout

A stack is allocated at a high address and grows towards lower addresses.

stack frame layout

# Position Independent Executables (PIE)

The memory addresses are not fully randomized, particularly the lower 3 bits of the base address, even when PIE is enabled.

pwndbg> info proc mappings
process 67443
Mapped address spaces:

Start Addr         End Addr           Size               Offset             Perms File
0x0000555555554000 0x0000555555555000 0x1000             0x0                r--p  /ptr/vuln
0x0000555555555000 0x0000555555556000 0x1000             0x1000             r-xp  /ptr/vuln
0x0000555555556000 0x0000555555557000 0x1000             0x2000             r--p  /ptr/vuln
0x0000555555557000 0x0000555555558000 0x1000             0x2000             r--p  /ptr/vuln
0x0000555555558000 0x0000555555559000 0x1000             0x3000             rw-p  /ptr/vuln
0x00007ffff7c00000 0x00007ffff7c28000 0x28000            0x0                r--p  /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007ffff7c28000 0x00007ffff7db0000 0x188000           0x28000            r-xp  /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007ffff7db0000 0x00007ffff7dff000 0x4f000            0x1b0000           r--p  /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007ffff7dff000 0x00007ffff7e03000 0x4000             0x1fe000           r--p  /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007ffff7e03000 0x00007ffff7e05000 0x2000             0x202000           rw-p  /usr/lib/x86_64-linux-gnu/libc.so.6
0x00007ffff7e05000 0x00007ffff7e12000 0xd000             0x0                rw-p
0x00007ffff7fa0000 0x00007ffff7fa3000 0x3000             0x0                rw-p
0x00007ffff7fbd000 0x00007ffff7fbf000 0x2000             0x0                rw-p
0x00007ffff7fbf000 0x00007ffff7fc1000 0x2000             0x0                r--p  [vvar]
0x00007ffff7fc1000 0x00007ffff7fc3000 0x2000             0x0                r--p  [vvar_vclock]
0x00007ffff7fc3000 0x00007ffff7fc5000 0x2000             0x0                r-xp  [vdso]
0x00007ffff7fc5000 0x00007ffff7fc6000 0x1000             0x0                r--p  /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x00007ffff7fc6000 0x00007ffff7ff1000 0x2b000            0x1000             r-xp  /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x00007ffff7ff1000 0x00007ffff7ffb000 0xa000             0x2c000            r--p  /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x00007ffff7ffb000 0x00007ffff7ffd000 0x2000             0x36000            r--p  /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x00007ffff7ffd000 0x00007ffff7fff000 0x2000             0x38000            rw-p  /usr/lib/x86_64-linux-gnu/ld-linux-x86-64.so.2
0x00007ffffffdd000 0x00007ffffffff000 0x22000            0x0                rw-p  [stack]
0xffffffffff600000 0xffffffffff601000 0x1000             0x0                --xp  [vsyscall]

# Heap

Unlike the stack, the heap segment starts at a low address and grows towards higher memory addresses. The basic concept in the heap meamory allocation is chunk, as defined below.

/*
  This struct declaration is misleading (but accurate and necessary).
  It declares a "view" into memory allowing access to necessary
  fields at known offsets from a given base. See explanation below.
*/

struct malloc_chunk {

  INTERNAL_SIZE_T      mchunk_prev_size;  /* Size of previous chunk (if free).  */
  INTERNAL_SIZE_T      mchunk_size;       /* Size in bytes, including overhead. */

  struct malloc_chunk* fd;         /* double links -- used only if free. */
  struct malloc_chunk* bk;

  /* Only used for large blocks: pointer to next larger size.  */
  struct malloc_chunk* fd_nextsize; /* double links -- used only if free. */
  struct malloc_chunk* bk_nextsize;
};

# House of Force

"House Of Force" is an exploitation approach against the heap memory. This exploitation requires the attacker can override the size field in the top chunk's header. Then, the attacker can leverage the integer overflow to control the memory address that malloc will return, further leading to arbitrary memory read/write.

# References