安全測試之探索windows遊戲掃雷
作者:京東工業 宛煜昕
掃雷遊戲相信很多人都從小玩過,在那個電腦遊戲並不多的時代,掃雷成為玩的熱度蠻高的一款遊戲之一,然而就在有一次,接觸到了一次不尋常的掃雷過程,使得後來我也有了這個衝動,也來做一次。通過動態調試,逆向和C來寫一個掃雷輔助工具從而提高逆向與編碼技能。
動態調試(分析)
首先進行掃雷程序的動態調試(分析):
打開OD(ollydebug工具),把掃雷拖放到OD中,F9運行;ctrl+G輸入要跟隨的表達式,輸入rand,點擊【確定】,跳轉到該函數調用處,F2設置斷點,此次是想通過API rand函數來找尋突破口。在掃雷窗口的雷區中任意點擊一個位置(圖片中出現2的位置),再點擊還原(【笑臉】按鈕-),如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-47ab6wPcUZdhgd9TD.png)
此時OD會在剛設置的rand處的斷點斷下來,如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-490A49q3jbUNLkmLgO.png)
通過找到隨機函數rand,下面進行棧回溯,回到上級函數中,來找到push(壓入棧)的參數,也就是説隨機生成函數(rand)是隨機生成的高,寬,雷數。點擊K(調用堆棧),彈出K調用堆棧窗口,查看堆棧窗口信息,找到返回地址,雙擊K調用堆棧窗口中的返回地址,返回到上一層,此過程稱為棧回溯。仔細觀察下圖的堆棧信息010036D2(返回地址)。
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-50LO6aDIJtkWezkYY.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-50CXUOKb7o6YbGsIi.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-50fP6s8MqIFl0jl30i.png)
單步F8,觀察寄存器,數據窗口和堆棧窗口變化,dword ptr ss:[esp+0x4]或dword ptr ds:[XXX]數據窗口跟蹤數值(000DFC44值是09),如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-53Ml10LJjgwMuO53pds.png)
返回到上層函數後,分析這裏面的指令,得知剛才隨機rand生成的寬(09),如下圖,注意觀察地址010036C7。
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-56pz76aHK6z3FRZGd.png)
首先從這個函數返回的結果着手分析eax,單步後,可以看到往堆棧中(地址010036D2)壓入了一個數字09,如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-57PnwLZmces229LTh9.png)
通過以上分析,基本可以猜測得到周邊的隨機函數rand生成是高,雷數。可以試着改變掃雷設置(自定義雷區),如下圖,來準確定位rand函數及傳參,點擊【確定】,再點擊【還原(笑臉-)】按鈕。
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-58rhW3n3KQpwVcGbv.png)
觀察OD,如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-58GoGikdkIuypXRGE.png)
發現push 0C(000DFC84值為0C),可以確定這個rand函數push 0C就是雷區的高度。同時在內存區域也能明確看到一個大致的雷區圖形,通過以上方法,大致可以猜測0x80就是雷。或者與IDA共同分析,通過靜態分析,可以更直觀的看到程序邏輯。得到如下數據:基地址,雷數等信息,如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-58mYcPRvHGhwXFBct.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-58ggDSdld0bxACAVi.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-589dtb722SwlMqhRnI.png)
以上代碼大概意思是先設置了全局寬0x09,高0x0C,雷數0x0A的變量,通過判斷兩層循環,隨機生成了寬和高。得地圖基地址:0x01005340。通過分析下圖得知無雷是0x0F,有雷是0x8F,牆壁是0x10。
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-59IsS3YZWpU0GlQO9.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-10-59pXxa59ZnBJB0DOLL.png)
通過寬,高的地址,打印出掃雷區域和雷數,並可以更直觀的區分邊牆,雷。
下面開始要想如何標記雷了,通過假設WinProc(通過棧回溯到消息回調函數)中看到有關GetDC函數,大致猜測會用到Bitblt,在OD中ctrl+g輸入要跟隨的表達式,錄入“BitBlt”,按F2設置斷點,點擊掃雷區域任意一個位置,OD會斷在BitBlt位置。
在BitBlt中還有一個BitBlt函數,初步判斷覺得是用雙緩衝方式繪圖,
BitBlt(hDestDC,//目的DC XDest, // 目的x座標 YDest, // 目的y座標 10, // 10, // 重繪區域的高和寬 hSrcDC, // 源DC 0, 0, SRCCOPY);// 指定操作方式計算雷的座標(點擊第一個掃雷的方塊,查看座標),需要注意邊牆,如下圖:
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-008cLSQRhyPC22nbko.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-00g6dZZXZOXjU9tAq.png)
減去邊牆的值:
-0x04=0x0C(12)-0x10(16)
0x27=0x37(55)-0x10(16)
得到座標公式:x(XDest:12)=1*0x10(16)-0x04(4),y(YDest:55)=1*0x10(16)+0x27(39)。
代碼編寫
通過以上大致的分析,可進行代碼的編寫了,
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-0022Uzn0kxxrAZdEAK.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-00Sx8dO7yLyshsEXK.png)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-00yThjcDI0VcYxCEK.png)
成果
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-01RciSVe1pn3NNBTP.png)
輸入3landmine位置,獲取出landmine(10牆壁,8Flandmine,0F無雷)
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-02R22ZG6m7ko8rZ7Lb.png)
輸入2自動掃雷,標記雷並開出地圖
![](http://s3.cn-north-1.jdcloud-oss.com/shendengbucket1/2023-03-22-11-02ELyWP11gOpWX22ZPH.png)
通過這個小項目,首先加強了對軟件的一種逆向思維,如:看到這一種面板,大概猜到是用數組來實現的,其次雷的佈局是隨機生成的,然後通過動態調試可以瞭解實現方法(開發者的一種實現思路),可找到關鍵的基地址,幾種狀態(無雷,有雷,牆壁),最後編碼階段可以理解內存的操作,幾個重要的API,FindWindow獲取句柄,OpenProcess打開句柄,ReadProcessMemory讀取內存信息,PostMessage異步消息模式,CloseHandle關閉句柄。其中有一些分析有誤或不到位的地方還請拍磚。多逆向,分析代碼有很多幫助,不僅可以拓寬自己編程與測試的思維及水平,還能發現,開發及利用程序中的漏洞或給程序打補丁等。希望小夥伴們在這條任重而道遠的路上加油,互勉。
- 應用健康度隱患刨析解決系列之數據庫時區設置
- 對於Vue3和Ts的心得和思考
- 一文詳解擴散模型:DDPM
- zookeeper的Leader選舉源碼解析
- 一文帶你搞懂如何優化慢SQL
- 京東金融Android瘦身探索與實踐
- 微前端框架single-spa子應用加載解析
- cookie時效無限延長方案
- 聊聊前端性能指標那些事兒
- Spring竟然可以創建“重複”名稱的bean?—一次項目中存在多個bean名稱重複問題的排查
- 京東金融Android瘦身探索與實踐
- Spring源碼核心剖析
- 深入淺出RPC服務 | 不同層的網絡協議
- 安全測試之探索windows遊戲掃雷
- 關於數據庫分庫分表的一點想法
- 對於Vue3和Ts的心得和思考
- Bitmap、RoaringBitmap原理分析
- 京東小程序CI工具實踐
- 測試用例設計指南
- 當你對 redis 説你中意的女孩是 Mia