Частина 4 - Хакінг Hello World
У останньому урокі ми розглянули, як належно відлагодити наші дуже прості бінарні файли в Radare2. Сьогодні ми будемо хакнути цей статичний .elf бінарний файл і перетворити його на .uf2 формат і підключити його до нашого Pico і побачити чарівність.
Давайте знову переглянемо наші дуже прості програми.
#include <stdio.h> #include "pico/stdlib.h" int main() { stdio_init_all(); while(1) { printf("Hello world!\n"); sleep_ms(1000); } return 0; }
Давайте завантажимо наші бінарні файли.
radare2 -w arm -b 16 0x02_hello_world.elf
Давайте зробимо автоматичну аналітику.
aaaa
Давайте підійдемо до головної частини програми.
s main
Давайте використаємо візуальний режим і натисніть p двічі, щоб отримати нашу улюблену оглядову панель.
V
Давайте переглянемо простий збірник ARM32.
Я б хакнув цей бінарний файл двома способами. Як ми обговорили в останньому урокі, ми бачимо вміст всередині пам'яті 0x00000338 який містить значення нашої стрічки. Давайте натисніть колонку: і натисніть Enter.
:> psz @ [0x00000338] Hello world!
Давайте переглянемо strings. Я хочу, щоб ви звернули увагу на "Hello world!", оскільки ви побачите дві адреси. Адреса на лівому боці - фізична адреса, а адреса прямо справа - віртуальна адреса. Ми будуть займатися віртуальною адресою. Для кращого розуміння давайте зробимо наступне.
:> iz~ | less
Як ви бачите, наша стрічка знаходиться вгорі.
[Strings] nth paddr vaddr len size section type string ――――――――――――――――――――――――――――――――――――――――――――――――――――――――― 0 0x00014cf8 0x00004cf8 12 13 .rodata ascii Hello world! 1 0x00014d08 0x00004d08 26 27 .rodata ascii No spinlocks are available 2 0x00014d24 0x00004d24 33 34 .rodata ascii Hardware alarm %d already claimed 3 0x00014d48 0x00004d48 15 16 .rodata ascii \n*** PANIC ***\n 4 0x00014d5c 0x00004d5c 11 12 .rodata ascii Hard assert 5 0x00014d68 0x00004d68 7 8 .rodata ascii Release 6 0x00014d70 0x00004d70 5 6 .rodata ascii 1.0.0 7 0x00014d78 0x00004d78 4 5 .rodata ascii pico 8 0x00014d80 0x00004d80 16 17 .rodata ascii 0x02_hello_world 9 0x00014d94 0x00004d94 11 12 .rodata ascii Mar 21 2021 10 0x00014db2 0x00004db2 4 5 .rodata ascii uBhM 11 0x00014dbc 0x00004dbc 10 11 .rodata ascii UART stdin 12 0x00014dc8 0x00004dc8 11 12 .rodata ascii UART stdout 13 0x00014dd4 0x00004dd4 19 20 .rodata ascii UART stdin / stdout 14 0x00014dfc 0x00004dfc 18 19 .rodata ascii USB stdin / stdout 15 0x00014e1c 0x00004e1c 12 13 .rodata ascii Raspberry Pi 16 0x00014e2c 0x00004e2c 4 5 .rodata ascii Pico 17 0x00014e34 0x00004e34 12 13 .rodata ascii 000000000000 18 0x00014e44 0x00004e44 9 10 .rodata ascii Board CDC 19 0x00014ec4 0x00004ec4 19 20 .rodata ascii Unhandled IRQ 0x%x\n 20 0x00014ed8 0x00004ed8 39 40 .rodata ascii Isochronous wMaxPacketSize %d too large 21 0x00014f00 0x00004f00 30 31 .rodata ascii ep %d %s was already available 22 0x00014f20 0x00004f20 40 41 .rodata ascii Can't continue xfer on inactive ep %d %s 23 0x00014f4c 0x00004f4c 35 36 .rodata ascii Transferred more data than expected 0 0x00020135 0x10000135 5 6 .data ascii V\n`\eh 1 0x0002018b 0x1000018b 5 6 .data ascii &CF\eh 2 0x000201a0 0x100001a0 4 5 .data ascii CF\ey 3 0x000201a8 0x100001a8 4 5 .data ascii CF\eh 4 0x000201d0 0x100001d0 4 5 .data ascii \thAq 5 0x0002028d 0x1000028d 5 6 .data ascii GpF\t8 6 0x00020805 0x10000805 5 11 .data utf16le \a \b \b 7 0x00020905 0x10000905 5 11 .data utf16le \b \t \t 8 0x00020a05 0x10000a05 5 11 .data utf16le \t \n \n 9 0x00020b05 0x10000b05 5 11 .data utf16le \n \v \v (END)
Ви можете побачити значення 0x00004cf8 яке містить нашу стрічку, щоб підтвердити це ми можемо зробити наступне.
:> psz @ 0x00004cf8 Hello world!
Давайте хакнемо це.
:> w Hacked World! @ [0x00000338]
Давайте тепер перевіримо, чи змінилося значення.
:> psz @ 0x00004cf8 Hacked World!
Іншою річчю, яку я хотів би хакнути, є sleep_ms яка зараз встановлена на 1000. Пам'ятайте, вона показує 250 десяткове або 0xfa шістнадцяткове і ми логічно зміщуємо ліворуч двічі, як ми обговорили в останньому урокі. Перший логічний зміщення ліворуч буде збільшувати на 2, привівши нас до 500, а другий логічний зміщення ліворуч буде збільшувати на 2, привівши нас до 1000.
lsls r0, r0, 2
Давайте хакнемо це, змінивши 2 на 1. Це зробить затримку 500 мс або півсекунди.
:> wa lsls r0, r0, 1 @ 0x00000330 Written 2 byte(s) (lsls r0, r0, 1) = wx 4000
Давайте перевіримо.
:> pd 1 @ 0x00000330 │ 0x00000330 4000 lsls r0, r0, 1
Ми можемо побачити, що воно змінилося.
Тепер у нас нічого не залишається, як вийти і перетворити наші .elf на .uf2!
./elf2uf2/elf2uf2 0x02_hello_world.elf 0x02_hello_world.uf2
Підключіть Pico і переконайтеся, що ви натискаєте BOOTSEL або використовуєте налаштування, які я надав у останньому урокі.
cp 0x02_hello_world.uf2 /Volumes/RPI-RP2
Давайте побачимо!
screen /dev/tty.usbmodem0000000000001
АХА!
Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World! Hacked World!
Кожну півсекунду!
У наступному урокі ми обговоримо змінні.