# Data modification

Luckily C contains a rarely-used [format specifier `%n`](/pwn/stack-exploitation/format-string/specifier.md#type-field). This specifier takes in a pointer (memory address) and writes there **the&#x20;*****number of characters written so far***.&#x20;

{% hint style="success" %}
If the input can be controlled, the number of characters written and the location where they are written can also be controlled.
{% endhint %}

## How %n works ?&#x20;

As explain in introduction, `%n` take a pointer as argument and write there **the&#x20;*****number of characters written so far***.&#x20;

This mean that to write `0x41` which is `81` in decimal, It means that 81 characters must be written before the `%n` placeholder in order to make it write `0x41` at the targeted location.

{% hint style="warning" %}
Note that the `%n` specifier will write an int size data at the targeted location so it will write "0x00000041" instead of "0x41"&#x20;

use :&#x20;

* `%hhn` to write a char size data (1 byte)
* `%hn` to write a short size data (2 bytes)
  {% endhint %}

## Padding

As explained before, a large amount of chars had to be sent in order to write a byte. But in much case, the user input lenght is size limited, so how to write as many characters as needed ?&#x20;

To do that, the usage of padding will help : `%81d` will write 81 characters (the decimal value of the pointed argument padded with spaces in order to have a data size of 81)."

## Arbitrary write

In order to write at an arbitrary location, the user input offset must be known because the targeted address will be injected here, such as [Arbitrary data read](/pwn/stack-exploitation/format-string/data-leak.md#arbitrary-data-read).

Then, A format string will be sent that will write the sufficient amount of characters in order to write the chosen value. &#x20;

{% hint style="warning" %}
If the chosen data is 0x41, the format string need to write 77 chars (81-4) because there is already 4 written char to inject the targeted address
{% endhint %}

Finally there is the `%n` or any of variants.&#x20;

{% hint style="warning" %}
In order to write an arbitrary value larger than 2 bytes, it's generaly needed to write it with several `%hn` format string cause that write more than `0xffff` (65535) chars in one time is too long.&#x20;

So, if the chosed value is 0x44434241, the payload must be :&#x20;

`[targeted address][targeted address+2]%16953d%7$hn%514d%6$hn`

\
16953 = 16961 (0x4241) - 8&#x20;

514 =  17475 (0x4443) - 16961 (chars already written for the first arbitrary write)

\
Note that **the lowest value must be write first** because it's impossible to padd with negative values.&#x20;
{% endhint %}

## Pwntools

Pwntools has a feature for automating `%n` format string exploits:

```python
from pwn import *
payload = fmtstr_payload(offset, {location : value})
```

Example if the user input offset is 7 and the targeted address is 0x41414141 and the arbitrary chose value is 0x44434241 :&#x20;

```python
from pwn import *
payload = fmtstr_payload(7, {0x41414141 : 0x44434241})
```

```
b'%65c%18$hhn%1c%19$hhn%1c%20$hhn%1c%21$hhnaaaAAAABAAACAAADAAA'
```

{% hint style="info" %}
In this example, the format string is injected before the targeted address ( it's better to do that in case of null bytes in the targeted address that will stop the printf function )&#x20;
{% endhint %}


---

# 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/format-string/data-modification.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.
