It is common to have an issues when you write a plugin, especially if you do this for the first time. This is why debugging them is very important. The first step for debugging is to set an environment variable when running radare2 instance:
R_DEBUG=yes r2 /bin/ls
Loading /usr/local/lib/radare2/2.2.0-git//bin_xtr_dyldcache.so
Cannot find symbol 'radare_plugin' in library '/usr/local/lib/radare2/2.2.0-git//bin_xtr_dyldcache.so'
Cannot open /usr/local/lib/radare2/2.2.0-git//2.2.0-git
Loading /home/user/.config/radare2/plugins/asm_mips_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Loading /home/user/.config/radare2/plugins/asm_sparc_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Cannot open /home/user/.config/radare2/plugins/pimp
Cannot open /home/user/.config/radare2/plugins/yara
Loading /home/user/.config/radare2/plugins/asm_arm_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Loading /home/user/.config/radare2/plugins/core_yara.so
Module version mismatch /home/user/.config/radare2/plugins/core_yara.so (2.1.0) vs (2.2.0-git)
Loading /home/user/.config/radare2/plugins/asm_ppc_ks.so
PLUGIN OK 0x55b205ea6070 fcn 0x7f298de08762
Loading /home/user/.config/radare2/plugins/lang_python3.so
PLUGIN OK 0x55b205ea5ed0 fcn 0x7f298de08692
Loading /usr/local/lib/radare2/2.2.0-git/bin_xtr_dyldcache.so
Cannot find symbol 'radare_plugin' in library '/usr/local/lib/radare2/2.2.0-git/bin_xtr_dyldcache.so'
Cannot open /usr/local/lib/radare2/2.2.0-git/2.2.0-git
Cannot open directory '/usr/local/lib/radare2-extras/2.2.0-git'
Cannot open directory '/usr/local/lib/radare2-bindings/2.2.0-git'
USER CONFIG loaded from /home/user/.config/radare2/radare2rc
-- In visual mode press 'c' to toggle the cursor mode. Use tab to navigate
[0x00005520]>
Testing the plugin
This plugin is used by rasm2 and r2. You can verify that the plugin is properly loaded with this command:
$ rasm2 -L | grep mycpu
_d mycpu My CPU disassembler (LGPL3)
Let's open an empty file using the 'mycpu' arch and write some random code there.
$ r2 -
-- I endians swap
[0x00000000]> e asm.arch=mycpu
[0x00000000]> woR
[0x00000000]> pd 10
0x00000000 888e mov r8, 14
0x00000002 b2a5 ifnot r10, r5
0x00000004 3f67 ret
0x00000006 7ef6 bl r15, r6
0x00000008 2701 xor r0, 1
0x0000000a 9826 mov r2, 6
0x0000000c 478d xor r8, 13
0x0000000e 6b6b store r6, 11
0x00000010 1382 add r8, r2
0x00000012 7f15 ret
Yay! it works.. and the mandatory oneliner too!
r2 -nqamycpu -cwoR -cpd' 10' -
Creating an r2pm package of the plugin
As you remember radare2 has its own packaging manager and we can easily add newly written plugin for everyone to access.
All packages are located in radare2-pm repository, and have very simple text format.
R2PM_BEGIN
R2PM_GIT "https://github.com/user/mycpu"
R2PM_DESC "[r2-arch] MYCPU disassembler and analyzer plugins"
R2PM_INSTALL() {
${MAKE} clean
${MAKE} all || exit 1
${MAKE} install R2PM_PLUGDIR="${R2PM_PLUGDIR}"
}
R2PM_UNINSTALL() {
rm -f "${R2PM_PLUGDIR}/asm_mycpu."*
rm -f "${R2PM_PLUGDIR}/anal_mycpu."*
}
R2PM_END
Then add it in the /db directory of radare2-pm repository and send a pull request to the mainline.
Crackmes
Crackmes (from "crack me" challenge) are the training ground for reverse engineering people. This section will go over tutorials on how to defeat various crackmes using r2.
IOLI CrackMes
The IOLI crackme is a good starting point for learning r2. This is a set of tutorials based on the tutorial at dustri
The IOLI crackmes are available at a locally hosted mirror
IOLI 0x00
This is the first IOLI crackme, and the easiest one.
$ ./crackme0x00
IOLI Crackme Level 0x00
Password: 1234
Invalid Password!
The first thing to check is if the password is just plaintext inside the file. In this case, we don't need to do any disassembly, and we can just use rabin2 with the -z flag to search for strings in the binary.
$ rabin2 -z ./crackme0x00
[Strings]
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000568 0x08048568 24 25 .rodata ascii IOLI Crackme Level 0x00\n
1 0x00000581 0x08048581 10 11 .rodata ascii Password:
2 0x0000058f 0x0804858f 6 7 .rodata ascii 250382
3 0x00000596 0x08048596 18 19 .rodata ascii Invalid Password!\n
4 0x000005a9 0x080485a9 15 16 .rodata ascii Password OK :)\n
So we know what the following section is, this section is the header shown when the application is run.
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000568 0x08048568 24 25 .rodata ascii IOLI Crackme Level 0x00\n
Here we have the prompt for the password.
1 0x00000581 0x08048581 10 11 .rodata ascii Password:
This is the error on entering an invalid password.
3 0x00000596 0x08048596 18 19 .rodata ascii Invalid Password!\n
This is the message on the password being accepted.
4 0x000005a9 0x080485a9 15 16 .rodata ascii Password OK :)\n
What is this? It's a string, but we haven't seen it in running the application yet.
2 0x0000058f 0x0804858f 6 7 .rodata ascii 250382
Let's give this a shot.
$ ./crackme0x00
IOLI Crackme Level 0x00
Password: 250382
Password OK :)
So we now know that 250382 is the password, and have completed this crackme.
IOLI 0x01
This is the second IOLI crackme.
$ ./crackme0x01
IOLI Crackme Level 0x01
Password: test
Invalid Password!
Let's check for strings with rabin2.
$ rabin2 -z ./crackme0x01
[Strings]
nth paddr vaddr len size section type string
―――――――――――――――――――――――――――――――――――――――――――――――――――――――
0 0x00000528 0x08048528 24 25 .rodata ascii IOLI Crackme Level 0x01\n
1 0x00000541 0x08048541 10 11 .rodata ascii Password:
2 0x0000054f 0x0804854f 18 19 .rodata ascii Invalid Password!\n
3 0x00000562 0x08048562 15 16 .rodata ascii Password OK :)\n
This isn't going to be as easy as 0x00. Let's try disassembly with r2.
$
r2 ./crackme0x01
-- Use `zoom.byte=printable` in zoom mode ('z' in Visual mode) to find
strings
[0x08048330]> aa
[0x08048330]> pdf@main
; DATA XREF from entry0 @ 0x8048347
/ 113: int main (int argc, char **argv, char **envp);
| ; var int32_t var_4h @ ebp-0x4
| ; var int32_t var_sp_4h @ esp+0x4
| 0x080483e4 55 push ebp
| 0x080483e5 89e5 mov ebp, esp
| 0x080483e7 83ec18 sub esp, 0x18
| 0x080483ea 83e4f0 and esp, 0xfffffff0
| 0x080483ed b800000000 mov eax, 0
| 0x080483f2 83c00f add eax, 0xf ;
15
| 0x080483f5 83c00f add eax, 0xf ;
15
| 0x080483f8 c1e804 shr eax, 4
| 0x080483fb c1e004 shl eax, 4
| 0x080483fe 29c4 sub esp, eax
| 0x08048400 c70424288504. mov dword [esp],
str.IOLI_Crackme_Level_0x01 ; [0x8048528:4]=0x494c4f49 ; "IOLI Crackme
Level 0x01\n"
| 0x08048407 e810ffffff call sym.imp.printf ;