C - специфікатор формату% x


78

У мене маленьке запитання. Я знаю, що специфікатор формату% x можна використовувати для зчитування значень зі стеку під час атаки рядка формату.

Я знайшов такий код:

Що означає 08? Що саме робить? Дякую :)


1
Ширина поля 8 символів, коротші числа з префіксом до початкових нулів відповідно до ширини поля, наприклад 000007acабо 0005ceef.
Христо Ілієв

2
Про яку функцію йде мова? Ви говорите "прочитати значення", але всі відповіді, здається, припускають printf(), що використовується.
розслабитися

1
@unwind хороший момент. ми всі пишемо для друку.
Grijesh Chauhan

1
Дурний я. Так, я мав на увазі використання цього коду у функції printf.
Matthew

Відповіді:


138

Зламатися:

  • 8 говорить, що ви хочете показати 8 цифр
  • 0що ви хочете поставити префікс до 0'замість просто порожніх пробілів
  • x що ви хочете друкувати малими шістнадцятковими літерами.

Швидкий приклад (завдяки Грієшу Чаухану):

Вихід:

Також для довідки див. Http://www.cplusplus.com/reference/cstdio/printf/ .


9
Додав приклад, сподіваюся, що вам сподобався. ЯКЩО ні, ви не зможете повернутися до своєї версії
Grijesh Chauhan

1
@Matthew ви також повинні спробувати з %-8xі капіталом X. і спостерігати за ефектом
Grijesh Chauhan

1
Незважаючи на те, що 8і 0є обома цифрами (і, отже, однаковими частинами граматики англійською мовою), вони є різними частинами граматики формату printf. 0є «прапор» , і 8є параметром «ширина» (який може бути <ε (no input)>, <d (any number greater than 0)>або * (a literal asterisk)). Це, безумовно, неінтуїтивний API! Але що не скажеш ... це все старомодні речі C, де пам’ять була такою преміум-категорією, що ти хочеш зберегти якомога більше символів у програмі - я погоджуюся з їх рішенням, враховуючи обмеження, з якими вони стикалися!
Ari Sweedler

1
Я думаю, що це цікаве питання, про яке потрібно поміркувати. Як би ви переробили printfсинтаксис? Мені подобається використовувати %в якості символу втечі, він такий унікальний і нішевий для форматування рядків. Я думаю, що модифікатори слід додавати, а не додавати , але таким чином ви можете читати їх зліва направо. Щось на зразок %<specifier>[%f<flags>][%-w<width>.<precision>]%, замість %[flags][width][.precision][length]specifier. Я вибрав %між кожним полем, а також одне для закриття (так що ви все ще можете зробити %x%x- `% x %% x%) і дозволяє вказати специфікатор із декількома
символами

5

%08x означає, що кожне число має бути надруковане принаймні 8 символів із заповненням усіх відсутніх цифр нулями, наприклад, для "1" буде 00000001


2

Це вказує, скільки цифр ви хочете показувати.

ціле число або *, що визначає мінімальну ширину поля. Результат заповнюється пробілами (за замовчуванням), якщо потрібно, ліворуч, якщо вирівняно праворуч, або праворуч, якщо вирівняно ліворуч. У випадку, коли використовується *, ширина визначається додатковим аргументом типу int. Якщо значення аргументу від'ємне, це призводить до вказаного прапора - і додатної ширини поля.



2

Атака рядка форматування на printf, про яку ви згадали, не характерна для форматування "% x" - у будь-якому випадку, коли printf має більше параметрів форматування, ніж передані змінні, він буде зчитувати значення зі стеку, які йому не належать. Ви отримаєте те саме питання з% d, наприклад. % x корисний, коли ви хочете бачити ці значення як шістнадцяткові.

Як пояснювалось у попередніх відповідях,% 08x видасть 8-значне шістнадцяткове число, заповнене попередніми нулями.

Використовуючи форматування у прикладі коду в printf, без додаткових параметрів:

Витягне 4 параметри зі стеку та відобразить їх як 8-значні заповнені шістнадцяткові числа.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.