Patterns#

Recurring forms the operator sees in disassembly and writes by hand.

Function prologue / epilogue#

Most x86-64 callees set up a frame, save callee-saved registers, then restore on the way out.

func:
    push rbp
    mov  rbp, rsp
    sub  rsp, 32         ; local space (16-byte aligned)
    ; ... body ...
    add  rsp, 32
    pop  rbp
    ret

Tail call#

Replace call; ret with jmp when the call is the last thing the function does; one fewer stack frame, the same effect.

; instead of:  call helper / ret
jmp  helper

Position-independent code#

Compute addresses relative to rip so the code works wherever it gets loaded, in shared libraries, ASLR, and shellcode.

lea  rdi, [rel msg]
call printf wrt ..plt

NOP sled#

A run of 0x90 (nop) bytes that lets execution slide into a following payload. Used by exploit writers to widen the landing zone for an unreliable jump; defenders flag long nop runs.

times 64 nop
; payload:
; ...

Stack canary check#

Compiler emits a load of %fs:0x28 into the frame on entry and compares it back on exit; mismatch ends in __stack_chk_fail.

mov  rax, qword [fs:0x28]
mov  qword [rbp-0x8], rax
; ...
mov  rcx, qword [rbp-0x8]
xor  rcx, qword [fs:0x28]
jne  __stack_chk_fail

References#