Binary Reverse Engineering with Reversing Elf
Description
Reverse engineering is the process of analyzing a product, system, or software to understand its design, architecture, functionality, and behavior, often with the goal of replicating, modifying, or improving it. In the context of software, reverse engineering specifically refers to the analysis of compiled code (binaries) to uncover its original source code or to understand its inner workings.The main goal is to understand the program’s logic, identify vulnerabilities, extract useful information, or modify its behavior.Common techniques include disassembly, decompilation, debugging, and dynamic analysis.
We have a good amount of Open source tools for reverse engineering. Common ones are IDA Pro, Radare2, Immunity Debugger, Ghidra and so on..
Since this is a basic intro to reverse engineering concept, I am focussing on common command line tools and Radare2
Environment and Tools Used
Kali Linux
Reversing-ELF THM
Radare2
Note - Tools would be preinstalled in Kali
Walkthrough
This free THM box is so good to practice or to get an intro to the reverse engineering. Let’s start with each binaries.
Crackme1
Let’s run it in terminal and we would get the first flag. If you are getting permission error use chmod to add execute permission.
chmod +x crackme1
./crackme1
Crackme2
On running the binary in terminal, we would get an usage message. Here we want to give a password as an argument. Let’s see whether the binary is hiding something using strings. We use Strings to extract printable strings from binary files.
strings crackme2
We can see the password and a subsequent string saying Access Granted!. Let’s pass it as an argument on the binary execution.
./crackme2 password
We would get the second flag
Crackme3
Simply executing, we are getting the same argument error like we saw with Crackme2. Let’s use strings again and see whether the password is hiding. !crackme3-1 The password is base-64 encoded. Let’s use Cyberchef for decoding. !crackme3-2 Pass the password as an argument on executing the binary and we would get the flag.
./crackme3 password
Crackme4
On executing, we are getting a new message.This time the string is hidden and we used strcmp. Strcmp is a string fuction used to compare two strings. So if we could disassemble the binary to catch the value that the application use for comparing, we would get the string.
Running strings command, we are not seeing any interesting thing. Let’s use Radare2. Basic usage and command arguments of radare2
r2 -d binaryname - Opens in Debug mode
AAA - Starts analyzing
afl - List all functions
pdf @function-name - Selecting a function
db address - Setting a breakpoint
ood - Restarting programme
dc - Continue programme execution
px @address - Displays value holding in the address
r2 -d crackme4
[0x7faedf88e360]> AAA
|ERROR| Invalid command 'AAA' (0x41)
[0x7faedf88e360]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Finding and parsing C++ vtables (avrr)
[x] Skipping type matching analysis in debugger mode (aaft)
[x] Propagate noreturn information (aanr)
[x] Use -AA or aaaa to perform additional experimental analysis.
0x7faedf88e360]> afl
0x00400540 1 42 entry0
0x00400510 1 6 sym.imp.__libc_start_main
0x00400570 4 41 sym.deregister_tm_clones
0x004005a0 4 57 sym.register_tm_clones
0x004005e0 3 28 sym.__do_global_dtors_aux
0x00400600 4 45 -> 42 entry.init0
0x004007d0 1 2 sym.__libc_csu_fini
0x0040062d 4 77 sym.get_pwd
0x004007d4 1 9 sym._fini
0x0040067a 6 156 sym.compare_pwd
0x00400760 4 101 sym.__libc_csu_init
0x00400716 4 74 main
0x004004b0 3 26 sym._init
0x00400530 1 6 loc.imp.__gmon_start__
0x004004e0 1 6 sym.imp.puts
0x004004f0 1 6 sym.imp.__stack_chk_fail
0x00400500 1 6 sym.imp.printf
0x00400520 1 6 sym.imp.strcmp
[0x7faedf88e360]> pdf @main
; DATA XREF from entry0 @ 0x40055d
┌ 74: int main (int argc, char **argv);
│ ; var int64_t var_10h @ rbp-0x10
│ ; var int64_t var_4h @ rbp-0x4
│ ; arg int argc @ rdi
│ ; arg char **argv @ rsi
│ 0x00400716 55 push rbp
│ 0x00400717 4889e5 mov rbp, rsp
│ 0x0040071a 4883ec10 sub rsp, 0x10
│ 0x0040071e 897dfc mov dword [var_4h], edi ; argc
│ 0x00400721 488975f0 mov qword [var_10h], rsi ; argv
│ 0x00400725 837dfc02 cmp dword [var_4h], 2
│ ┌─< 0x00400729 741b je 0x400746
│ │ 0x0040072b 488b45f0 mov rax, qword [var_10h]
│ │ 0x0040072f 488b00 mov rax, qword [rax]
│ │ 0x00400732 4889c6 mov rsi, rax
│ │ 0x00400735 bf10084000 mov edi, str.Usage_:__s_password_nThis_time_the_string_is_hidden_and_we_used_strcmp_n ; 0x400810 ; "Usage : %s password\nThis time the string is hidden and we used strcmp\n"
│ │ 0x0040073a b800000000 mov eax, 0
│ │ 0x0040073f e8bcfdffff call sym.imp.printf ; int printf(const char *format)
│ ┌──< 0x00400744 eb13 jmp 0x400759
│ │└─> 0x00400746 488b45f0 mov rax, qword [var_10h]
│ │ 0x0040074a 4883c008 add rax, 8
│ │ 0x0040074e 488b00 mov rax, qword [rax]
│ │ 0x00400751 4889c7 mov rdi, rax
│ │ 0x00400754 e821ffffff call sym.compare_pwd
│ │ ; CODE XREF from main @ 0x400744
│ └──> 0x00400759 b800000000 mov eax, 0
│ 0x0040075e c9 leave
└ 0x0040075f c3 ret
[0x7faedf88e360]> pdf @sym.compare_pwd
; CALL XREF from main @ 0x400754
┌ 156: sym.compare_pwd (int64_t arg1);
│ ; var int64_t var_28h @ rbp-0x28
│ ; var int64_t var_20h @ rbp-0x20
│ ; var int64_t var_18h @ rbp-0x18
│ ; var int64_t var_10h @ rbp-0x10
│ ; var int64_t var_eh @ rbp-0xe
│ ; var int64_t var_8h @ rbp-0x8
│ ; arg int64_t arg1 @ rdi
│ 0x0040067a 55 push rbp
│ 0x0040067b 4889e5 mov rbp, rsp
│ 0x0040067e 4883ec30 sub rsp, 0x30
│ 0x00400682 48897dd8 mov qword [var_28h], rdi ; arg1
│ 0x00400686 64488b042528. mov rax, qword fs:[0x28]
│ 0x0040068f 488945f8 mov qword [var_8h], rax
│ 0x00400693 31c0 xor eax, eax
│ 0x00400695 48b8495d7b49. movabs rax, 0x7b175614497b5d49 ; 'I]{I\x14V\x17{'
│ 0x0040069f 488945e0 mov qword [var_20h], rax
│ 0x004006a3 48b857414751. movabs rax, 0x547b175651474157 ; 'WAGQV\x17{T'
│ 0x004006ad 488945e8 mov qword [var_18h], rax
│ 0x004006b1 66c745f05340 mov word [var_10h], 0x4053 ; 'S@'
│ 0x004006b7 c645f200 mov byte [var_eh], 0
│ 0x004006bb 488d45e0 lea rax, [var_20h]
│ 0x004006bf 4889c7 mov rdi, rax
│ 0x004006c2 e866ffffff call sym.get_pwd
│ 0x004006c7 488b55d8 mov rdx, qword [var_28h]
│ 0x004006cb 488d45e0 lea rax, [var_20h]
│ 0x004006cf 4889d6 mov rsi, rdx
│ 0x004006d2 4889c7 mov rdi, rax
│ 0x004006d5 e846feffff call sym.imp.strcmp ; int strcmp(const char *s1, const char *s2)
│ 0x004006da 85c0 test eax, eax
│ ┌─< 0x004006dc 750c jne 0x4006ea
│ │ 0x004006de bfe8074000 mov edi, str.password_OK ; 0x4007e8 ; "password OK"
│ │ 0x004006e3 e8f8fdffff call sym.imp.puts ; int puts(const char *s)
│ ┌──< 0x004006e8 eb16 jmp 0x400700
│ │└─> 0x004006ea 488b45d8 mov rax, qword [var_28h]
│ │ 0x004006ee 4889c6 mov rsi, rax
│ │ 0x004006f1 bff4074000 mov edi, str.password___s__not_OK_n ; 0x4007f4 ; "password \"%s\" not OK\n"
│ │ 0x004006f6 b800000000 mov eax, 0
│ │ 0x004006fb e800feffff call sym.imp.printf ; int printf(const char *format)
│ │ ; CODE XREF from sym.compare_pwd @ 0x4006e8
│ └──> 0x00400700 488b45f8 mov rax, qword [var_8h]
│ 0x00400704 644833042528. xor rax, qword fs:[0x28]
│ ┌─< 0x0040070d 7405 je 0x400714
│ │ 0x0040070f e8dcfdffff call sym.imp.__stack_chk_fail
│ └─> 0x00400714 c9 leave
└ 0x00400715 c3 ret
[0x7faedf88e360]> db 0x004006cf
[0x7faac35da360]> dc
hit breakpoint at: 0x4006cf
[0x004006cf]> px@ rax
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7ffde534d1c0 6d79 5f6d 3072 335f 7365 6375 7233 5f70 ****************
0x7ffde534d1d0 7764 0000 0000 0000 0022 ae61 0915 3e15 **.......".a..>.
0x7ffde534d1e0 00d2 34e5 fd7f 0000 5907 4000 0000 0000 ..4.....Y.@.....
0x7ffde534d1f0 18d3 34e5 fd7f 0000 0000 0000 0200 0000 ..4.............
0x7ffde534d200 0200 0000 0000 0000 cac6 3ec3 aa7f 0000 ..........>.....
0x7ffde534d210 0000 0000 0000 0000 1607 4000 0000 0000 ..........@.....
0x7ffde534d220 0000 0000 0200 0000 18d3 34e5 fd7f 0000 ..........4.....
0x7ffde534d230 18d3 34e5 fd7f 0000 fba9 6bf9 8ec2 e69b ..4.......k.....
0x7ffde534d240 0000 0000 0000 0000 30d3 34e5 fd7f 0000 ........0.4.....
0x7ffde534d250 0000 0000 0000 0000 0020 5fc3 aa7f 0000 ......... _.....
0x7ffde534d260 fba9 4f5d e708 1d64 fba9 6b74 f344 b364 ..O]...d..kt.D.d
0x7ffde534d270 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7ffde534d280 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7ffde534d290 18d3 34e5 fd7f 0000 0022 ae61 0915 3e15 ..4......".a..>.
0x7ffde534d2a0 0e00 0000 0000 0000 85c7 3ec3 aa7f 0000 ..........>.....
0x7ffde534d2b0 1607 4000 0000 0000 0000 0000 aa7f 0000 ..@.............
We got the password in rax. Pass it to the binary to get the flag.
Crackme5
Let’s crack Crackme5. Executing the binary is saying us to dig deeper. So let’s dig deeper.
Strings command is not showing anything of the interest. We can see a text saying “Good game”, so we would get this output once complete.
Let’s use radare2
We can see strcmp when disassembling.
└─$ r2 -d crackme5
[0x7ff071a0b360]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Finding and parsing C++ vtables (avrr)
[x] Skipping type matching analysis in debugger mode (aaft)
[x] Propagate noreturn information (aanr)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x7ff071a0b360]> afl
0x004005e0 1 42 entry0
0x004005a0 1 6 sym.imp.__libc_start_main
0x00400610 4 50 -> 41 sym.deregister_tm_clones
0x00400650 4 58 -> 55 sym.register_tm_clones
0x00400690 3 28 sym.__do_global_dtors_aux
0x004006b0 4 38 -> 35 entry.init0
0x00400940 1 2 sym.__libc_csu_fini
0x00400944 1 9 sym._fini
0x004006d6 7 157 sym.strcmp_
0x004008d0 4 101 sym.__libc_csu_init
0x00400773 6 251 main
0x0040086e 4 93 sym.check
0x00400528 3 26 sym._init
0x004005d0 1 6 sym..plt.got
0x00400560 1 6 sym.imp.strncmp
0x00400570 1 6 sym.imp.puts
0x00400580 1 6 sym.imp.strlen
0x00400590 1 6 sym.imp.__stack_chk_fail
0x004005b0 1 6 sym.imp.atoi
0x004005c0 1 6 sym.imp.__isoc99_scanf
[0x7ff071a0b360]> pdf @main
; DATA XREF from entry0 @ 0x4005fd
; CALL XREF from sym.check @ 0x4008c3
┌ 251: int main (int argc, char **argv);
│ ; var int64_t var_70h @ rbp-0x70
│ ; var int64_t var_64h @ rbp-0x64
│ ; var int64_t var_54h @ rbp-0x54
│ ; var int64_t var_50h @ rbp-0x50
│ ; var int64_t var_30h @ rbp-0x30
│ ; var int64_t var_2fh @ rbp-0x2f
│ ; var int64_t var_2eh @ rbp-0x2e
│ ; var int64_t var_2dh @ rbp-0x2d
│ ; var int64_t var_2ch @ rbp-0x2c
│ ; var int64_t var_2bh @ rbp-0x2b
│ ; var int64_t var_2ah @ rbp-0x2a
│ ; var int64_t var_29h @ rbp-0x29
│ ; var int64_t var_28h @ rbp-0x28
│ ; var int64_t var_27h @ rbp-0x27
│ ; var int64_t var_26h @ rbp-0x26
│ ; var int64_t var_25h @ rbp-0x25
│ ; var int64_t var_24h @ rbp-0x24
│ ; var int64_t var_23h @ rbp-0x23
│ ; var int64_t var_22h @ rbp-0x22
│ ; var int64_t var_21h @ rbp-0x21
│ ; var int64_t var_20h @ rbp-0x20
│ ; var int64_t var_1fh @ rbp-0x1f
│ ; var int64_t var_1eh @ rbp-0x1e
│ ; var int64_t var_1dh @ rbp-0x1d
│ ; var int64_t var_1ch @ rbp-0x1c
│ ; var int64_t var_1bh @ rbp-0x1b
│ ; var int64_t var_1ah @ rbp-0x1a
│ ; var int64_t var_19h @ rbp-0x19
│ ; var int64_t var_18h @ rbp-0x18
│ ; var int64_t var_17h @ rbp-0x17
│ ; var int64_t var_16h @ rbp-0x16
│ ; var int64_t var_15h @ rbp-0x15
│ ; var int64_t var_8h @ rbp-0x8
│ ; arg int argc @ rdi
│ ; arg char **argv @ rsi
│ 0x00400773 55 push rbp
│ 0x00400774 4889e5 mov rbp, rsp
│ 0x00400777 4883ec70 sub rsp, 0x70
│ 0x0040077b 897d9c mov dword [var_64h], edi ; argc
│ 0x0040077e 48897590 mov qword [var_70h], rsi ; argv
│ 0x00400782 64488b042528. mov rax, qword fs:[0x28]
│ 0x0040078b 488945f8 mov qword [var_8h], rax
│ 0x0040078f 31c0 xor eax, eax
│ 0x00400791 c645d04f mov byte [var_30h], 0x4f ; 'O' ; 79
│ 0x00400795 c645d166 mov byte [var_2fh], 0x66 ; 'f' ; 102
│ 0x00400799 c645d264 mov byte [var_2eh], 0x64 ; 'd' ; 100
│ 0x0040079d c645d36c mov byte [var_2dh], 0x6c ; 'l' ; 108
│ 0x004007a1 c645d444 mov byte [var_2ch], 0x44 ; 'D' ; 68
│ 0x004007a5 c645d553 mov byte [var_2bh], 0x53 ; 'S' ; 83
│ 0x004007a9 c645d641 mov byte [var_2ah], 0x41 ; 'A' ; 65
│ 0x004007ad c645d77c mov byte [var_29h], 0x7c ; '|' ; 124
│ 0x004007b1 c645d833 mov byte [var_28h], 0x33 ; '3' ; 51
│ 0x004007b5 c645d974 mov byte [var_27h], 0x74 ; 't' ; 116
│ 0x004007b9 c645da58 mov byte [var_26h], 0x58 ; 'X' ; 88
│ 0x004007bd c645db62 mov byte [var_25h], 0x62 ; 'b' ; 98
│ 0x004007c1 c645dc33 mov byte [var_24h], 0x33 ; '3' ; 51
│ 0x004007c5 c645dd32 mov byte [var_23h], 0x32 ; '2' ; 50
│ 0x004007c9 c645de7e mov byte [var_22h], 0x7e ; '~' ; 126
│ 0x004007cd c645df58 mov byte [var_21h], 0x58 ; 'X' ; 88
│ 0x004007d1 c645e033 mov byte [var_20h], 0x33 ; '3' ; 51
│ 0x004007d5 c645e174 mov byte [var_1fh], 0x74 ; 't' ; 116
│ 0x004007d9 c645e258 mov byte [var_1eh], 0x58 ; 'X' ; 88
│ 0x004007dd c645e340 mov byte [var_1dh], 0x40 ; elf_phdr
│ 0x004007e1 c645e473 mov byte [var_1ch], 0x73 ; 's' ; 115
│ 0x004007e5 c645e558 mov byte [var_1bh], 0x58 ; 'X' ; 88
│ 0x004007e9 c645e660 mov byte [var_1ah], 0x60 ; '`' ; 96
│ 0x004007ed c645e734 mov byte [var_19h], 0x34 ; '4' ; 52
│ 0x004007f1 c645e874 mov byte [var_18h], 0x74 ; 't' ; 116
│ 0x004007f5 c645e958 mov byte [var_17h], 0x58 ; 'X' ; 88
│ 0x004007f9 c645ea74 mov byte [var_16h], 0x74 ; 't' ; 116
│ 0x004007fd c645eb7a mov byte [var_15h], 0x7a ; 'z' ; 122
│ 0x00400801 bf54094000 mov edi, str.Enter_your_input: ; 0x400954 ; "Enter your input:"
│ 0x00400806 e865fdffff call sym.imp.puts ; int puts(const char *s)
│ 0x0040080b 488d45b0 lea rax, [var_50h]
│ 0x0040080f 4889c6 mov rsi, rax
│ 0x00400812 bf66094000 mov edi, 0x400966
│ 0x00400817 b800000000 mov eax, 0
│ 0x0040081c e89ffdffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ 0x00400821 488d55d0 lea rdx, [var_30h]
│ 0x00400825 488d45b0 lea rax, [var_50h]
│ 0x00400829 4889d6 mov rsi, rdx
│ 0x0040082c 4889c7 mov rdi, rax
│ 0x0040082f e8a2feffff call sym.strcmp_
│ 0x00400834 8945ac mov dword [var_54h], eax
│ 0x00400837 837dac00 cmp dword [var_54h], 0
│ ┌─< 0x0040083b 750c jne 0x400849
│ │ 0x0040083d bf69094000 mov edi, str.Good_game ; 0x400969 ; "Good game"
│ │ 0x00400842 e829fdffff call sym.imp.puts ; int puts(const char *s)
│ ┌──< 0x00400847 eb0a jmp 0x400853
│ │└─> 0x00400849 bf73094000 mov edi, str.Always_dig_deeper ; 0x400973 ; "Always dig deeper"
│ │ 0x0040084e e81dfdffff call sym.imp.puts ; int puts(const char *s)
│ │ ; CODE XREF from main @ 0x400847
│ └──> 0x00400853 b800000000 mov eax, 0
│ 0x00400858 488b4df8 mov rcx, qword [var_8h]
│ 0x0040085c 6448330c2528. xor rcx, qword fs:[0x28]
│ ┌─< 0x00400865 7405 je 0x40086c
│ │ 0x00400867 e824fdffff call sym.imp.__stack_chk_fail
│ └─> 0x0040086c c9 leave
└ 0x0040086d c3 ret
[0x7ff071a0b360]> db 0x0040082c
[0x7ff071a0b360]> dc
Enter your input:
hellothereworld
hit breakpoint at: 0x40082c
[0x0040082c]> px @rax
- offset - 0 1 2 3 4 5 6 7 8 9 A B C D E F 0123456789ABCDEF
0x7fff20ea3300 6865 6c6c 6f74 6865 7265 776f 726c 6400 hellothereworld.
0x7fff20ea3310 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7fff20ea3320 4f66 646c 4453 417c 3374 5862 3332 7e58 ****************
0x7fff20ea3330 3374 5840 7358 6034 7458 747a 0000 0000 ************....
0x7fff20ea3340 0000 0000 0000 0000 00f9 838c 1ccd 1f9e ................
0x7fff20ea3350 0100 0000 0000 0000 cad6 8171 f07f 0000 ...........q....
0x7fff20ea3360 0000 0000 0000 0000 7307 4000 0000 0000 ........s.@.....
0x7fff20ea3370 0000 0000 0100 0000 6834 ea20 ff7f 0000 ........h4. ....
0x7fff20ea3380 6834 ea20 ff7f 0000 1128 dab9 1d12 d111 h4. .....(......
0x7fff20ea3390 0000 0000 0000 0000 7834 ea20 ff7f 0000 ........x4. ....
0x7fff20ea33a0 0000 0000 0000 0000 0030 a271 f07f 0000 .........0.q....
0x7fff20ea33b0 1128 18df c953 2fee 1128 dc14 1ef1 31ee .(...S/..(....1.
0x7fff20ea33c0 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7fff20ea33d0 0000 0000 0000 0000 0000 0000 0000 0000 ................
0x7fff20ea33e0 6834 ea20 ff7f 0000 00f9 838c 1ccd 1f9e h4. ............
0x7fff20ea33f0 0e00 0000 0000 0000 85d7 8171 f07f 0000 ...........q....
We got the answer!!
Crackme6
Using radare2 again.
└─$ r2 -d crackme6
[0x7f462f4c2360]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Finding and parsing C++ vtables (avrr)
[x] Skipping type matching analysis in debugger mode (aaft)
[x] Propagate noreturn information (aanr)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x7f462f4c2360]> afl
0x00400490 1 42 entry0
0x00400470 1 6 sym.imp.__libc_start_main
0x004004c0 4 41 sym.deregister_tm_clones
0x004004f0 4 57 sym.register_tm_clones
0x00400530 3 28 sym.__do_global_dtors_aux
0x00400550 4 45 -> 42 entry.init0
0x004007d0 1 2 sym.__libc_csu_fini
0x004007d4 1 9 sym._fini
0x004006d1 4 64 sym.compare_pwd
0x00400760 4 101 sym.__libc_csu_init
0x00400711 4 74 main
0x0040057d 28 340 sym.my_secure_test
0x00400418 3 26 sym._init
0x00400480 1 6 loc.imp.__gmon_start__
0x00400450 1 6 sym.imp.puts
0x00400460 1 6 sym.imp.printf
[0x7f462f4c2360]> pdf @main
; DATA XREF from entry0 @ 0x4004ad
┌ 74: int main (int argc, char **argv);
│ ; var int64_t var_10h @ rbp-0x10
│ ; var int64_t var_4h @ rbp-0x4
│ ; arg int argc @ rdi
│ ; arg char **argv @ rsi
│ 0x00400711 55 push rbp
│ 0x00400712 4889e5 mov rbp, rsp
│ 0x00400715 4883ec10 sub rsp, 0x10
│ 0x00400719 897dfc mov dword [var_4h], edi ; argc
│ 0x0040071c 488975f0 mov qword [var_10h], rsi ; argv
│ 0x00400720 837dfc02 cmp dword [var_4h], 2
│ ┌─< 0x00400724 741b je 0x400741
│ │ 0x00400726 488b45f0 mov rax, qword [var_10h]
│ │ 0x0040072a 488b00 mov rax, qword [rax]
│ │ 0x0040072d 4889c6 mov rsi, rax
│ │ 0x00400730 bf10084000 mov edi, str.Usage_:__s_password_nGood_luck__read_the_source_n ; 0x400810 ; "Usage : %s password\nGood luck, read the source\n"
│ │ 0x00400735 b800000000 mov eax, 0
│ │ 0x0040073a e821fdffff call sym.imp.printf ; int printf(const char *format)
│ ┌──< 0x0040073f eb13 jmp 0x400754
│ │└─> 0x00400741 488b45f0 mov rax, qword [var_10h]
│ │ 0x00400745 4883c008 add rax, 8
│ │ 0x00400749 488b00 mov rax, qword [rax]
│ │ 0x0040074c 4889c7 mov rdi, rax
│ │ 0x0040074f e87dffffff call sym.compare_pwd
│ │ ; CODE XREF from main @ 0x40073f
│ └──> 0x00400754 b800000000 mov eax, 0
│ 0x00400759 c9 leave
└ 0x0040075a c3 ret
[0x7f462f4c2360]> pdf @sym.compare_pwd
; CALL XREF from main @ 0x40074f
┌ 64: sym.compare_pwd (int64_t arg1);
│ ; var int64_t var_8h @ rbp-0x8
│ ; arg int64_t arg1 @ rdi
│ 0x004006d1 55 push rbp
│ 0x004006d2 4889e5 mov rbp, rsp
│ 0x004006d5 4883ec10 sub rsp, 0x10
│ 0x004006d9 48897df8 mov qword [var_8h], rdi ; arg1
│ 0x004006dd 488b45f8 mov rax, qword [var_8h]
│ 0x004006e1 4889c7 mov rdi, rax
│ 0x004006e4 e894feffff call sym.my_secure_test
│ 0x004006e9 85c0 test eax, eax
│ ┌─< 0x004006eb 750c jne 0x4006f9
│ │ 0x004006ed bfe8074000 mov edi, str.password_OK ; 0x4007e8 ; "password OK"
│ │ 0x004006f2 e859fdffff call sym.imp.puts ; int puts(const char *s)
│ ┌──< 0x004006f7 eb16 jmp 0x40070f
│ │└─> 0x004006f9 488b45f8 mov rax, qword [var_8h]
│ │ 0x004006fd 4889c6 mov rsi, rax
│ │ 0x00400700 bff4074000 mov edi, str.password___s__not_OK_n ; 0x4007f4 ; "password \"%s\" not OK\n"
│ │ 0x00400705 b800000000 mov eax, 0
│ │ 0x0040070a e851fdffff call sym.imp.printf ; int printf(const char *format)
│ │ ; CODE XREF from sym.compare_pwd @ 0x4006f7
│ └──> 0x0040070f c9 leave
└ 0x00400710 c3 ret
[0x7f462f4c2360]> pdf @sym.my_secure_test
; CALL XREF from sym.compare_pwd @ 0x4006e4
┌ 340: sym.my_secure_test (int64_t arg1);
│ ; var int64_t var_8h @ rbp-0x8
│ ; arg int64_t arg1 @ rdi
│ 0x0040057d 55 push rbp
│ 0x0040057e 4889e5 mov rbp, rsp
│ 0x00400581 48897df8 mov qword [var_8h], rdi ; arg1
│ 0x00400585 488b45f8 mov rax, qword [var_8h]
│ 0x00400589 0fb600 movzx eax, byte [rax]
│ 0x0040058c 84c0 test al, al
│ ┌─< 0x0040058e 740b je 0x40059b
│ │ 0x00400590 488b45f8 mov rax, qword [var_8h]
│ │ 0x00400594 0fb600 movzx eax, byte [rax]
│ │ 0x00400597 3c31 cmp al, 0x31 ; 49
│ ┌──< 0x00400599 740a je 0x4005a5
│ │└─> 0x0040059b b8ffffffff mov eax, 0xffffffff ; -1
│ │┌─< 0x004005a0 e92a010000 jmp 0x4006cf
│ └──> 0x004005a5 488b45f8 mov rax, qword [var_8h]
│ │ 0x004005a9 4883c001 add rax, 1
│ │ 0x004005ad 0fb600 movzx eax, byte [rax]
│ │ 0x004005b0 84c0 test al, al
│ ┌──< 0x004005b2 740f je 0x4005c3
│ ││ 0x004005b4 488b45f8 mov rax, qword [var_8h]
│ ││ 0x004005b8 4883c001 add rax, 1
│ ││ 0x004005bc 0fb600 movzx eax, byte [rax]
│ ││ 0x004005bf 3c33 cmp al, 0x33 ; 51
│ ┌───< 0x004005c1 740a je 0x4005cd
│ │└──> 0x004005c3 b8ffffffff mov eax, 0xffffffff ; -1
│ │┌──< 0x004005c8 e902010000 jmp 0x4006cf
│ └───> 0x004005cd 488b45f8 mov rax, qword [var_8h]
│ ││ 0x004005d1 4883c002 add rax, 2
│ ││ 0x004005d5 0fb600 movzx eax, byte [rax]
│ ││ 0x004005d8 84c0 test al, al
│ ┌───< 0x004005da 740f je 0x4005eb
│ │││ 0x004005dc 488b45f8 mov rax, qword [var_8h]
│ │││ 0x004005e0 4883c002 add rax, 2
│ │││ 0x004005e4 0fb600 movzx eax, byte [rax]
│ │││ 0x004005e7 3c33 cmp al, 0x33 ; 51
│ ┌────< 0x004005e9 740a je 0x4005f5
│ │└───> 0x004005eb b8ffffffff mov eax, 0xffffffff ; -1
│ │┌───< 0x004005f0 e9da000000 jmp 0x4006cf
│ └────> 0x004005f5 488b45f8 mov rax, qword [var_8h]
│ │││ 0x004005f9 4883c003 add rax, 3
│ │││ 0x004005fd 0fb600 movzx eax, byte [rax]
│ │││ 0x00400600 84c0 test al, al
│ ┌────< 0x00400602 740f je 0x400613
│ ││││ 0x00400604 488b45f8 mov rax, qword [var_8h]
│ ││││ 0x00400608 4883c003 add rax, 3
│ ││││ 0x0040060c 0fb600 movzx eax, byte [rax]
│ ││││ 0x0040060f 3c37 cmp al, 0x37 ; 55
│ ┌─────< 0x00400611 740a je 0x40061d
│ │└────> 0x00400613 b8ffffffff mov eax, 0xffffffff ; -1
│ │┌────< 0x00400618 e9b2000000 jmp 0x4006cf
│ └─────> 0x0040061d 488b45f8 mov rax, qword [var_8h]
│ ││││ 0x00400621 4883c004 add rax, 4
│ ││││ 0x00400625 0fb600 movzx eax, byte [rax]
│ ││││ 0x00400628 84c0 test al, al
│ ┌─────< 0x0040062a 740f je 0x40063b
│ │││││ 0x0040062c 488b45f8 mov rax, qword [var_8h]
│ │││││ 0x00400630 4883c004 add rax, 4
│ │││││ 0x00400634 0fb600 movzx eax, byte [rax]
│ │││││ 0x00400637 3c5f cmp al, 0x5f ; 95
│ ┌──────< 0x00400639 740a je 0x400645
│ │└─────> 0x0040063b b8ffffffff mov eax, 0xffffffff ; -1
│ │┌─────< 0x00400640 e98a000000 jmp 0x4006cf
│ └──────> 0x00400645 488b45f8 mov rax, qword [var_8h]
│ │││││ 0x00400649 4883c005 add rax, 5
│ │││││ 0x0040064d 0fb600 movzx eax, byte [rax]
│ │││││ 0x00400650 84c0 test al, al
│ ┌──────< 0x00400652 740f je 0x400663
│ ││││││ 0x00400654 488b45f8 mov rax, qword [var_8h]
│ ││││││ 0x00400658 4883c005 add rax, 5
│ ││││││ 0x0040065c 0fb600 movzx eax, byte [rax]
│ ││││││ 0x0040065f 3c70 cmp al, 0x70 ; 112
│ ┌───────< 0x00400661 7407 je 0x40066a
│ │└──────> 0x00400663 b8ffffffff mov eax, 0xffffffff ; -1
│ │┌──────< 0x00400668 eb65 jmp 0x4006cf
│ └───────> 0x0040066a 488b45f8 mov rax, qword [var_8h]
│ ││││││ 0x0040066e 4883c006 add rax, 6
│ ││││││ 0x00400672 0fb600 movzx eax, byte [rax]
│ ││││││ 0x00400675 84c0 test al, al
│ ┌───────< 0x00400677 740f je 0x400688
│ │││││││ 0x00400679 488b45f8 mov rax, qword [var_8h]
│ │││││││ 0x0040067d 4883c006 add rax, 6
│ │││││││ 0x00400681 0fb600 movzx eax, byte [rax]
│ │││││││ 0x00400684 3c77 cmp al, 0x77 ; 119
│ ────────< 0x00400686 7407 je 0x40068f
│ └───────> 0x00400688 b8ffffffff mov eax, 0xffffffff ; -1
│ ┌───────< 0x0040068d eb40 jmp 0x4006cf
│ ────────> 0x0040068f 488b45f8 mov rax, qword [var_8h]
│ │││││││ 0x00400693 4883c007 add rax, 7
│ │││││││ 0x00400697 0fb600 movzx eax, byte [rax]
│ │││││││ 0x0040069a 84c0 test al, al
│ ────────< 0x0040069c 740f je 0x4006ad
│ │││││││ 0x0040069e 488b45f8 mov rax, qword [var_8h]
│ │││││││ 0x004006a2 4883c007 add rax, 7
│ │││││││ 0x004006a6 0fb600 movzx eax, byte [rax]
│ │││││││ 0x004006a9 3c64 cmp al, 0x64 ; 100
│ ────────< 0x004006ab 7407 je 0x4006b4
│ ────────> 0x004006ad b8ffffffff mov eax, 0xffffffff ; -1
│ ────────< 0x004006b2 eb1b jmp 0x4006cf
│ ────────> 0x004006b4 488b45f8 mov rax, qword [var_8h]
│ │││││││ 0x004006b8 4883c008 add rax, 8
│ │││││││ 0x004006bc 0fb600 movzx eax, byte [rax]
│ │││││││ 0x004006bf 84c0 test al, al
│ ────────< 0x004006c1 7407 je 0x4006ca
│ │││││││ 0x004006c3 b8ffffffff mov eax, 0xffffffff ; -1
│ ────────< 0x004006c8 eb05 jmp 0x4006cf
│ ────────> 0x004006ca b800000000 mov eax, 0
│ │││││││ ; XREFS: CODE 0x004005a0 CODE 0x004005c8 CODE 0x004005f0 CODE 0x00400618 CODE 0x00400640 CODE 0x00400668
│ │││││││ ; XREFS: CODE 0x0040068d CODE 0x004006b2 CODE 0x004006c8
│ └└└└└└└─> 0x004006cf 5d pop rbp
└ 0x004006d0 c3 ret
We can see that there is a compare function inside the @sym.my_secure_test which compare values inside the register. The Hex, let’s convert it to Text.
Crackme7
This looks like an interactive application file. On running it with strings, I couldn’t find anything interesting. Let’s analyze it with R2.
r2 -d crackme7
[0xf7f34120]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Finding and parsing C++ vtables (avrr)
[x] Skipping type matching analysis in debugger mode (aaft)
[x] Propagate noreturn information (aanr)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0xf7f34120]> afl
0x080483c0 1 34 entry0
0x08048380 1 6 sym.imp.__libc_start_main
0x08048400 4 43 sym.deregister_tm_clones
0x08048430 4 53 sym.register_tm_clones
0x08048470 3 30 sym.__do_global_dtors_aux
0x08048490 4 43 -> 40 entry.init0
0x080486a6 4 149 sym.giveFlag
0x080487a0 1 2 sym.__libc_csu_fini
0x080483f0 1 4 sym.__x86.get_pc_thunk.bx
0x080487a4 1 20 sym._fini
0x08048740 4 93 sym.__libc_csu_init
0x080484bb 20 491 main
0x08048324 3 35 sym._init
0x080483b0 1 6 sym..plt.got
0x08048360 1 6 sym.imp.printf
0x08048370 1 6 sym.imp.puts
0x08048390 1 6 sym.imp.memset
0x080483a0 1 6 sym.imp.__isoc99_scanf
[0xf7f34120]> pdf @main
; DATA XREF from entry0 @ 0x80483d7
┌ 491: int main (char **argv);
│ ; var int32_t var_78h @ ebp-0x78
│ ; var int32_t var_14h @ ebp-0x14
│ ; var int32_t var_10h @ ebp-0x10
│ ; var int32_t var_ch @ ebp-0xc
│ ; var int32_t var_8h @ ebp-0x8
│ ; arg char **argv @ esp+0x94
│ 0x080484bb 8d4c2404 lea ecx, [argv]
│ 0x080484bf 83e4f0 and esp, 0xfffffff0
│ 0x080484c2 ff71fc push dword [ecx - 4]
│ 0x080484c5 55 push ebp
│ 0x080484c6 89e5 mov ebp, esp
│ 0x080484c8 57 push edi
│ 0x080484c9 51 push ecx
│ 0x080484ca 83ec70 sub esp, 0x70
│ ; CODE XREFS from main @ 0x8048590, 0x8048643
│ ┌┌─> 0x080484cd 83ec0c sub esp, 0xc
│ ╎╎ 0x080484d0 68e0870408 push str.Menu:_n_n_1__Say_hello_n_2__Add_numbers_n_3__Quit ; 0x80487e0 ; "Menu:\n\n[1] Say hello\n[2] Add numbers\n[3] Quit"
│ ╎╎ 0x080484d5 e896feffff call sym.imp.puts ; int puts(const char *s)
│ ╎╎ 0x080484da 83c410 add esp, 0x10
│ ╎╎ 0x080484dd 83ec0c sub esp, 0xc
│ ╎╎ 0x080484e0 680e880408 push str._n____ ; 0x804880e ; "\n[>] "
│ ╎╎ 0x080484e5 e876feffff call sym.imp.printf ; int printf(const char *format)
│ ╎╎ 0x080484ea 83c410 add esp, 0x10
│ ╎╎ 0x080484ed 83ec08 sub esp, 8
│ ╎╎ 0x080484f0 8d45f4 lea eax, [var_ch]
│ ╎╎ 0x080484f3 50 push eax
│ ╎╎ 0x080484f4 6814880408 push 0x8048814
│ ╎╎ 0x080484f9 e8a2feffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ ╎╎ 0x080484fe 83c410 add esp, 0x10
│ ╎╎ 0x08048501 83f801 cmp eax, 1 ; 1
│ ┌───< 0x08048504 741a je 0x8048520
│ │╎╎ 0x08048506 83ec0c sub esp, 0xc
│ │╎╎ 0x08048509 6817880408 push str.Unknown_input_ ; 0x8048817 ; "Unknown input!"
│ │╎╎ 0x0804850e e85dfeffff call sym.imp.puts ; int puts(const char *s)
│ │╎╎ 0x08048513 83c410 add esp, 0x10
│ │╎╎ 0x08048516 b801000000 mov eax, 1
│ ┌────< 0x0804851b e97c010000 jmp 0x804869c
│ │└───> 0x08048520 8b45f4 mov eax, dword [var_ch]
│ │ ╎╎ 0x08048523 83f801 cmp eax, 1 ; 1
│ │┌───< 0x08048526 756d jne 0x8048595
│ ││╎╎ 0x08048528 83ec0c sub esp, 0xc
│ ││╎╎ 0x0804852b 6826880408 push str.What_is_your_name__ ; 0x8048826 ; "What is your name? "
│ ││╎╎ 0x08048530 e82bfeffff call sym.imp.printf ; int printf(const char *format)
│ ││╎╎ 0x08048535 83c410 add esp, 0x10
│ ││╎╎ 0x08048538 8d5588 lea edx, [var_78h]
│ ││╎╎ 0x0804853b b800000000 mov eax, 0
│ ││╎╎ 0x08048540 b919000000 mov ecx, 0x19 ; 25
│ ││╎╎ 0x08048545 89d7 mov edi, edx
│ ││╎╎ 0x08048547 f3ab rep stosd dword es:[edi], eax
│ ││╎╎ 0x08048549 83ec08 sub esp, 8
│ ││╎╎ 0x0804854c 8d4588 lea eax, [var_78h]
│ ││╎╎ 0x0804854f 50 push eax
│ ││╎╎ 0x08048550 683a880408 push str._99s ; 0x804883a ; "%99s"
│ ││╎╎ 0x08048555 e846feffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ ││╎╎ 0x0804855a 83c410 add esp, 0x10
│ ││╎╎ 0x0804855d 83f801 cmp eax, 1 ; 1
│ ┌─────< 0x08048560 741a je 0x804857c
│ │││╎╎ 0x08048562 83ec0c sub esp, 0xc
│ │││╎╎ 0x08048565 683f880408 push str.Unable_to_read_name_ ; 0x804883f ; "Unable to read name!"
│ │││╎╎ 0x0804856a e801feffff call sym.imp.puts ; int puts(const char *s)
│ │││╎╎ 0x0804856f 83c410 add esp, 0x10
│ │││╎╎ 0x08048572 b801000000 mov eax, 1
│ ┌──────< 0x08048577 e920010000 jmp 0x804869c
│ │└─────> 0x0804857c 83ec08 sub esp, 8
│ │ ││╎╎ 0x0804857f 8d4588 lea eax, [var_78h]
│ │ ││╎╎ 0x08048582 50 push eax
│ │ ││╎╎ 0x08048583 6854880408 push str.Hello___s__n ; 0x8048854 ; "Hello, %s!\n"
│ │ ││╎╎ 0x08048588 e8d3fdffff call sym.imp.printf ; int printf(const char *format)
│ │ ││╎╎ 0x0804858d 83c410 add esp, 0x10
│ │ ││└──< 0x08048590 e938ffffff jmp 0x80484cd
│ │ │└───> 0x08048595 8b45f4 mov eax, dword [var_ch]
│ │ │ ╎ 0x08048598 83f802 cmp eax, 2 ; 2
│ │ │ ┌──< 0x0804859b 0f85a7000000 jne 0x8048648
│ │ │ │╎ 0x080485a1 83ec0c sub esp, 0xc
│ │ │ │╎ 0x080485a4 6860880408 push str.Enter_first_number:_ ; 0x8048860 ; "Enter first number: "
│ │ │ │╎ 0x080485a9 e8b2fdffff call sym.imp.printf ; int printf(const char *format)
│ │ │ │╎ 0x080485ae 83c410 add esp, 0x10
│ │ │ │╎ 0x080485b1 83ec08 sub esp, 8
│ │ │ │╎ 0x080485b4 8d45f0 lea eax, [var_10h]
│ │ │ │╎ 0x080485b7 50 push eax
│ │ │ │╎ 0x080485b8 6875880408 push 0x8048875
│ │ │ │╎ 0x080485bd e8defdffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ │ │ │╎ 0x080485c2 83c410 add esp, 0x10
│ │ │ │╎ 0x080485c5 83f801 cmp eax, 1 ; 1
│ │ │┌───< 0x080485c8 741a je 0x80485e4
│ │ │││╎ 0x080485ca 83ec0c sub esp, 0xc
│ │ │││╎ 0x080485cd 6878880408 push str.Unable_to_read_number_ ; 0x8048878 ; "Unable to read number!"
│ │ │││╎ 0x080485d2 e899fdffff call sym.imp.puts ; int puts(const char *s)
│ │ │││╎ 0x080485d7 83c410 add esp, 0x10
│ │ │││╎ 0x080485da b801000000 mov eax, 1
│ │┌─────< 0x080485df e9b8000000 jmp 0x804869c
│ │││└───> 0x080485e4 83ec0c sub esp, 0xc
│ │││ │╎ 0x080485e7 688f880408 push str.Enter_second_number:_ ; 0x804888f ; "Enter second number: "
│ │││ │╎ 0x080485ec e86ffdffff call sym.imp.printf ; int printf(const char *format)
│ │││ │╎ 0x080485f1 83c410 add esp, 0x10
│ │││ │╎ 0x080485f4 83ec08 sub esp, 8
│ │││ │╎ 0x080485f7 8d45ec lea eax, [var_14h]
│ │││ │╎ 0x080485fa 50 push eax
│ │││ │╎ 0x080485fb 6875880408 push 0x8048875
│ │││ │╎ 0x08048600 e89bfdffff call sym.imp.__isoc99_scanf ; int scanf(const char *format)
│ │││ │╎ 0x08048605 83c410 add esp, 0x10
│ │││ │╎ 0x08048608 83f801 cmp eax, 1 ; 1
│ │││┌───< 0x0804860b 7417 je 0x8048624
│ │││││╎ 0x0804860d 83ec0c sub esp, 0xc
│ │││││╎ 0x08048610 6878880408 push str.Unable_to_read_number_ ; 0x8048878 ; "Unable to read number!"
│ │││││╎ 0x08048615 e856fdffff call sym.imp.puts ; int puts(const char *s)
│ │││││╎ 0x0804861a 83c410 add esp, 0x10
│ │││││╎ 0x0804861d b801000000 mov eax, 1
│ ┌───────< 0x08048622 eb78 jmp 0x804869c
│ ││││└───> 0x08048624 8b55f0 mov edx, dword [var_10h]
│ ││││ │╎ 0x08048627 8b45ec mov eax, dword [var_14h]
│ ││││ │╎ 0x0804862a 8d0c02 lea ecx, [edx + eax]
│ ││││ │╎ 0x0804862d 8b55ec mov edx, dword [var_14h]
│ ││││ │╎ 0x08048630 8b45f0 mov eax, dword [var_10h]
│ ││││ │╎ 0x08048633 51 push ecx
│ ││││ │╎ 0x08048634 52 push edx
│ ││││ │╎ 0x08048635 50 push eax
│ ││││ │╎ 0x08048636 68a5880408 push str._d___d___d_n ; 0x80488a5 ; "%d + %d = %d\n"
│ ││││ │╎ 0x0804863b e820fdffff call sym.imp.printf ; int printf(const char *format)
│ ││││ │╎ 0x08048640 83c410 add esp, 0x10
│ ││││ │└─< 0x08048643 e985feffff jmp 0x80484cd
│ ││││ └──> 0x08048648 8b45f4 mov eax, dword [var_ch]
│ ││││ 0x0804864b 83f803 cmp eax, 3 ; 3
│ ││││ ┌─< 0x0804864e 7512 jne 0x8048662
│ ││││ │ 0x08048650 83ec0c sub esp, 0xc
│ ││││ │ 0x08048653 68b3880408 push str.Goodbye_ ; 0x80488b3 ; "Goodbye!"
│ ││││ │ 0x08048658 e813fdffff call sym.imp.puts ; int puts(const char *s)
│ ││││ │ 0x0804865d 83c410 add esp, 0x10
│ ││││ ┌──< 0x08048660 eb35 jmp 0x8048697
│ ││││ │└─> 0x08048662 8b45f4 mov eax, dword [var_ch]
│ ││││ │ 0x08048665 3d697a0000 cmp eax, 0x7a69
│ ││││ │┌─< 0x0804866a 7517 jne 0x8048683
│ ││││ ││ 0x0804866c 83ec0c sub esp, 0xc
│ ││││ ││ 0x0804866f 68bc880408 push str.Wow_such_h4x0r_ ; 0x80488bc ; "Wow such h4x0r!"
│ ││││ ││ 0x08048674 e8f7fcffff call sym.imp.puts ; int puts(const char *s)
│ ││││ ││ 0x08048679 83c410 add esp, 0x10
│ ││││ ││ 0x0804867c e825000000 call sym.giveFlag
│ ││││┌───< 0x08048681 eb14 jmp 0x8048697
│ ││││││└─> 0x08048683 8b45f4 mov eax, dword [var_ch]
│ ││││││ 0x08048686 83ec08 sub esp, 8
│ ││││││ 0x08048689 50 push eax
│ ││││││ 0x0804868a 68cc880408 push str.Unknown_choice:__d_n ; 0x80488cc ; "Unknown choice: %d\n"
│ ││││││ 0x0804868f e8ccfcffff call sym.imp.printf ; int printf(const char *format)
│ ││││││ 0x08048694 83c410 add esp, 0x10
│ ││││││ ; CODE XREFS from main @ 0x8048660, 0x8048681
│ ││││└└──> 0x08048697 b800000000 mov eax, 0
│ ││││ ; CODE XREFS from main @ 0x804851b, 0x8048577, 0x80485df, 0x8048622
│ └└└└────> 0x0804869c 8d65f8 lea esp, [var_8h]
│ 0x0804869f 59 pop ecx
│ 0x080486a0 5f pop edi
│ 0x080486a1 5d pop ebp
│ 0x080486a2 8d61fc lea esp, [ecx - 4]
└ 0x080486a5 c3 ret
Looking at the main function, we can see that it is comparing a value. It is comparing a hex value- cmp eax, 0x7a69
Let’s convert it to decimal.
Pass the hex value to the application and we would get the flag.
Crackme8
Let’s go, our final task.!. We need a password for this. Open it up in radare.
r2 -d crackme8
[0xf7f87120]> aaa
[x] Analyze all flags starting with sym. and entry0 (aa)
[x] Analyze function calls (aac)
[x] Analyze len bytes of instructions for references (aar)
[x] Finding and parsing C++ vtables (avrr)
[x] Skipping type matching analysis in debugger mode (aaft)
[x] Propagate noreturn information (aanr)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0xf7f87120]> afl
0x080483a0 1 34 entry0
0x08048360 1 6 sym.imp.__libc_start_main
0x080483e0 4 43 sym.deregister_tm_clones
0x08048410 4 53 sym.register_tm_clones
0x08048450 3 30 sym.__do_global_dtors_aux
0x08048470 4 43 -> 40 entry.init0
0x08048524 4 149 sym.giveFlag
0x08048620 1 2 sym.__libc_csu_fini
0x080483d0 1 4 sym.__x86.get_pc_thunk.bx
0x08048624 1 20 sym._fini
0x080485c0 4 93 sym.__libc_csu_init
0x0804849b 6 137 main
0x08048300 3 35 sym._init
0x08048390 1 6 sym..plt.got
0x08048340 1 6 sym.imp.printf
0x08048350 1 6 sym.imp.puts
0x08048370 1 6 sym.imp.memset
0x08048380 1 6 sym.imp.atoi
[0xf7f87120]> pdf @main
; DATA XREF from entry0 @ 0x80483b7
┌ 137: int main (char **argv);
│ ; var int32_t var_4h @ ebp-0x4
│ ; arg char **argv @ esp+0x24
│ 0x0804849b 8d4c2404 lea ecx, [argv]
│ 0x0804849f 83e4f0 and esp, 0xfffffff0
│ 0x080484a2 ff71fc push dword [ecx - 4]
│ 0x080484a5 55 push ebp
│ 0x080484a6 89e5 mov ebp, esp
│ 0x080484a8 51 push ecx
│ 0x080484a9 83ec04 sub esp, 4
│ 0x080484ac 89c8 mov eax, ecx
│ 0x080484ae 833802 cmp dword [eax], 2
│ ┌─< 0x080484b1 741d je 0x80484d0
│ │ 0x080484b3 8b4004 mov eax, dword [eax + 4]
│ │ 0x080484b6 8b00 mov eax, dword [eax]
│ │ 0x080484b8 83ec08 sub esp, 8
│ │ 0x080484bb 50 push eax
│ │ 0x080484bc 6860860408 push str.Usage:__s_password_n ; 0x8048660 ; "Usage: %s password\n"
│ │ 0x080484c1 e87afeffff call sym.imp.printf ; int printf(const char *format)
│ │ 0x080484c6 83c410 add esp, 0x10
│ │ 0x080484c9 b801000000 mov eax, 1
│ ┌──< 0x080484ce eb4c jmp 0x804851c
│ │└─> 0x080484d0 8b4004 mov eax, dword [eax + 4]
│ │ 0x080484d3 83c004 add eax, 4
│ │ 0x080484d6 8b00 mov eax, dword [eax]
│ │ 0x080484d8 83ec0c sub esp, 0xc
│ │ 0x080484db 50 push eax
│ │ 0x080484dc e89ffeffff call sym.imp.atoi ; int atoi(const char *str)
│ │ 0x080484e1 83c410 add esp, 0x10
│ │ 0x080484e4 3d0df0feca cmp eax, 0xcafef00d
│ │┌─< 0x080484e9 7417 je 0x8048502
│ ││ 0x080484eb 83ec0c sub esp, 0xc
│ ││ 0x080484ee 6874860408 push str.Access_denied. ; 0x8048674 ; "Access denied."
│ ││ 0x080484f3 e858feffff call sym.imp.puts ; int puts(const char *s)
│ ││ 0x080484f8 83c410 add esp, 0x10
│ ││ 0x080484fb b801000000 mov eax, 1
│ ┌───< 0x08048500 eb1a jmp 0x804851c
│ ││└─> 0x08048502 83ec0c sub esp, 0xc
│ ││ 0x08048505 6883860408 push str.Access_granted. ; 0x8048683 ; "Access granted."
│ ││ 0x0804850a e841feffff call sym.imp.puts ; int puts(const char *s)
│ ││ 0x0804850f 83c410 add esp, 0x10
│ ││ 0x08048512 e80d000000 call sym.giveFlag
│ ││ 0x08048517 b800000000 mov eax, 0
│ ││ ; CODE XREFS from main @ 0x80484ce, 0x8048500
│ └└──> 0x0804851c 8b4dfc mov ecx, dword [var_4h]
│ 0x0804851f c9 leave
│ 0x08048520 8d61fc lea esp, [ecx - 4]
└ 0x08048523 c3 ret
[0xf7f87120]>
We can see the cmp hex value - cmp eax, 0xcafef00d. Let’s convert it to decimal. The signed 2’s complement value works.
Got the FLAG!!!
Happy Hacking!!