Part 4 - Hacking Hello World

In the last lesson we reviewed how to properly debug our very simple binary in Radare2. Today we are going to hack that static .elf binary and convert it to the .uf2 format and flash to our Pico and see the magic happen.

Let's review our very simple program once more.

#include <stdio.h>
#include "pico/stdlib.h"

int main() 
{    
  stdio_init_all();

  while(1) 
  {
    printf("Hello world!\n");

    sleep_ms(1000);
  }

  return 0;
}

Let's load up our binary.

radare2 -w arm -b 16 0x02_hello_world.elf

Let's auto analyze.

aaaa

Let's seek to main.

s main

Let's use Visual mode and press p twice to get our our favorite debugger view.

V

Let's review the simple ARM32 Assembly.

I would hack this binary in two ways. As we discussed in the last lesson we see the contents inside the memory location 0x00000338 holding the value of our string. Let's press the colon : and press enter.

:> psz @ [0x00000338]
Hello world!

Let's review our strings. I want you to pay attention to the, "Hello world!" as you will see two addresses. The one on the left is the physical address and the one directly to the right is the virtual address. We will be concerned with the virtual address. To better understand let's do the following.

:> iz~ | less

As you can see our string is at the top.

[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)

You can see the value of 0x00004cf8 holds our string to prove it we can do the following.

:> psz @ 0x00004cf8
Hello world!

Let's hack this.

:> w Hacked World! @ [0x00000338]

Let's now verify the value is changed.

:> psz @ 0x00004cf8
Hacked World!

The other thing I would like to hack is the sleep_ms which is currently set at 1000. Remember it is showing 250 decimal or 0xfa hex and we logical shift left twice as we discuss in the last lesson. The first logical shift left will multiply by 2 bringing us to 500 and the 2nd logical shift left will multiply by 2 brining us to 1000.

lsls r0, r0, 2 

Let's hack this by changing the 2 to a 1. This will make the delay 500 ms or a half a second.

:> wa lsls r0, r0, 1 @ 0x00000330
Written 2 byte(s) (lsls r0, r0, 1) = wx 4000

Let's verify.

:> pd 1 @ 0x00000330
│           0x00000330      4000           lsls r0, r0, 1

We can clearly see it changed.

All we have to do now is exit and convert our .elf to .uf2!

./elf2uf2/elf2uf2 0x02_hello_world.elf 0x02_hello_world.uf2

Plug in the Pico and make sure you hold down BOOTSEL or use the setup I provided in the last lesson.

cp 0x02_hello_world.uf2 /Volumes/RPI-RP2

Let's screen it!

screen /dev/tty.usbmodem0000000000001

AHH yea!

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!

Every half a second!

Next lesson we will discuss variables.

results matching ""

    No results matching ""