標籤:

R2逆向學習(1-3)

樣本

使用的是IOLI-crackme

crackme0x00

直接運行:

./crackme0x00 nIOLI Crackme Level 0x00nPassword: 123nInvalid Password!n

直接使用r2載入反編譯

r2 crackme0x00 n-- Too bad there is no gif support in r2. Yet. -- @r2gifn[0x08048360]> aaan[x] Analyze all flags starting with sym. and entry0 (aa)n[x] Analyze len bytes of instructions for references (aar)n[x] Analyze function calls (aac)n[x] Use -AA or aaaa to perform additional experimental analysis.n[x] Constructing a function name for fcn.* and sym.func.* functions (aan)n[0x08048360]> n

運行aaa進行反編譯

查看字元串信息:

iznvaddr=0x08048568 paddr=0x00000568 ordinal=000 sz=25 len=24 section=.rodata type=ascii string=IOLI Crackme Level 0x00nvaddr=0x08048581 paddr=0x00000581 ordinal=001 sz=11 len=10 section=.rodata type=ascii string=Password: nvaddr=0x0804858f paddr=0x0000058f ordinal=002 sz=7 len=6 section=.rodata type=ascii string=250382nvaddr=0x08048596 paddr=0x00000596 ordinal=003 sz=19 len=18 section=.rodata type=ascii string=Invalid Password!nvaddr=0x080485a9 paddr=0x000005a9 ordinal=004 sz=16 len=15 section=.rodata type=ascii string=Password OK :)n

可以明顯的看到字元串信息

裡面有個250382,這個是東西?

使用afl查看用到的函數:

afln0x080482f8 1 23 sym._initn0x08048320 1 6 sym.imp.__libc_start_mainn0x08048330 1 6 sym.imp.scanfn0x08048340 1 6 sym.imp.printfn0x08048350 1 6 sym.imp.strcmpn0x08048360 1 33 entry0n0x08048384 3 33 fcn.08048384n0x080483b0 6 47 sym.__do_global_dtors_auxn0x080483e0 4 50 sym.frame_dummyn0x08048414 4 127 mainn0x080484a0 4 99 sym.__libc_csu_initn0x08048510 1 5 sym.__libc_csu_finin0x08048515 1 4 sym.__i686.get_pc_thunk.bxn0x08048520 4 35 sym.__do_global_ctors_auxn0x08048544 1 26 sym._finin

裡面的函數fcn.08048384應該是主要函數,進入函數反編譯查看代碼

[0x08048000]> s 0x08048384n[0x08048384]> pdfn/ (fcn) fcn.08048384 33n| fcn.08048384 ();n| ; CALL XREF from 0x080482fe (sym._init)n| ; CALL XREF from 0x08048388 (fcn.08048384)n| 0x08048384 55 push ebpn| 0x08048385 89e5 mov ebp, espn| 0x08048387 53 push ebxn| 0x08048388 e800000000 call 0x804838dn| ; CALL XREF from 0x08048388 (fcn.08048384)n| 0x0804838d 5b pop ebxn| 0x0804838e 81c3671c0000 add ebx, 0x1c67n| 0x08048394 52 push edxn| 0x08048395 8b83fcffffff mov eax, dword [ebx - 4]n| 0x0804839b 85c0 test eax, eaxn| ,=< 0x0804839d 7402 je 0x80483a1n| | 0x0804839f ffd0 call eaxn| | ; JMP XREF from 0x0804839d (fcn.08048384)n| `-> 0x080483a1 58 pop eaxn| 0x080483a2 5b pop ebxn| 0x080483a3 c9 leaven 0x080483a4 c3 retn

後面不知道咋搞了,直接使用250382輸入

./crackme0x00 nIOLI Crackme Level 0x00nPassword: 250382nPassword OK :)n

crackme0x01

直接使用r2反編譯

r2 crackme0x01 n-- Invert the block bytes using the I key in visual moden[0x08048330]> aaan[x] Analyze all flags starting with sym. and entry0 (aa)n[x] Analyze len bytes of instructions for references (aar)n[x] Analyze function calls (aac)n[x] Use -AA or aaaa to perform additional experimental analysis.n[x] Constructing a function name for fcn.* and sym.func.* functions (aan)n[0x08048330]> afln0x080482d4 1 23 sym._initn0x080482fc 1 6 sym.imp.__libc_start_mainn0x0804830c 1 6 sym.imp.scanfn0x0804831c 1 6 sym.imp.printfn0x08048330 1 33 entry0n0x08048354 3 33 fcn.08048354n0x08048380 6 47 sym.__do_global_dtors_auxn0x080483b0 4 50 sym.frame_dummyn0x080483e4 4 113 mainn0x08048460 4 99 sym.__libc_csu_initn0x080484d0 1 5 sym.__libc_csu_finin0x080484d5 1 4 sym.__i686.get_pc_thunk.bxn0x080484e0 4 35 sym.__do_global_ctors_auxn0x08048504 1 26 sym._finin[0x08048330]> s mainn[0x080483e4]> pdfn;-- main:n/ (fcn) main 113n| main ();n| ; var int local_4h @ ebp-0x4n| ; var int local_4h_2 @ esp+0x4n| ; DATA XREF from 0x08048347 (entry0)n| 0x080483e4 55 push ebpn| 0x080483e5 89e5 mov ebp, espn| 0x080483e7 83ec18 sub esp, 0x18n| 0x080483ea 83e4f0 and esp, 0xfffffff0n| 0x080483ed b800000000 mov eax, 0n| 0x080483f2 83c00f add eax, 0xfn| 0x080483f5 83c00f add eax, 0xfn| 0x080483f8 c1e804 shr eax, 4n| 0x080483fb c1e004 shl eax, 4n| 0x080483fe 29c4 sub esp, eaxn| 0x08048400 c70424288504. mov dword [esp], str.IOLI_Crackme_Level_0x01_n ; [0x8048528:4]=0x494c4f49 ; "IOLI Crackme Level 0x01n"n| 0x08048407 e810ffffff call sym.imp.printf ; int printf(const char *format)n| 0x0804840c c70424418504. mov dword [esp], str.Password: ; [0x8048541:4]=0x73736150 ; "Password: "n| 0x08048413 e804ffffff call sym.imp.printf ; int printf(const char *format)n| 0x08048418 8d45fc lea eax, [local_4h]n| 0x0804841b 89442404 mov dword [local_4h_2], eaxn| 0x0804841f c704244c8504. mov dword [esp], 0x804854c ; [0x804854c:4]=0x49006425 ; "%d"n| 0x08048426 e8e1feffff call sym.imp.scanf ; int scanf(const char *format)n| 0x0804842b 817dfc9a1400. cmp dword [local_4h], 0x149a ; [0x149a:4]=0x2ec0804n| ,=< 0x08048432 740e je 0x8048442n| | 0x08048434 c704244f8504. mov dword [esp], str.Invalid_Password__n ; [0x804854f:4]=0x61766e49 ; "Invalid Password!n"n| | 0x0804843b e8dcfeffff call sym.imp.printf ; int printf(const char *format)n| ,==< 0x08048440 eb0c jmp 0x804844en| || ; JMP XREF from 0x08048432 (main)n| |`-> 0x08048442 c70424628504. mov dword [esp], str.Password_OK_:__n ; [0x8048562:4]=0x73736150 ; "Password OK :)n"n| | 0x08048449 e8cefeffff call sym.imp.printf ; int printf(const char *format)n| | ; JMP XREF from 0x08048440 (main)n| `--> 0x0804844e b800000000 mov eax, 0n| 0x08048453 c9 leaven 0x08048454 c3 retn

imp說明是import引用的符號 str說明是字元串

看到裡面有個cmp對比,後面的0x說明是16進位。使用r2進行轉碼

[0x080483e4]> ? 0x149an5274 0x149a 012232 5.2K 0000:049a 5274 "x9ax14" 0001010010011010 5274.0 5274.000000f 5274.000000n

輸入

./crackme0x01 nIOLI Crackme Level 0x01nPassword: 5274nPassword OK :)n

crackme0x02

首先和上面一樣的,進行反編譯操作

afln0x080482d4 1 23 sym._initn0x080482fc 1 6 sym.imp.__libc_start_mainn0x0804830c 1 6 sym.imp.scanfn0x0804831c 1 6 sym.imp.printfn0x08048330 1 33 entry0n0x08048354 3 33 fcn.08048354n0x08048380 6 47 sym.__do_global_dtors_auxn0x080483b0 4 50 sym.frame_dummyn0x080483e4 4 144 mainn0x08048480 4 99 sym.__libc_csu_initn0x080484f0 1 5 sym.__libc_csu_finin0x080484f5 1 4 sym.__i686.get_pc_thunk.bxn0x08048500 4 35 sym.__do_global_ctors_auxn0x08048524 1 26 sym._finin[0x08048330]> s miann[0x00000000]> s mainn[0x080483e4]> pdfn;-- main:n/ (fcn) main 144n| main ();n| ; var int local_ch @ ebp-0xcn| ; var int local_8h @ ebp-0x8n| ; var int local_4h @ ebp-0x4n| ; var int local_4h_2 @ esp+0x4n| ; DATA XREF from 0x08048347 (entry0)n| 0x080483e4 55 push ebpn| 0x080483e5 89e5 mov ebp, espn| 0x080483e7 83ec18 sub esp, 0x18n| 0x080483ea 83e4f0 and esp, 0xfffffff0n| 0x080483ed b800000000 mov eax, 0n| 0x080483f2 83c00f add eax, 0xfn| 0x080483f5 83c00f add eax, 0xfn| 0x080483f8 c1e804 shr eax, 4n| 0x080483fb c1e004 shl eax, 4n| 0x080483fe 29c4 sub esp, eaxn| 0x08048400 c70424488504. mov dword [esp], str.IOLI_Crackme_Level_0x02_n ; [0x8048548:4]=0x494c4f49 ; "IOLI Crackme Level 0x02n"n| 0x08048407 e810ffffff call sym.imp.printf ; int printf(const char *format)n| 0x0804840c c70424618504. mov dword [esp], str.Password: ; [0x8048561:4]=0x73736150 ; "Password: "n| 0x08048413 e804ffffff call sym.imp.printf ; int printf(const char *format)n| 0x08048418 8d45fc lea eax, [local_4h]n| 0x0804841b 89442404 mov dword [local_4h_2], eaxn| 0x0804841f c704246c8504. mov dword [esp], 0x804856c ; [0x804856c:4]=0x50006425 ; "%d"n| 0x08048426 e8e1feffff call sym.imp.scanf ; int scanf(const char *format)n| 0x0804842b c745f85a0000. mov dword [local_8h], 0x5a ; Zn| 0x08048432 c745f4ec0100. mov dword [local_ch], 0x1ecn| 0x08048439 8b55f4 mov edx, dword [local_ch]n| 0x0804843c 8d45f8 lea eax, [local_8h]n| 0x0804843f 0110 add dword [eax], edxn| 0x08048441 8b45f8 mov eax, dword [local_8h]n| 0x08048444 0faf45f8 imul eax, dword [local_8h]n| 0x08048448 8945f4 mov dword [local_ch], eaxn| 0x0804844b 8b45fc mov eax, dword [local_4h]n| 0x0804844e 3b45f4 cmp eax, dword [local_ch]n| ,=< 0x08048451 750e jne 0x8048461n| | 0x08048453 c704246f8504. mov dword [esp], str.Password_OK_:__n ; [0x804856f:4]=0x73736150 ; "Password OK :)n"n| | 0x0804845a e8bdfeffff call sym.imp.printf ; int printf(const char *format)n| ,==< 0x0804845f eb0c jmp 0x804846dn| || ; JMP XREF from 0x08048451 (main)n| |`-> 0x08048461 c704247f8504. mov dword [esp], str.Invalid_Password__n ; [0x804857f:4]=0x61766e49 ; "Invalid Password!n"n| | 0x08048468 e8affeffff call sym.imp.printf ; int printf(const char *format)n| | ; JMP XREF from 0x0804845f (main)n| `--> 0x0804846d b800000000 mov eax, 0n| 0x08048472 c9 leaven 0x08048473 c3 retn[0x080483e4]> ? 0x5an90 0x5a 0132 90 0000:005a 90 "Z" 01011010 90.0 90.000000f 90.000000n[0x080483e4]> ? 0x1ecn492 0x1ec 0754 492 0000:01ec 492 "xecx01" 0000000111101100 492.0 492.000000f 492.000000n

看這段代碼:

0x0804842b c745f85a0000. mov dword [local_8h], 0x5a ; Zn| 0x08048432 c745f4ec0100. mov dword [local_ch], 0x1ecn| 0x08048439 8b55f4 mov edx, dword [local_ch]n| 0x0804843c 8d45f8 lea eax, [local_8h]n| 0x0804843f 0110 add dword [eax], edxn| 0x08048441 8b45f8 mov eax, dword [local_8h]n| 0x08048444 0faf45f8 imul eax, dword [local_8h]n| 0x08048448 8945f4 mov dword [local_ch], eaxn| 0x0804844b 8b45fc mov eax, dword [local_4h]n

代碼為:

b = 90;nc = 492;nc = ((b + c) * (b + c));n

輸入:

./crackme0x02 nIOLI Crackme Level 0x02nPassword: 338724nPassword OK :)n

crackme0x03

r2 直接運行crackme0x03

反編譯進入main函數中

[0x08048498]> pdfn;-- main:n/ (fcn) sym.main 128n| sym.main ();n| ; var int local_ch @ ebp-0xcn| ; var int local_8h @ ebp-0x8n| ; var int local_4h @ ebp-0x4n| ; var int local_4h_2 @ esp+0x4n| ; DATA XREF from 0x08048377 (entry0)n| 0x08048498 55 push ebpn| 0x08048499 89e5 mov ebp, espn| 0x0804849b 83ec18 sub esp, 0x18n| 0x0804849e 83e4f0 and esp, 0xfffffff0n| 0x080484a1 b800000000 mov eax, 0n| 0x080484a6 83c00f add eax, 0xfn| 0x080484a9 83c00f add eax, 0xfn| 0x080484ac c1e804 shr eax, 4n| 0x080484af c1e004 shl eax, 4n| 0x080484b2 29c4 sub esp, eaxn| 0x080484b4 c70424108604. mov dword [esp], str.IOLI_Crackme_Level_0x03_n ; [0x8048610:4]=0x494c4f49 ; "IOLI Crackme Level 0x03n"n| 0x080484bb e890feffff call sym.imp.printf ; int printf(const char *format)n| 0x080484c0 c70424298604. mov dword [esp], str.Password: ; [0x8048629:4]=0x73736150 ; "Password: "n| 0x080484c7 e884feffff call sym.imp.printf ; int printf(const char *format)n| 0x080484cc 8d45fc lea eax, [local_4h]n| 0x080484cf 89442404 mov dword [local_4h_2], eaxn| 0x080484d3 c70424348604. mov dword [esp], 0x8048634 ; [0x8048634:4]=0x6425 ; "%d"n| 0x080484da e851feffff call sym.imp.scanf ; int scanf(const char *format)n| 0x080484df c745f85a0000. mov dword [local_8h], 0x5a ; Zn| 0x080484e6 c745f4ec0100. mov dword [local_ch], 0x1ecn| 0x080484ed 8b55f4 mov edx, dword [local_ch]n| 0x080484f0 8d45f8 lea eax, [local_8h]n| 0x080484f3 0110 add dword [eax], edxn| 0x080484f5 8b45f8 mov eax, dword [local_8h]n| 0x080484f8 0faf45f8 imul eax, dword [local_8h]n| 0x080484fc 8945f4 mov dword [local_ch], eaxn| 0x080484ff 8b45f4 mov eax, dword [local_ch]n| 0x08048502 89442404 mov dword [local_4h_2], eaxn| 0x08048506 8b45fc mov eax, dword [local_4h]n| 0x08048509 890424 mov dword [esp], eaxn| 0x0804850c e85dffffff call sym.testn| 0x08048511 b800000000 mov eax, 0n| 0x08048516 c9 leaven 0x08048517 c3 retn

主要看的命令信息

0x080484df c745f85a0000. mov dword [local_8h], 0x5a ; Zn| 0x080484e6 c745f4ec0100. mov dword [local_ch], 0x1ecn| 0x080484ed 8b55f4 mov edx, dword [local_ch]n| 0x080484f0 8d45f8 lea eax, [local_8h]n| 0x080484f3 0110 add dword [eax], edxn| 0x080484f5 8b45f8 mov eax, dword [local_8h]n| 0x080484f8 0faf45f8 imul eax, dword [local_8h]n| 0x080484fc 8945f4 mov dword [local_ch], eaxn| 0x080484ff 8b45f4 mov eax, dword [local_ch]n| 0x08048502 89442404 mov dword [local_4h_2], eaxn| 0x08048506 8b45fc mov eax, dword [local_4h]n| 0x08048509 890424 mov dword [esp], eaxn

解析這些命令可以知道

edx = 0x1ec #使用`? 0x1ec`查看可知是492neax -> ebp -0x8neax = (0x1ec+0x5a)=582neax = 582*582=n

關鍵得演算法就是這個

得到的數字輸入程序中

IOLI Crackme Level 0x03nPassword: 338724nPassword OK!!! :)n

程序裡面還有個加密演算法sym.shift,這個是個移位加密的演算法,有興趣的可以自己嘗試下解密


推薦閱讀:

如何優雅地做一個使用OS X的黑客?
看雪.TSRC 2017CTF秋季賽第三題 wp
閑扯ARM指令集一
新手到大神反編譯unity3d遊戲系列教程【一】
Android 有沒有逆向工程的工具? 效果如何?

TAG:逆向工程 |