這題有好多種解法,我會一個個解釋。
只用OD
只用CE
CE+OD
下載文件
點(diǎn)兩下試試
無殼
1.只用OD
只用OD我只想出兩種辦法,雖然只是下斷點(diǎn)的方式不同,但也代表了不同的思路。
一、 第一種是最直接的也是最笨的,在搜索字符串里的所有內(nèi)容都下斷點(diǎn),這里幸好搜索的字符串不是很多,而且flag湊巧是直接存儲在內(nèi)存里的,所以可以使用。若沒這么幸運(yùn)的話就只能在提示的字符串 “點(diǎn)擊一萬次有flag” 處下斷點(diǎn),一點(diǎn)點(diǎn)的往上翻代碼了。
二、 我們知道了這個程序使用VB寫的,且會彈出一個對話框,對話框在VB理常用的函數(shù)為rtcMsgBox,可以用ODB的插件來自動下斷點(diǎn),
只用OD第一種辦法:在每一處字符串下斷點(diǎn),這里我們就只在可疑字符串下斷點(diǎn)了
即第3、4、5、6、7行
首先斷在了最后一條,
看起來是在初始化變量,F(xiàn)9繼續(xù)運(yùn)行
跳出對話框,單擊確定繼續(xù)程序
點(diǎn)擊后觸發(fā)斷點(diǎn),
這三個可疑的字符串在一起,但是其上并沒有大跳轉(zhuǎn),甚至根本沒有跳轉(zhuǎn),那最后一個可疑字符串就更可疑了,繼續(xù)F9運(yùn)行程序,程序并沒有斷在最后一個字符串處,說明這個字符串很有可能就是達(dá)到條件(點(diǎn)擊一萬次)后才會出現(xiàn)的字符串,
這個字符串上面還有一個大跳轉(zhuǎn),那這個字符串就很有可能是flag了,或者flag相關(guān)的字符串,我們把這個大跳轉(zhuǎn)nop掉,看看會出現(xiàn)什么
DeZmqMUhRcP8NgJgzLPdXa
這題最坑的地方也就是這個字符串就出現(xiàn)了,之前做這個題也是斷在這里,直到最近出了Writeup才知道,這個看起來像base64的字符串其實(shí)是他的遠(yuǎn)親,base58
我們都知道base64的范圍是 ?數(shù)字(10)+大小寫字母(26*2=52)+兩個特殊字符(+,/)
而base58是剔除了容易被人誤識別的數(shù)字0,L的小寫,i的大寫和o的大寫,還有兩個特殊字符(+,/)
得到flag
只用OD第二種方法,利用OD的插件,在rtcMsgBox下斷點(diǎn),F(xiàn)9運(yùn)行程序,被斷下
這個地方已經(jīng)不屬于程序的領(lǐng)空了,這里是VB調(diào)用的庫的領(lǐng)空,在這個位置我們在棧里可以找到程序調(diào)用函數(shù)的地址,在其上回車以回到程序領(lǐng)空
然后我們就可以苦哈哈地慢慢往上翻代碼了,這個下斷點(diǎn)的方式適合在沒有明確的提示字符串的時候使用,在有提示字符串的時候還是用字符串來查找比較方便。
CE+OD
打開程序,CE附加程序,
這里我們不知道這個變化的數(shù)字的類型,雖然看起來很像整型
所以我們設(shè)置掃描類型為未知的初始值,點(diǎn)擊首次掃描
然后點(diǎn)擊按鈕,變化一下數(shù)值
再用CE搜索變化的數(shù)值
點(diǎn)擊再次掃描
這樣太慢了,我們可以用變動的數(shù)值和未變動的數(shù)值切換來不斷搜索
最后剩了八個結(jié)果實(shí)在分辨不出來了
不過這就夠了,我們也不需要知道那么細(xì)致,隨便選一個,雙擊,拉到下面的界面里,右鍵他選擇 ?找出是什么改寫了這個地址
注意像這樣的,地址特別大的,一定不是程序的代碼,這個是程序調(diào)用的庫的地址
像這樣40打頭的才是程序的代碼,具體要看程序的PE頭里定義的基地址,一般為400000。
然后我們就可以記住這個地址,用OD打開程序,到這個地址看看,CE也可以看,但是很多操作不方便
畢竟不是專門用來調(diào)試程序的應(yīng)用。
我們用OD附加到進(jìn)程上,
ctrl+g 到401D44看看
距離我們第一次找到的關(guān)鍵跳轉(zhuǎn)也很近,
這之間有大量的棕色的浮點(diǎn)數(shù)運(yùn)算,而關(guān)鍵跳轉(zhuǎn)之后再無浮點(diǎn)運(yùn)算,所以這可能就是算法部分,這次我們仔細(xì)分析下算法部分,
這里可以說是算法部分最重要的四條代碼了,從0x4010A8存儲的10000就能看出來,在我解釋浮點(diǎn)助記符之前,我要先解釋一下浮點(diǎn)運(yùn)算:
在包含浮點(diǎn)運(yùn)算的處理器里,有8個寄存器,分別是ST0-ST7,他們通過浮點(diǎn)助記符來進(jìn)行浮點(diǎn)運(yùn)算,他們的使用方法與棧很類似,存儲的順序從ST0開始到ST7,常用的浮點(diǎn)助記符有:
fld 相當(dāng)于push
fstp 相當(dāng)于pop
fadd 相當(dāng)于add
fsub 相當(dāng)于sub
fdiv 相當(dāng)于div
fmul 相當(dāng)于mul
fstsw 把狀態(tài)寄存器存入寄存器里
fcomp 相當(dāng)于cmp
再具體點(diǎn)的用法我會在用的時候解釋,現(xiàn)在在最開始的浮點(diǎn)運(yùn)算處下斷點(diǎn)
因?yàn)榇a跨度有點(diǎn)大,我就不一一截圖了,只把關(guān)鍵代碼寫下來
fld qword ptr ds:[esi+0x34]
把從[esi+0x34]存入ST0
fadd qword ptr ds:[0x4010B0]
0x4010B0是200.0,即ST0+=200.0
fstp qword ptr ds:[esi+0x34]
即[esi+0x34] = ST0
fstsw ax
把狀態(tài)寄存器存入ax,周圍并沒有可以影響到狀態(tài)寄存器的代碼,所以忽略就行
fld qword ptr ds:[esi+0x34]
即ST0=[esi+0x34]
fdiv qword ptr ds:[0x4010B0]
即ST0/=200.0
fstp qword ptr ss:[esp]
即[esp]=ST0,這里存儲的就是實(shí)際的點(diǎn)擊數(shù)了
fclex
查了一下是叫做浮點(diǎn)檢查錯誤清除,不會影響結(jié)果所以忽略
fld qword ptr ds:[esi+0x34]
即ST0=[esi+0x34],
fdiv qword ptr ds:[0x4010B0]
即ST0/=200.0
fcomp qword ptr ds:[0x4010A8]
即ST0與10000比較
fstsw ax
把狀態(tài)寄存器存入ax
test ah,0x40
比對狀態(tài)寄存器,
je 401e97
關(guān)鍵跳轉(zhuǎn)
然后怎么改就看個人喜歡了,可以像上次一樣直接nop掉關(guān)鍵跳轉(zhuǎn),也可以修改0x4010B0里的值來達(dá)到點(diǎn)一次等于數(shù)次的效果,也可以直接修改0x4010A8里的值,讓一萬次變成1次。flag處理部分不再贅述。
后來我查了一下,test ah,0x40 比對的是狀態(tài)寄存器的cf寄存器,即進(jìn)位寄存器,所以他只會在從9999進(jìn)位到10000時觸發(fā),
只用CE:
運(yùn)行程序,用CE附加上
由于我們已經(jīng)知道了數(shù)值的類型為雙浮點(diǎn)(雙浮點(diǎn)數(shù)占八個字節(jié),有效數(shù)字16位,之前的200.0可以數(shù)一下有效數(shù)字就知道了,即使不知道類型為雙浮點(diǎn)也可以一個個試,通常數(shù)據(jù)存儲類型只有4字節(jié),單浮點(diǎn),雙浮點(diǎn)類型,偶爾也有單字節(jié)的布爾類型),我們設(shè)置掃描類型為未知的初始值,數(shù)值類型為雙浮點(diǎn)搜索,
然后用 變動的數(shù)值/未變動的數(shù)值切換搜索,很快就搜索到了一個很扎眼的數(shù)值,除了這個2200都是后面跟了很多個小數(shù)的雙浮點(diǎn)數(shù),然后用2200/11得到增量200,
雙擊把他加入下面的界面,設(shè)置大小為1999800
然后點(diǎn)擊程序的按鈕
就從11變成了100000,從而得到flag
當(dāng)然,如果我們知道了增量為200,也可以直接搜索200*X
另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)cdcxhl.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。