Вызов printf
с введенной пользователем строкой формата очень рискован, и любой спецификатор формата, который не соответствует фактическому аргументу, вызывает неопределенное поведение.
Но в вашем случае это равно цель вопроса.
Из первого вывода видно, что хотя printf
не было передано ни одного аргумента, шестым аргументом, который он находит для %x
, является указатель secret
в вызывающей стороне. frame.
Если вы передадите строку "%x%x%x%x%x%.2s"
, вы сможете получить содержимое секретного массива, поскольку значение, используемое printf
для %s
, будет указателем secret
.
Если вы передадите строку "%x%x%x%x%x%hhn"
, значение указателя secret
будет использоваться в качестве места для хранения количества символов, выведенных на данный момент, тем самым изменяя фактический secret
.
Вы можете использовать другой формат, чтобы изменить это количество символов. Например, %.0s
должен просто игнорировать аргумент, не производящий вывода, а %65c
должен производить 65 байтов вывода. Следовательно, если вы хотите сохранить 'A'
в секрете, эта строка формата может сработать: "%.0s%.0s%.0s%.0s%65d%hhn"
.
Конечно, это полностью спецификаций системы и компилятора c, действительно это подход не будет работать на 64-битных системах, но вы тестируете на 32-битной системе.