算法分析:BUUCTF-2019全國賽的一道逆向題
1.對程序進(jìn)行查殼,發(fā)現(xiàn)是個(gè)無殼vc編譯的

?
2.運(yùn)行程序,查看程序運(yùn)行流程,在password中輸入12345678,按下Crack按鈕以后沒有任何提示程序結(jié)束運(yùn)行

3.依舊先讓od跑一遍,以前說過的這種通過用戶輸入然后再按下按鈕觸發(fā)事件的先對GetDlgItemTextA函數(shù)斷點(diǎn)看程序是否是用這個(gè)函數(shù)從輸入框獲取用戶輸入的

在輸入框輸入12345678按下Crack按鈕后成功在GetDlgItemTextA函數(shù)斷下,由于我們的斷點(diǎn)是GetDlgItemTextA函數(shù)的入口點(diǎn),屬于系統(tǒng)領(lǐng)空,所以我們直接往下找到離GetDlgItemTextA函數(shù)入口點(diǎn)最近的retn斷點(diǎn)跑完GetDlgItemTextA這個(gè)函數(shù)去查看按鈕的其他邏輯事件

4.查看按鈕其他邏輯事件

跑完GetDlgItemTextA函數(shù)后發(fā)現(xiàn)往下有一個(gè)ExitProcess的函數(shù),這讓我們聯(lián)想到了我們正常運(yùn)行程序時(shí)候輸入12345678程序結(jié)束運(yùn)行,那可以肯定這個(gè)函數(shù)就是在我們輸入12345678按下Crack按鈕觸發(fā)的,從這個(gè)函數(shù)往上看發(fā)現(xiàn)在這個(gè)函數(shù)之前有個(gè)jbe跳轉(zhuǎn),點(diǎn)擊一看,如果跳轉(zhuǎn)便是跳過這個(gè)ExitProcess的執(zhí)行,說明這個(gè)jbe時(shí)一個(gè)關(guān)鍵點(diǎn),那我們對jbe這個(gè)跳轉(zhuǎn)的條件 cmp eax,0x6進(jìn)行斷點(diǎn)分析

jbe的條件是對比eax的值是否小于等于0x6,如果滿足則就跳過退出程序函數(shù),我們一看eax的值便是我們輸入12345678的長度,那我們重新輸入六個(gè)數(shù)123456作為用戶輸入的值運(yùn)行到這里

果然,eax此時(shí)確實(shí)是用戶輸入的長度,而且jbe跳過了退出,ecx存入了我們輸入的123456,但是是以字符串形式存入(這里要注意,后面會(huì)用到)那我們繼續(xù)走跳過退出后的代碼

經(jīng)過這個(gè)函數(shù)后,eax的值變?yōu)榱?x1e240,我們在看這個(gè)call的參數(shù)只有一個(gè)ecx,那在這個(gè)call之前我們知道ecx的值是字符串‘’123456“的地址,那說明這個(gè)0x1e240和這個(gè)123456有關(guān)系,一個(gè)是字符串一個(gè)是十六進(jìn)制,這個(gè)我們就可以猜想是否這個(gè)0x1e240是”123456“轉(zhuǎn)換的十六進(jìn)制數(shù),那我們用代碼驗(yàn)證一下
#include
??? int main()
??? {
??????????? char num[6] = "123456";
??????????? int last = atol(num);
??????????? printf("%x",last);
??? }

果然,我們的猜想是正確的,那繼續(xù)往下走

這幾行代碼將eax的值賦值給了edx,而且edx還加1,此時(shí)還出現(xiàn)了一個(gè)對比jnz跳轉(zhuǎn),跳轉(zhuǎn)的條件是edx的值是否等于0x7b,不等于則跳轉(zhuǎn),我測試了一下跳轉(zhuǎn)后的流程是重復(fù)執(zhí)行獲取用戶輸入,所以我們?yōu)榱瞬唤Y(jié)束程序則要使得edx等于0x7b,也就是說需要eax+1 = 0x7b,我們剛才分析過eax是我們輸入字符串的轉(zhuǎn)16進(jìn)制數(shù),那我們此時(shí)可以得知eax=0x7b-1 = (字符轉(zhuǎn)十六進(jìn)制數(shù))用戶輸入,最后可以用代碼算出我們要輸入什么,這里要強(qiáng)調(diào)一個(gè)問題,從對GetDlgItemTextA斷點(diǎn)以來,我們輸入的變化情況:123456(整數(shù))->”123456“(字符串)->0x1e240(十六進(jìn)制數(shù)),其實(shí)我們輸入的就是經(jīng)歷了兩個(gè)函數(shù)itoa->atol;所以這里我們可以直接得知我們輸入要滿足其等于0x7b-1,所以就是數(shù)字122,那我們從新代開程序斷點(diǎn)在上圖這個(gè)cmp



此時(shí),下面又出現(xiàn)了三個(gè)接連的對比,分別是地址ss:[ebp-0x101]、ss:[ebp-0xFF]、ss:[ebp-0x100]的值分別和0x78、0x7a、0x79對比,這三個(gè)jnz經(jīng)過測試都是跳轉(zhuǎn)到重復(fù)執(zhí)行獲取用戶輸入和這一系列的判斷,那此時(shí)我們來分析這三個(gè)地址的特殊性,發(fā)現(xiàn)我們剛才輸入那三個(gè)數(shù)122的地址是ss:[ebp-0x108],第一個(gè)地址在122地址往后3個(gè)字節(jié),第二個(gè)地址在122地址往后1個(gè)字節(jié),第三個(gè)地址在122地址往后2個(gè)字節(jié),那這三個(gè)地址的值到底來自哪里呢?我們知道這個(gè)Crake的第一個(gè)要求便是用戶輸入的值小于等于6,說明我們可以輸入6個(gè)長度的任意字符,那剩下的這三個(gè)字節(jié)加上122的長度剛好是六個(gè)。那還不簡單?直接找出這三個(gè)不滿足jnz跳轉(zhuǎn)的值是多少就行了
條件:
ss:[ebp-0x101] =0x78 字符:z
ss:[ebp-0xFF] = 0x7a 字符:x
ss:[ebp-0x100] = 0x79 字符:y
按位置排序出來便是xyz,那我們重新打開輸入122xyz斷點(diǎn)最后一個(gè)jnz
5.運(yùn)行到這里看到了flag字符,估計(jì)接下來就是出現(xiàn)flag的時(shí)候了,繼續(xù)單步執(zhí)行到正確flag提示信息出現(xiàn)前是這些代碼,由于沒有什么算法存在,這些代碼知識用來拼接flag的所以就不分析了
? 004011E4???????????? . A1 A02F4200????? mov eax,dword ptr ds:[0x422FA0]????? ; flag
? 004011E9???????????? . 8985 F4FDFFFF???? mov dword ptr ss:[ebp-0x20C],eax
? 004011EF???????????? . 8A0D A42F4200???? mov cl,byte ptr ds:[0x422FA4]
? 004011F5???????????? . 888D F8FDFFFF???? mov byte ptr ss:[ebp-0x208],cl
? 004011FB???????????? . B9 3F000000????? mov ecx,0x3F
? 00401200???????????? . 33C0?????????? xor eax,eax
? 00401202???????????? . 8DBD F9FDFFFF???? lea edi,dword ptr ss:[ebp-0x207]
? 00401208???????????? . F3:AB????????? rep stos dword ptr es:[edi]
? 0040120A???????????? . 66:AB????????? stos word ptr es:[edi]
? 0040120C???????????? . AA??????????? stos byte ptr es:[edi]
? 0040120D???????????? . 6A 0A????????? push 0xA????????????????????? ; /Arg3 = 0000000A
? 0040120F???????????? . 8D95 F0FCFFFF???? lea edx,dword ptr ss:[ebp-0x310]????? ; |
? 00401215???????????? . 52??????????? push edx????????????????????? ; |Arg2 = 00000079
? 00401216???????????? . 8B85 F8FEFFFF ????mov eax,dword ptr ss:[ebp-0x108]????? ; |
? 0040121C???????????? . 50??????????? push eax????????????????????? ; |Arg1 = 00000078
? 0040121D???????????? . E8 9E290000????? call 1.00403BC0???????????????? ; \1.00403BC0
? 00401222???????????? . 83C4 0C? ???????add esp,0xC
? 00401225???????????? . 68 44204200????? push 1.00422044???????????????? ; {
? 0040122A???????????? . 8D8D F4FDFFFF???? lea ecx,dword ptr ss:[ebp-0x20C]
? 00401230???????????? . 51??????????? push ecx
? 00401231???????????? . E8 3A020000????? call 1.00401470
? 00401236???????????? . 83C4 08???????? add esp,0x8
? 00401239???????????? . 8D95 F0FCFFFF???? lea edx,dword ptr ss:[ebp-0x310]
? 0040123F???????????? . 52??????????? push edx
? 00401240???????????? . 8D85 F4FDFFFF???? lea eax,dword ptr ss:[ebp-0x20C]
? 00401246???????????? . 50??????????? push eax
? 00401247???????????? . E8 24020000????? call 1.00401470
? 0040124C???????????? . 83C4 08???????? add esp,0x8
? 0040124F???????????? . 68 40204200????? push 1.00422040???????????????? ; _
? 00401254???????????? . 8D8D F4FDFFFF???? lea ecx,dword ptr ss:[ebp-0x20C]
? 0040125A???????????? . 51??????????? push ecx
? 0040125B???????????? . E8 10020000????? call 1.00401470
? 00401260???????????? . 83C4 08???????? add esp,0x8
? 00401263????????? ???. 68 2C204200????? push 1.0042202C???????????????? ; Buff3r_0v3rf|0w
? 00401268???????????? . 8D95 F4FDFFFF???? lea edx,dword ptr ss:[ebp-0x20C]
? 0040126E???????????? . 52??????????? push edx
? 0040126F???????????? . E8 FC010000????? call 1.00401470
? 00401274???????????? . 83C4 08???????? add esp,0x8
? 00401277???????????? . 68 28204200????? push 1.00422028???????????????? ; }
? 0040127C???????????? . 8D85 F4FDFFFF???? lea eax,dword ptr ss:[ebp-0x20C]
? 00401282???????????? . 50??????????? push eax
? 00401283???????????? . E8 E8010000????? call 1.00401470
