Note that because radare2 uses Capstone to disassemble ARM code, there are issues with the disassembly. arm-none-eabi-objdump -d compiledbinary.elf
actually does a better job in some cases. For example, msr
isn't decompiled correctly...
First, you have to either strip the default ELF binaries the default Makefiles build when you run make
OR you need to just compile .bin
files using something like:
make binaryname.bin
Once you have a .bin
file, you can then load it into radare2 and disassemble it. Keep in mind you'll need to use the following flags to configure r2 to look for ARM, 16bit, and Cortex specific opcodes (-a arm -b 16 -e asm.cpu=cortex
):
r2 -a arm -b 16 -e asm.cpu=cortex miniblink.bin
> aaa (to analyze the binary)
> afl (to show the functions it's found)
> pdf @fcn.000001f8 (to show main())
> pdf @0x00000230 (to show gpio_toggle())
Then, enter Visual mode if you'd like:
> VV
And walk through the graph using the n
and N
keys. Use p
and P
to change the graph view mode!
Left image here is Radare, Right is GDB:
This time, I'm trying to disassemble the Bitcrazy Crazyflie 1.0 firmware. The file is called cf1.elf
.
First reason I'm trying to disassemble this is so I can run the code and have a breakpoint trigger in r2
when the code hites somewhere in this function: crtpCommanderRpytDecodeSetpoint
in this file: src/modules/src/crtp_commander_rpyt.c
on line 175
Second it to do the same, when any change happens to variable values
inside the function crtpCommanderRpytDecodeSetpoint
in the file src/modules/src/crtp_commander_rpyt.c
.
This is the area of the code where I can see the setpoint variables being sent over the radio link.
Since I last touched this stuff, a GSoC happened in the r2
world. I'm not sure the status of that work, but if nothing else, it doesn't seem to support target extended-remote /dev/ttyACM0
which I was partially hoping someone would build.
Alas, I'll probably have to build it myself.
r2 -a arm -b 16 -e asm.cpu=cortex cf1.elf
Warning: Cannot initialize dynamic strings (oops. Not sure why this is happening...)
> aaa
> e asm.pseudo=true (to help n0bs like me read ARM ASM)
> afl (to show the functions it's found)
> pdf @main (to show main())
> pdf @sym.crtpCommanderRpytDecodeSetpoint (to show crtpCommanderRpytDecodeSetpoint())
And that matches these similar set of gdb commands (Except that r2
is way easier to read...):
arm-none-eabi-gdb cf1.elf
(gdb) disassemble main
(gdb) disassemble crtpCommanderRpytDecodeSetpoint
Well, because r2
has issues just connecting right to /dev/ttyACM0
where the Black Magic Probe is sitting with it's own GDB server AND since we actually want to see the packets being sent out by r2
and received by the BMP, we link everything up through some command line hackery:
Note: This assumes you have the Black Magic probe on /dev/ttyACM0
(gdb extended-remote target) and /dev/ttyACM1
(UART)
stty -F /dev/ttyACM0 raw -onlcr -iexten -echo -echoe -echok -echoctl -echoke
nc -vkl -p 2000 > /dev/ttyACM0 < /dev/ttyACM0
Remember: when youre done with this hackery, run this to get a sane terminal back on /dev/ttyACM0
stty sane < /dev/ttyACM0
r2 -a arm -b 16 -e asm.cpu=cortex -d gdb://127.0.0.1:2000/1 cf1.elf
>
Once that's
Also, if you're landing here and have not yet had the enjoyment of consuming the amazing work Azeria/@azeria-labs has done on ARM assembly, it's entirely worth a read!
https://azeria-labs.com/writing-arm-assembly-part-1/