bugku 好用的CE WriteUp

好用的CE

clip_image002

這題有好多種解法,我會一個個解釋。

只用OD

只用CE

CE+OD

下載文件

clip_image004

clip_image006

點兩下試試

clip_image008

無殼

clip_image010

1.只用OD

只用OD我只想出兩種辦法,雖然只是下斷點的方式不同,但也代表了不同的思路。

一、 第一種是最直接的也是最笨的,在搜索字符串裏的所有內容都下斷點,這裏幸好搜索的字符串不是很多,而且flag湊巧是直接存儲在內存裏的,所以可以使用。若沒這麼幸運的話就只能在提示的字符串 “點擊一萬次有flag” 處下斷點,一點點的往上翻代碼了。

clip_image012

二、 我們知道了這個程序使用VB寫的,且會彈出一個對話框,對話框在VB理常用的函數爲rtcMsgBox,可以用ODB的插件來自動下斷點,

clip_image014

只用OD第一種辦法:在每一處字符串下斷點,這裏我們就只在可疑字符串下斷點了

即第3、4、5、6、7行

clip_image012[1]

首先斷在了最後一條,

clip_image016

看起來是在初始化變量,F9繼續運行

clip_image004[1]

跳出對話框,單擊確定繼續程序

clip_image006[1]

點擊後觸發斷點,

clip_image018

clip_image020

這三個可疑的字符串在一起,但是其上並沒有大跳轉,甚至根本沒有跳轉,那最後一個可疑字符串就更可疑了,繼續F9運行程序,程序並沒有斷在最後一個字符串處,說明這個字符串很有可能就是達到條件(點擊一萬次)後纔會出現的字符串,

clip_image022

這個字符串上面還有一個大跳轉,那這個字符串就很有可能是flag了,或者flag相關的字符串,我們把這個大跳轉nop掉,看看會出現什麼

clip_image024

DeZmqMUhRcP8NgJgzLPdXa

這題最坑的地方也就是這個字符串就出現了,之前做這個題也是斷在這裏,直到最近出了Writeup才知道,這個看起來像base64的字符串其實是他的遠親,base58

我們都知道base64的範圍是 數字(10)+大小寫字母(26*2=52)+兩個特殊字符(+,/)

而base58是剔除了容易被人誤識別的數字0,L的小寫,i的大寫和o的大寫,還有兩個特殊字符(+,/)

clip_image026

得到flag

只用OD第二種方法,利用OD的插件,在rtcMsgBox下斷點,F9運行程序,被斷下

clip_image028

這個地方已經不屬於程序的領空了,這裏是VB調用的庫的領空,在這個位置我們在棧裏可以找到程序調用函數的地址,在其上回車以回到程序領空

clip_image030

clip_image032

然後我們就可以苦哈哈地慢慢往上翻代碼了,這個下斷點的方式適合在沒有明確的提示字符串的時候使用,在有提示字符串的時候還是用字符串來查找比較方便。

CE+OD

打開程序,CE附加程序,

clip_image034

這裏我們不知道這個變化的數字的類型,雖然看起來很像整型

clip_image008[1]

所以我們設置掃描類型爲未知的初始值,點擊首次掃描

clip_image036

然後點擊按鈕,變化一下數值

clip_image038

再用CE搜索變化的數值

clip_image040

點擊再次掃描

clip_image042

這樣太慢了,我們可以用變動的數值和未變動的數值切換來不斷搜索

最後剩了八個結果實在分辨不出來了

clip_image044

不過這就夠了,我們也不需要知道那麼細緻,隨便選一個,雙擊,拉到下面的界面裏,右鍵他選擇 找出是什麼改寫了這個地址

clip_image046

clip_image048

注意像這樣的,地址特別大的,一定不是程序的代碼,這個是程序調用的庫的地址

clip_image050

像這樣40打頭的纔是程序的代碼,具體要看程序的PE頭裏定義的基地址,一般爲400000。

然後我們就可以記住這個地址,用OD打開程序,到這個地址看看,CE也可以看,但是很多操作不方便

clip_image052

畢竟不是專門用來調試程序的應用。

我們用OD附加到進程上,

clip_image054

ctrl+g 到401D44看看

clip_image056

距離我們第一次找到的關鍵跳轉也很近,

clip_image058

這之間有大量的棕色的浮點數運算,而關鍵跳轉之後再無浮點運算,所以這可能就是算法部分,這次我們仔細分析下算法部分,

clip_image060

這裏可以說是算法部分最重要的四條代碼了,從0x4010A8存儲的10000就能看出來,在我解釋浮點助記符之前,我要先解釋一下浮點運算:

在包含浮點運算的處理器裏,有8個寄存器,分別是ST0-ST7,他們通過浮點助記符來進行浮點運算,他們的使用方法與棧很類似,存儲的順序從ST0開始到ST7,常用的浮點助記符有:

fld 相當於push

fstp 相當於pop

fadd 相當於add

fsub 相當於sub

fdiv 相當於div

fmul 相當於mul

fstsw 把狀態寄存器存入寄存器裏

fcomp 相當於cmp

再具體點的用法我會在用的時候解釋,現在在最開始的浮點運算處下斷點

clip_image062

因爲代碼跨度有點大,我就不一一截圖了,只把關鍵代碼寫下來

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

把狀態寄存器存入ax,周圍並沒有可以影響到狀態寄存器的代碼,所以忽略就行

fld qword ptr ds:[esi+0x34]

即ST0=[esi+0x34]

fdiv qword ptr ds:[0x4010B0]

即ST0/=200.0

fstp qword ptr ss:[esp]

即[esp]=ST0,這裏存儲的就是實際的點擊數了

fclex

查了一下是叫做浮點檢查錯誤清除,不會影響結果所以忽略

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

把狀態寄存器存入ax

test ah,0x40

比對狀態寄存器,

je 401e97

關鍵跳轉

然後怎麼改就看個人喜歡了,可以像上次一樣直接nop掉關鍵跳轉,也可以修改0x4010B0裏的值來達到點一次等於數次的效果,也可以直接修改0x4010A8裏的值,讓一萬次變成1次。flag處理部分不再贅述。

後來我查了一下,test ah,0x40 比對的是狀態寄存器的cf寄存器,即進位寄存器,所以他只會在從9999進位到10000時觸發,

只用CE:

運行程序,用CE附加上

由於我們已經知道了數值的類型爲雙浮點(雙浮點數佔八個字節,有效數字16位,之前的200.0可以數一下有效數字就知道了,即使不知道類型爲雙浮點也可以一個個試,通常數據存儲類型只有4字節,單浮點,雙浮點類型,偶爾也有單字節的布爾類型),我們設置掃描類型爲未知的初始值,數值類型爲雙浮點搜索,

clip_image064

然後用 變動的數值/未變動的數值切換搜索,很快就搜索到了一個很扎眼的數值,除了這個2200都是後面跟了很多個小數的雙浮點數,然後用2200/11得到增量200,

clip_image066

雙擊把他加入下面的界面,設置大小爲1999800

clip_image068

clip_image070

然後點擊程序的按鈕

clip_image072

就從11變成了100000,從而得到flag

當然,如果我們知道了增量爲200,也可以直接搜索200*X

clip_image074

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章