Частина 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 0x71c71c72

p/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 0x71c71c72

p/x $r3 0x4044471c </pre>

У ARM 32 збірці мови аргументи функцій передають у r0-r3, а якщо потрібно більше аргументів, вони розміщуються на стелі. У нашому випадку r0 містить наш модифікатор формату.

x/s $r0 0x10007070:    "%.16f\n"

У r1 бачимо значення, яке вказує на стелю.

x/w $r1 0x0: 0x20041f00

p/x *0x20041f00 0xa </pre>

Це ще одне місце, яке потрапляє в printf обгортка, щоб належним чином друкувати рядок в STDOUT. У нашому наступному урокі ми зможемо статично хакнути.

results matching ""

    No results matching ""