Lukas' Notes

c programming-languages

Definition

Format String

A format string is a string template that allows dynamic string construction: placeholders called format specifiers are replaced, in order, by the parameters passed to a format-string function. The C stdio.h family exposes printf, fprintf, sprintf, and snprintf, all taking a const char* format followed by a variable argument list.

Common Format Specifiers

Specifiers on 64-bit platforms

SpecifierSizeUsage
%d4 bytesint
%u4 bytesunsigned int
%x4 byteshex
%s8-byte ptrstring (prints until \0)
%c1 bytecharacter
%ld8 byteslong int
%f4 bytesfloat
%lf8 bytesdouble

Every specifier starts with %.

Length Modifiers

Modifiers cast the specifier's type

Length modifiers add another layer of control on top of a specifier, casting it to a char, short, long, or long long.

ModifierSizeUsage
hh1 bytechar
h2 bytesshort int
l8 byteslong int
ll8 byteslong long int

For example printf("%hhx", 0x1337) prints one hex-encoded byte (37) — the hh cast truncates to char width. The hhn variant is the byte-truncating write form central to format-string attacks.

Padding and Direct Parameter Access

Two extra controls the attack chains together

  • Padding%10x left-pads the value up to 10 characters: printf("%10x", 0x1337)0000001337.
  • Direct parameter access%n$x reads the n-th argument directly, bypassing ordering and letting one argument be used multiple times or out of order: printf("%2$x", 0xcafe, 0xdead, 0xabba)dead (the 2nd argument after the format string).

The two combine: printf("%3$08x", …) prints the 3rd argument, zero-padded to 8 characters. This combination is the building block for both the read primitive (pick which stack slot to read) and the write primitive (control the printed-character count, then %n to write it) of Format String Vulnerability.

Format-String Functions

Obs

The C <stdio.h> family is printf, fprintf, sprintf, snprintf — all taking a const char* format followed by a variable argument list. It is the varargs signature, and the absence of any argument count in that signature, that makes the format-string attack possible: the function has to walk arguments by parsing %s out of the format string itself.