Function Thunks and Stubs

A thunk (also called a stub or trampoline) is a tiny function whose only purpose is to forward execution to another function. It does little or no real work itself.

Why thunks exist

  • Import forwarding / indirection: A single fixed address can forward to a dynamically resolved real function without rewriting every call site.
  • Hooking: Replacing the jmp inside the stub redirects every caller through an attacker-controlled hook.
  • Delay-loaded imports: Compilers emit thunks for APIs resolved on first call.
  • Calling-convention adaptation: Some thunks translate cdecl ↔ stdcall or adjust argument layouts.
  • Manual mapping / shellcode: Position-independent stubs point to code loaded at runtime.

How to recognize a thunk

Look for a function that:

  • Has no meaningful logic (no loops, no arithmetic, no API calls except the jump).
  • Has a minimal or fake prologue, often just to keep the disassembler/decompiler happy.
  • Ends with an unconditional jmp to another function rather than ret.

Example:

.text:0078B460 network_send_caller proc near
.text:0078B460 push    ebp
.text:0078B461 mov     ebp, esp
.text:0078B463 pop     ebp
.text:0078B464 jmp     network_send
.text:0078B464 network_send_caller endp

The push ebp / mov ebp,esp / pop ebp sequence builds and immediately destroys a frame pointer so IDA and debuggers recognize a function boundary, while the real behavior is just jmp network_send.

What this means for analysis

  • All callers point to the stub, so the stub acts as a single gate.
  • Set a breakpoint on the stub to intercept every call, or follow the jump and break on the real implementation.
  • Arguments are already pushed before the stub is entered, so inspecting them at the stub works the same as at the real function.