Hello,
This is another IOLI crackme challenge solution.
root@kali:~/IOLI-crackme/bin-linux# r2 crackme0x05
[0x080483d0]> 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] Constructing a function name for fcn.* and sym.func.* functions (aan)
[x] Type matching analysis for all functions (afta)
[x] Use -AA or aaaa to perform additional experimental analysis.
[0x080483d0]> afl
0x0804833c 1 23 sym._init
0x08048364 1 6 sym.imp.__libc_start_main
0x08048374 1 6 sym.imp.scanf
0x08048384 1 6 sym.imp.strlen
0x08048394 1 6 sym.imp.printf
0x080483a4 1 6 sym.imp.sscanf
0x080483b4 1 6 sym.imp.exit
0x080483d0 1 33 entry0
0x080483f4 3 33 fcn.080483f4
0x08048420 6 47 sym.__do_global_dtors_aux
0x08048450 4 50 sym.frame_dummy
0x08048484 3 68 sym.parell
0x080484c8 6 120 sym.check
0x08048540 1 92 sym.main
0x080485a0 4 99 sym.__libc_csu_init
0x08048610 1 5 sym.__libc_csu_fini
0x08048615 1 4 sym.__i686.get_pc_thunk.bx
0x08048620 4 35 sym.__do_global_ctors_aux
0x08048644 1 26 sym._fini
[0x080483d0]> pdf @ sym.main
-- main:
┌ (fcn) sym.main 92
│ sym.main (int argc, char **argv, char **envp);
│ ; var int local_78h @ ebp-0x78
│ ; var int local_4h @ esp+0x4
│ ; DATA XREF from entry0 (0x80483e7)
│ 0x08048540 55 push ebp ; push word, doubleword or quadword onto the stack
│ 0x08048541 89e5 mov ebp, esp ; moves data from src to dst
│ 0x08048543 81ec88000000 sub esp, 0x88 ; substract src and dst, stores result on dst
│ 0x08048549 83e4f0 and esp, 0xfffffff0 ; binary and operation between src and dst, stores result on dst
│ 0x0804854c b800000000 mov eax, 0 ; moves data from src to dst
│ 0x08048551 83c00f add eax, 0xf ; adds src and dst, stores result on dst
│ 0x08048554 83c00f add eax, 0xf ; adds src and dst, stores result on dst
│ 0x08048557 c1e804 shr eax, 4 ; logic right shift (0 padding)
│ 0x0804855a c1e004 shl eax, 4 ; logic left shift (0 padding)
│ 0x0804855d 29c4 sub esp, eax ; substract src and dst, stores result on dst
│ 0x0804855f c704248e8604. mov dword [esp], str.IOLI_Crackme_Level_0x05 ; [0x804868e:4]=0x494c4f49 ; "IOLI Crackme Level 0x05\n" ; moves data from src to dst; const char *format
│ 0x08048566 e829feffff call sym.imp.printf ; calls a subroutine, push eip into the stack (esp) ; int printf(const char *format)
│ 0x0804856b c70424a78604. mov dword [esp], str.Password: ; [0x80486a7:4]=0x73736150 ; "Password: " ; moves data from src to dst; const char *format
│ 0x08048572 e81dfeffff call sym.imp.printf ; calls a subroutine, push eip into the stack (esp) ; int printf(const char *format)
│ 0x08048577 8d4588 lea eax, dword [local_78h] ; load effective address
│ 0x0804857a 89442404 mov dword [local_4h], eax ; moves data from src to dst
│ 0x0804857e c70424b28604. mov dword [esp], 0x80486b2 ; [0x80486b2:4]=0x7325 ; moves data from src to dst; const char *format
│ 0x08048585 e8eafdffff call sym.imp.scanf ; calls a subroutine, push eip into the stack (esp) ; int scanf(const char *format)
│ 0x0804858a 8d4588 lea eax, dword [local_78h] ; load effective address
│ 0x0804858d 890424 mov dword [esp], eax ; moves data from src to dst
│ 0x08048590 e833ffffff call sym.check ; calls a subroutine, push eip into the stack (esp)
│ 0x08048595 b800000000 mov eax, 0 ; moves data from src to dst
│ 0x0804859a c9 leave ; one byte alias for mov esp, ebp ; pop ebp
└ 0x0804859b c3 ret ; return from subroutine.
pop 4 bytes from esp and jump there.
[0x080483d0]> pdf @ sym.check`
┌ (fcn) sym.check 120
│ sym.check (char *s);
│ ; var char *local_dh @ ebp-0xd
│ ; var unsigned int local_ch @ ebp-0xc
│ ; var unsigned int local_8h @ ebp-0x8
│ ; var int local_4h @ ebp-0x4
│ ; arg char *s @ ebp+0x8
│ ; var char *format @ esp+0x4
│ ; var int local_8h_2 @ esp+0x8
│ ; CALL XREF from sym.main (0x8048590)
│ 0x080484c8 55 push ebp ; push word, doubleword or quadword onto the stack
│ 0x080484c9 89e5 mov ebp, esp ; moves data from src to dst
│ 0x080484cb 83ec28 sub esp, 0x28 ; '(' ; substract src and dst, stores result on dst
│ 0x080484ce c745f8000000. mov dword [local_8h], 0 ; moves data from src to dst
│ 0x080484d5 c745f4000000. mov dword [local_ch], 0 ; moves data from src to dst
│ ; CODE XREF from sym.check (0x8048530)
│ ┌─> 0x080484dc 8b4508 mov eax, dword [s] ; [0x8:4]=-1 ; 8 ; moves data from src to dst
│ ╎ 0x080484df 890424 mov dword [esp], eax ; moves data from src to dst; const char *s
│ ╎ 0x080484e2 e89dfeffff call sym.imp.strlen ; calls a subroutine, push eip into the stack (esp) ; size_t strlen(const char *s)
│ ╎ 0x080484e7 3945f4 cmp dword [local_ch], eax ; compare two operands
│ ┌──< 0x080484ea 7346 jae 0x8048532 ; jump short if above or equal (cf=0)
│ │╎ 0x080484ec 8b45f4 mov eax, dword [local_ch] ; moves data from src to dst
│ │╎ 0x080484ef 034508 add eax, dword [s] ; adds src and dst, stores result on dst
│ │╎ 0x080484f2 0fb600 movzx eax, byte [eax] ; move dst register size padding with zeroes
│ │╎ 0x080484f5 8845f3 mov byte [local_dh], al ; moves data from src to dst
│ │╎ 0x080484f8 8d45fc lea eax, dword [local_4h] ; load effective address
│ │╎ 0x080484fb 89442408 mov dword [local_8h_2], eax ; moves data from src to dst; ...
│ │╎ 0x080484ff c74424046886. mov dword [format], 0x8048668 ; [0x8048668:4]=0x50006425 ; moves data from src to dst; const char *format
│ │╎ 0x08048507 8d45f3 lea eax, dword [local_dh] ; load effective address
│ │╎ 0x0804850a 890424 mov dword [esp], eax ; moves data from src to dst; const char *s
│ │╎ 0x0804850d e892feffff call sym.imp.sscanf ; calls a subroutine, push eip into the stack (esp) ; int sscanf(const char *s, const char *format, ...)
│ │╎ 0x08048512 8b55fc mov edx, dword [local_4h] ; moves data from src to dst
│ │╎ 0x08048515 8d45f8 lea eax, dword [local_8h] ; load effective address
│ │╎ 0x08048518 0110 add dword [eax], edx ; adds src and dst, stores result on dst
│ │╎ 0x0804851a 837df810 cmp dword [local_8h], 0x10 ; compare two operands
│ ┌───< 0x0804851e 750b jne 0x804852b ; jump short if not equal/not zero (zf=0)
│ ││╎ 0x08048520 8b4508 mov eax, dword [s] ; [0x8:4]=-1 ; 8 ; moves data from src to dst
│ ││╎ 0x08048523 890424 mov dword [esp], eax ; moves data from src to dst
│ ││╎ 0x08048526 e859ffffff call sym.parell ; calls a subroutine, push eip into the stack (esp)
│ ││╎ ; CODE XREF from sym.check (0x804851e)
│ └───> 0x0804852b 8d45f4 lea eax, dword [local_ch] ; load effective address
│ │╎ 0x0804852e ff00 inc dword [eax] ; increment by 1
│ │└─< 0x08048530 ebaa jmp 0x80484dc ; jump
│ │ ; CODE XREF from sym.check (0x80484ea)
│ └──> 0x08048532 c70424798604. mov dword [esp], str.Password_Incorrect ; [0x8048679:4]=0x73736150 ; "Password Incorrect!\n" ; moves data from src to dst; const char *format
│ 0x08048539 e856feffff call sym.imp.printf ; calls a subroutine, push eip into the stack (esp) ; int printf(const char *format)
│ 0x0804853e c9 leave ; one byte alias for mov esp, ebp ; pop ebp
└ 0x0804853f c3 ret ; return from subroutine.
Pop 4 bytes from esp and jump there.
[0x080483d0]> ? 0x10
hex 0x10
octal 020
unit 16
segment 0000:0010
int32 16
string "\x10"
binary 0b00010000f
value: 16.0
float: 0.000000f
double: 0.000000
trits 0t121
Apparently this levels so similar to the past one, so let’s try the same method with 16 as cmp operand.
root@kali:~/IOLI-crackme/bin-linux# ./crackme0x05
IOLI Crackme Level 0x05
Password: 88
Password OK!