網路遊戲逆向分析-4-分析喊話call參數來源
網路遊戲逆向分析-4-分析喊話call參數來源
好久沒更新了,去實習去了,大家見諒一下。
前面找到了喊話功能call函數,然後分析了它的參數有五個,分別的四個push的和一個ecx:
第一次
edx = 0
ebx = 0
ecx = 7E205ABC //字元串的首地址
edx = 5ABEB800
ecx = 2747D108
第二次:
edx = 0
ebx = 0
ecx = 2747D108
edx = 5ABEB800
ecx = 2747D108
通用指令:
push 0 //第一個push edx對應的edx暫存器始終為0
push 0 //第二個push ebx,對應的ebx暫存器始終為0
push ecx //字元串的首地址
push 5ABEB800 //edx的值
mov ecx,2747D108
需要找到ecx和edx的值的來源
很明顯只需要分析到ecx和edx的來源就可以完全利用該函數了。
找ecx基址
這裡的ecx是從eax來的,然而eax往上只有一條mov eax,dword ptr ss:[esp+40]採用賦值語句,而我在打斷點給這裡之後,發現這裡的 ss:[esp+40] != 2747D108,並不和我們要的值相等,所以肯定是後面有函數把它改了,通過單步調試發現是中間的這個函數修改了eax:
進入該函數查看是一個jmp指令,再進入jmp指令查看:
就很明顯得可以看到基址了 eax== ds:[ds:[1595EF0] +38]
找edx(foo版本)
這個相當麻煩,首先還是先往上找,查看修改edx的內容:
這裡可以看到的是利用了esp暫存器,牽扯到esp暫存器就比較麻煩了,因為如果有函數調用肯定會修改esp暫存器的,不像之前那麼好找了。
我在嘗試了一些列的辦法後,決定採用偏移地址的辦法,也就是剛進入函數的時候的esp和到了該指令的esp+40的地址,首先給函數入口點和該指令分別打上斷點:
然後查看函數首指令的esp:
然後查看跑到了指令之後對應的esp+40的地址:
可以非常明顯的發現,兩個值就差了4個地址,而且在該函數該地址對應的值沒有改變過,所以在這個函數裡面找沒意義,需要往上找。
然後給外部函數打個斷點:
發現它其實就是棧頂的內容,調用call指令後會壓入一個返回地址,所以偏移了一下。
然後往該函數上看,就可以知道其實這個值就是我們找的喊話函數的一個外部函數的調用參數,而且這個外部函數也是一個thiscall:
eax==喊話call裡面的edx。
然後分析這裡的eax就好了。
這裡的最近一個指令又是和esp有關的:
mov eax,dword ptr ss:[esp+10]
所以就先把對應的地址記下來,然後給該函數整體的首部打一個斷點來觀察該地址如何被修改:
這裡呢,我發現了一個簡答的辦法,直接給該地址下一個硬體訪問斷點就好看,前面是我sb了。
發現,它在這裡是直接被bl修改了後四位,改成了5ABEB800,在該指令之前它的值為:5ABEB858,就修改了最後一個位元組 。該指令前的內容是xor bl,bl把bl清零了,然後再故意賦值過來的,看來是刻意而為之。
通過對這個大函數整體分析,可以看出來這個應該是一個完整的喊話函數call,先判斷你喊話是在那個分組,如果是組隊,你有沒有隊伍,然後還有判斷說話的cd是否夠。
我們之前一直採用的是普通的喊話,所以應該就在修改的時候前面是條件判斷判斷你是什麼分組,還有判斷你的cd,然後再調用mov byte ptr ss:[esp+10],bl來分到普通喊話裡面,然後調用。
但是其實這裡又浪費時間了,因為這個函數我是分析得沒錯,肯定是來比較喊話的分類還有CD看能不能發,但是這裡只有這一條指令改變了5ABEB858,所以就往上找5ABEB858這個值,因為5ABEB858->5ABEB800值所以往上找5ABEB858的來源。
所以又往上找一層函數:
這裡很明顯可以看到入棧了一個speak函數,繼續往上找一個函數call,看看到底誰修改了這個地址0019DAD8的內容為:5ABEB858
這個函數不對勁了,除了說話其它指令如移動這些也可以斷下來,而且0019DAD8這個地址的內容修改了,所以這裡感覺可以找到我們要的東西。我們給他改成一個條件斷點,來滿足0019DAD8的內容為:5ABEB858這樣,就可以只在喊話的時候斷下來了。
這裡其實也有不對了,當你點進對話框的時候就會被修改為5ABEB858這個值了,所以這裡應該是來確定是否是對話框,然後我們在後面的應該就是判斷能否正確發出。
這裡的整個函數沒看出有啥思路:
但是其實已經告訴我們很多資訊了。
所以我覺得再往上找一層:
條件斷點還是成功了,還是這個值,我真是服了。
再往上找:
這個函數體里也沒有看到有修改的,就又找上一層函數:
現在的情況就是你輸入和修改文本框就會斷下來,不僅僅是輸出。
但是還是沒有,又往上:
還是沒有,再往上:
但是這裡就出問題了,給第九層打了條件斷點,但是卻跳過了,停在了第八層,感覺要解決了。
所以這裡就專註來調試,第九層裡面的內容:
給第九層開始打一個斷點來觀察是哪裡修改了0019DAD8這個地址的內容:
但是不能這樣做,因為這個函數很多地方都會調用如果斷下來就會一直斷下來,根本不能確定是喊話的時候停下來的,所以在我觀察了所有的彙編指令後,我發現沒有一個是直接有基質然後賦值的,基本上都是和暫存器打交道,於是我決定給這裡面的每個函數調用完之後打條件斷點來判斷是不是這個函數修改的內容。
停在了這個啊,然後給前面這個call eax打一個條件,然後破案了,就是這個call eax裡面修改了ss:[0019DAD8] = 5ABEB858
這個屬實就把我難到了。
找edx(正確版本)
其實說前面是找到了的,但是我自己傻逼了。
首先:
如果看到有esp+某個偏移作為媒介調用很有可能是兩種情況:
1:傳給函數的參數
2:函數的局部變數
當然你想怎麼逆你自己看著來。
其實前面:
這裡的mov byte ptr ss:[esp+10],bl是已經找到了的。
太過於糾結為四個位元組了,其實這裡就是一個byte來確定,而且確定的就是發言的類型,為0就是普通發言。害難頂。
然後用程式碼注射器試一下:
push 0 //第一個push edx對應的edx暫存器始終為0
push 0 //第二個push ebx,對應的ebx暫存器始終為0
push ecx //字元串的首地址
push 0 //edx的值
mov ecx,2747D108 //這個是對象首地址,this地址
完全沒問題。
白忙活幾小時了。