# Gadgets

Gadgets are small snippets of code followed by a `ret` instruction, e.g. `pop rdi; ret`. We can manipulate the `ret` of these gadgets in such a way as to string together a large chain of them to do what we want.

### Example

Let's for a minute pretend the stack looks like this during the execution of a `pop rdi; ret` gadget.

![](/files/-MM6rsFs6OPZXMxmI27r)

What happens is fairly obvious - `0x10` gets popped into `rdi` as it is at the top of the stack during the `pop rdi`. Once the `pop` occurs, `rsp` moves:

![](/files/-MM6rxCFqvlYzlurxKMW)

And since `ret` is equivalent to `pop rip`, `0x5655576724` gets moved into `rip`. Note how the stack is laid out for this.

### Utilising Gadgets

When we overwrite the return pointer, we overwrite the value pointed at by `rsp`. Once that value is popped, it points at the next value at the stack - but wait. We can overwrite the next value in the stack.

Let's say that we want to exploit a binary to jump to a `pop rdi; ret` gadget, pop `0x100` into `rdi` then jump to `flag()`. Let's step-by-step the execution.

![](/files/-MM6sIO-028Md3bAqC2q)

On the *original* `ret`, which we overwrite the return pointer for, we pop the gadget address in. Now `rip` moves to point to the gadget, and `rsp` moves to the next memory address.

![](/files/-MM6siGn5gKQpFIburDO)

`rsp` moves to the `0x100`; `rip` to the `pop rdi`. Now when we pop, `0x100` gets moved into `rdi`.

![](/files/-MM6spSm54IYMXI_s_dQ)

RSP moves onto the next items on the stack, the address of `flag()`. The `ret` is executed and `flag()` is called.

### Summary

Essentially, if the gadget pops values from the stack, simply place those values afterwards (including the `pop rip` in `ret`). If we want to pop `0x10` into `rdi` and then jump to `0x16`, our payload would look like this:

![](/files/-MM6tEbSq0eMI851A8U4)

Note if you have multiple `pop` instructions, you can just add more values.

![](/files/-MM6tVlFA6IkEX7iFCOH)

{% hint style="info" %}
We use `rdi` as an example because, if you remember, that's the register for the first parameter in 64-bit. This means control of this register using this gadget is important.
{% endhint %}

### Finding Gadgets

We can use the tool [`ROPgadget`](https://github.com/JonathanSalwan/ROPgadget) to find possible gadgets.

```
$ ROPgadget --binary vuln-64

Gadgets information
============================================================
0x0000000000401069 : add ah, dh ; nop dword ptr [rax + rax] ; ret
0x000000000040109b : add bh, bh ; loopne 0x40110a ; nop ; ret
0x0000000000401037 : add byte ptr [rax], al ; add byte ptr [rax], al ; jmp 0x401024
[...]
```

Combine it with `grep` to look for specific registers.

```
$ ROPgadget --binary vuln-64 | grep rdi

0x0000000000401096 : or dword ptr [rdi + 0x404030], edi ; jmp rax
0x00000000004011db : pop rdi ; ret
```


---

# Agent Instructions: 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:

```
GET https://ir0nstone.gitbook.io/notes/binexp/stack/return-oriented-programming/gadgets.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
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.
