Сама строка формата будет в стеке (как вы объявили user_input
в качестве локальной переменной). Поэтому, если вы пройдете по стеку достаточно далеко (что именно %08x
заставляет printf
сделать), то в конечном итоге вы попадете в начало строки формата. %s
говорит printf
прочитать адрес из стека, а затем распечатать строку, найденную в этом месте. Поэтому он читает первые 4/8 байтов строки формата и использует их в качестве адреса.
Конечно, чтобы это работало, вам нужно точно знать, как далеко нужно прочитать стек, чтобы попасть в строку формата. Таким образом, вам может потребоваться настроить число %08x
.
Кроме того, пользователь, вводящий \x10
во время выполнения, отличается от строкового литерала в исходном коде, который содержит \x10
...