[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' -
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 (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.
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
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.
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 ;
int printf(const char *format)
| 0x0804840c c70424418504. mov dword [esp],
str.Password: ; [0x8048541:4]=0x73736150 ; "Password: "
| 0x08048413 e804ffffff call sym.imp.printf ;
int printf(const char *format)
| 0x08048418 8d45fc lea eax, [var_4h]
| 0x0804841b 89442404 mov dword [var_sp_4h], eax
| 0x0804841f c704244c8504. mov dword [esp], 0x804854c ;
[0x804854c:4]=0x49006425
| 0x08048426 e8e1feffff call sym.imp.scanf ;
int scanf(const char *format)
| 0x0804842b 817dfc9a1400. cmp dword [var_4h], 0x149a
| ,=< 0x08048432 740e je 0x8048442
| | 0x08048434 c704244f8504. mov dword [esp],
str.Invalid_Password ; [0x804854f:4]=0x61766e49 ; "Invalid Password!\n"
| | 0x0804843b e8dcfeffff call sym.imp.printf ;
int printf(const char *format)
| ,==< 0x08048440 eb0c jmp 0x804844e
| |`-> 0x08048442 c70424628504. mov dword [esp],