TL;DR
This guide explains how to exploit a buffer overflow vulnerability using the JMP ESP and CALL ESI techniques. We’ll cover finding suitable addresses, crafting an exploit payload, and executing shellcode.
Prerequisites
- Basic understanding of assembly language (x86).
- Familiarity with buffer overflow concepts.
- A vulnerable program (e.g., a C application with an unbounded string copy).
- Debugging tools like GDB or OllyDbg.
1. Identify the Vulnerability
The target program must have a buffer overflow vulnerability, typically in functions that handle user input without proper bounds checking (e.g., strcpy, gets). Use debugging tools to locate this function.
2. Find JMP ESP Gadget
- What is a JMP ESP gadget? It’s an instruction sequence in the program or loaded libraries that ends with
jmp esp. This allows us to redirect execution to the stack, where our shellcode will be located. - Use a disassembler (e.g., objdump, IDA Pro) to search for
jmp espwithin the executable and its linked libraries. -
objdump -d vulnerable_program | grep 'jmp esp' - Record the address of a reliable
jmp espgadget.
3. Find CALL ESI Gadget
- What is a CALL ESI gadget? This instruction sequence allows us to call an address pointed to by the ESI register. We’ll use this to execute our shellcode, which will be placed in memory and whose address stored in ESI.
- Use a disassembler to search for
call esiwithin the executable and its linked libraries. -
objdump -d vulnerable_program | grep 'call esi' - Record the address of a reliable
call esigadget.
4. Craft the Exploit Payload
- Shellcode: Prepare your shellcode (e.g., using Metasploit or hand-written assembly). Ensure it’s position-independent code if necessary.
- Padding: Determine the amount of padding needed to overwrite the return address on the stack. This is done by debugging and observing where the return address is located relative to the buffer.
- JMP ESP Address: Include the address of your
jmp espgadget in the payload, overwriting the original return address. - CALL ESI Address: Place the address of your
call esigadget after the JMP ESP address on the stack. - ESI Value: Put the address where you’ll place your shellcode in memory immediately after the CALL ESI address. This will be loaded into the ESI register by the CALL ESI instruction.
5. Example Payload Structure (Conceptual)
[Buffer] + [Padding] + [JMP ESP Address] + [CALL ESI Address] + [Shellcode Address]
6. Execute the Exploit
- Run the vulnerable program with your crafted payload as input.
- If successful, execution will jump to
jmp esp, then executecall esiwhich calls the address of shellcode in memory.
7. Debugging and Troubleshooting
- Segmentation Faults: Often indicate an incorrect JMP ESP or CALL ESI address, or a problem with your shellcode.
- Incorrect Shellcode Execution: Verify that the shellcode is correctly placed in memory and that the ESI register contains the correct address before the
call esiinstruction. - ASLR (Address Space Layout Randomization): If ASLR is enabled, you’ll need to find ways to bypass it (e.g., information leaks) or disable it for testing purposes.

