Частина 15 - Дебагування подвійного значення
Давайте переглянемо 0x06_double.c as__.
#include <stdio.h>include "pico/stdlib.h"
int main() { stdio_init_all();
while(1) { double x = 40.5;
printf("%f\n", x);
sleep_ms(1000); }
return 0; } </pre>
Давайте запустимо наш дебагер.
radare2 -w arm -b 16 0x06_double.elfДавайте зробимо аналіз автоматично.
aaaaДавайте спробуємо потрапити до головної частини програми.
s mainДавайте перейдемо до візуального режиму, натиснувши V і потім p двічі, щоб потрапити до хорошого режиму дебагування.
Ми бачимо вказівник формату в [0x0000033c]..
:> psz @ [0x0000033c] %fПодвійне значення знаходиться в [0x00000340].
:> pff @ [0x00000340] 0x00004000 = 9.32830524e-09Окей... Той самий випадок, як у урокі про плаваючі числа, чому я витратив час на вибір 40.5? Я хотів показати вам остаточну доведення того, що компілятор буде обробляти це так само, як і плаваюче число, коли функціональність Pico SDK виконує своє чарівництво, оскільки немає співпроцесора. Давайте розглянемо модифікацію нашої програми.
#include <stdio.h>include "pico/stdlib.h"
int main() { stdio_init_all();
while(1) { double x = 40.55555555555555555555;
printf("%.16f\n", x)
sleep_ms(1000); }
return 0; } </pre>
При компіляції і виконанні програми ми отримуємо наступне.
40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000Окей, добре... Цей вигляд відрізняється. Давайте спробуємо здійснити аналіз зворотньої інженерії в динаміці в GDB. Для цього не потрібно виконувати цей аналіз і встановлювати всі необхідні кроки в GDB, оскільки є багато кроків, а також необхідна додаткова конфігурація Pico, як показано нижче.
Обсяг цього курсу полягає в розумінні статичної зворотньої інженерії, але я хотів відійти від цього і показати вам, що GDB показує нам з цим новим бінарним файлом. Для цього не потрібно використовувати динамічну зворотню інженерію, якщо ви не маєте ситуації, де ви повинні динамічно завантажити і вивести код бінарного файлу. Динамічна зворотня інженерія робить роботу легшою, але я хочу показати вам, що статична зворотня інженерія може забезпечити всі необхідні дані без необхідності встановлення віддаленого процесу для виконання бінарного файлу. Якщо ви вважаєте необхідним спробувати це, вам потрібно буде встановити репозиторій OpenOCD в папці Pico, яку ми створили в початку цього курсу. Ви можете знайти деталі на посиланні нижче і перейти до 5.1 Інсталяція OpenOCD в даних. https://datasheets.raspberrypi.org/pico/getting-started-with-pico.pdf
Вам потрібно буде відвідати сторінку нижче і завантажити uf2, розташований в Дебагування за допомогою іншого Raspberry Pi Pico , а потім встановити uf2 на перший Pico. https://www.raspberrypi.org/documentation/rp2040/getting-started/\#board-specifications
ТЕРМІНАЛ 1: Вам потрібно встановити перший термінал для входу в папку OpenOCD і виконати наступне.
src/openocd -f interface/picoprobe.cfg -f target/rp2040.cfg -s tclТЕРМІНАЛ 2: Вам потрібно потрапити в папку збірки проекту і виконати наступне.
arm-none-eabi-gdb 0x06_double.elf target extended-remote localhost:3333 load monitor reset init b main cТЕРМІНАЛ 3: Вам потрібно виконати емулятор екрану, який почне працювати з блінкучим курсором.
screen /dev/tty.usbmodem14101 115200Незважаючи на це коротке пояснення, давайте спробуємо здійснити аналіз динамічно в GDB.
Ми бачимо дві значення в 0x10000340 і 0x10000344. Давайте видалим всі розгалуження і зупинимося перед call до printf обгортка.
d b *0x1000032e cДавайте вивчіть значення кожного з цих місць.
p/x *0x10000340 0x71c71c72p/x *0x10000344 0x4044471c
</pre>
Відомо, що наступний вивід це те, що друкує.
40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000 40.5555555560000000Що відбувається, це те, що ці значення тепер знаходяться в R2 і R3 відповідно.
p/x $r2 0x71c71c72p/x $r3 0x4044471c </pre>
У ARM 32 збірці мови аргументи функцій передають у r0-r3, а якщо потрібно більше аргументів, вони розміщуються на стелі. У нашому випадку r0 містить наш модифікатор формату.
x/s $r0 0x10007070: "%.16f\n"У r1 бачимо значення, яке вказує на стелю.
x/w $r1 0x0: 0x20041f00p/x *0x20041f00 0xa </pre>
Це ще одне місце, яке потрапляє в printf обгортка, щоб належним чином друкувати рядок в STDOUT. У нашому наступному урокі ми зможемо статично хакнути.