逆向扫雷笔记
??? 好吧我承認放暑假我懶了。。。有一個多月沒更新了。前幾天看到久違的“紙牌”,想到了搞一下掃雷。其實三天前我就搞定了,但是緊接著我就往學校趕了,之后又感冒發燒拖到現在。現在我的體溫還沒有降下去,故后面的語言組織可能有些混亂。
??? 之所以選擇了掃雷首先是因為這是一個SDK編寫程序,結構清晰、明了,可以很快的找到想要找的函數,而且游戲的運行模式也比較簡單,就是在點下去的時候生 成一個“雷表”,之后獲取鼠標的消息,根據雷表的信息和鼠標的消息來決定調用的函數。并且,分析一個SDK程序的匯編代碼可以幫助我更好的理解 Windows程序運行的過程。
??? 先看看程序運行的方式。運行掃雷,在下面按下鼠標左鍵只會使格子變成凹陷狀,不會發生任何事。當鼠標左鍵彈起時,就會翻開相應格子。按下鼠標右鍵時會在相應格子出插上旗子。知道這些就足夠了。
??? 好了,知道了這些,可以開始動手了。首先想到的就是下消息斷點。用OD載入掃雷,F9運行,用Spy++來獲取窗口句柄,點上面的“W”看到相應句柄,右鍵下消息斷點202 WM_LBOTTOMUP,結果彈出了這個對話框。。。
??? 看來是不能直接下消息斷點了。重新載入,停在這兒
01003E21?>?$??6A?70?????????push????7001003E23???.??68?90130001???push????01001390
01003E28???.??E8?DF010000???call????0100400C
01003E2D???.??33DB?????? xor???? ebx,?ebx
01003E2F???.??53??????? push????ebx??????????????????? ;?/pModule?=>?NULL
01003E30???.??8B3D?8C100001? mov?????edi,?dword?ptr?[<&KERNEL32.GetMo>??????????? ;?|kernel32.GetModuleHandleA
01003E36???.??FFD7?????? call????edi??????????????????? ;?\GetModuleHandleA
01003E38???.??66:8138?4D5A? cmp?????word?ptr?[eax],?5A4D
01003E3D???.??75?1F????? jnz?????short?01003E5E
??? 沒什么用往下拉看到這兒
01003F86???>?\6A?0A?????????push????0A01003F88???.??58????????????pop?????eax
01003F89???>??50????????????push????eax
01003F8A???.??56????????????push????esi
01003F8B???.??53????????????push????ebx
01003F8C???.??53????????????push????ebx
01003F8D???.??FFD7??????????call????edi
01003F8F???.??50????????????push????eax?????????????? ? ?? ;?|Arg1
01003F90???.??E8?5BE2FFFF????? call????010021F0????????????????? ;?\winmine.010021F0
??? 在01003F90???.??E8?5BE2FFFF???call????010021F0??? ;?\winmine.010021F0???? 處跟進去。期間有個小插曲,我用筆記本可以順利的F4到那兒,但是用臺式機就會在01003F17???.??FF15?8C110001?call????dword?ptr?[<&msvcrt.__getmainarg>;??msvcrt.__getmainargs (好像)進入死循環。全程跟蹤后發現進入了異常處理,然后返回的程序開始出,反復循環。但是用臺式機的虛擬機卻 又可以正常F4。至今不知為什么,希望有高手看到可以給予一點指示。小弟跪謝。后來注意到臺式機載入后可以F9運行,于是嘗試在01003F90???.??E8?5BE2FFFF???call????010021F0?? ;?\winmine.010021F0 處下斷點,果然可以正常斷下來。
??? 跟進去一看就能發現是我們所熟悉的WinMain函數。往下拉找到窗口注冊函數,因為我們要找的是消息處理函數,窗口注冊函數調用了WNDCLASS結構的指針,而消息處理函數是WNDCLASS結果的成員。我們看到
0100228B??|.??50????????????push????eax??????????????????? ;?/pWndClass0100228C??|.??897D?D4???????mov?????dword?ptr?[ebp-2C],?edi??????????;?|
0100228F??|.??8975?D8???????mov?????dword?ptr?[ebp-28],?esi??????????;?|
01002292??|.??FF15?CC100001?call????dword?ptr?[<&USER32.RegisterClas>;?\RegisterClassW
??? 得知WNDCLASS地址在eax里。獲取eax內容得知WNDCLASS地址為0006FE98。因為消息處理函數的地址是WNDCLASS結構的第二 個成員所以db 0006FE98 + 4h,可以看到0006FE9C??C9?1B?00?01?00?00?00?00????? ?......
??? 所以消息處理函數的地址為01001BC9。轉到01001BC9,這就是我們的消息處理函數了~
??? 接下來找到我們需要的API 202 WM_LBUTTONUP和204 WM_RBUTTONDOWN
01001FDF??|>?\33FF??????????xor?????edi,?edi????? ;??Cases?202?(WM_LBUTTONUP),205?(WM_RBUTTONUP),208?(WM_MBUTTONUP)?of?switch?01001F5F
0100200F??|>?\393D?48510001?cmp?????dword?ptr?[1005148],?edi????? ;??Case?204?(WM_RBUTTONDOWN)?of?switch?01001F5F 然后
01001FDF??|>?\33FF??????????xor?????edi,?edi?????????????????????????;??Cases?202?(WM_LBUTTONUP),205?(WM_RBUTTONUP),208?(WM_MBUTTONUP)?of?switch?01001F5F
01001FE1??|.??393D?40510001?cmp?????dword?ptr?[1005140],?edi
01001FE7??|.??0F84?BC010000?je??????010021A9
01001FED??|>??893D?40510001?mov?????dword?ptr?[1005140],?edi
01001FF3??|.??FF15?D8100001?call????dword?ptr?[<&USER32.ReleaseCaptu>;?[ReleaseCapture
01001FF9??|.??841D?00500001?test????byte?ptr?[1005000],?bl
01001FFF??|.??0F84?B6000000?je??????010020BB
01002005??|.??E8?D7170000???call????010037E1 而左鍵彈起的執行函數就是01002005??|.??E8?D7170000???call????010037E1 ,跟進去。之后反復跟蹤,發現函數
010038B1??|.??E8?5CFCFFFF???call????01003512 是無論炸死與否都調用的函數。跟進去反復跟蹤和F9,發現炸死時使用了跳轉
01003536??|.?/75?50?????????jnz?????short?01003588??? 接下來就是改變跳轉位置讓其不調用炸死函數。一開始我然他調到一個什么都不做返回的地方(主要堆棧平衡),運行后發現的卻炸不死了,但是按過的雷看不出來,效果不好于是選擇的跳到插旗函數。
0100200F??|>?\393D?48510001?cmp?????dword?ptr?[1005148],?edi?????????;??Case?204?(WM_RBUTTONDOWN)?of?switch?01001F5F01002015??|.^?0F85?69FFFFFF?jnz?????01001F84
0100201B??|.??841D?00500001?test????byte?ptr?[1005000],?bl
01002021??|.??0F84?82010000?je??????010021A9
01002027??|.??393D?40510001?cmp?????dword?ptr?[1005140],?edi
0100202D??|.??74?27?????????je??????short?01002056
0100202F??|.??6A?FD?????????push????-3???????????????? ;?/Arg2?=?FFFFFFFD
01002031??|.??6A?FD?????????push????-3???????????????? ;?|Arg1?=?FFFFFFFD
01002033??|.??E8?9C110000???call????010031D4???????????????? ;?\winmine.010031D4
01002038??|.??FF75?14???????push????dword?ptr?[ebp+14]???????? ;?/lParam
0100203B??|.??891D?44510001?mov?????dword?ptr?[1005144],?ebx??????? ;?|
??? 反復跟蹤后發現一定會使用跳轉01002059??|.?/0F84?09010000?je??????01002168
??? 跳轉到
01002168??|>?\393D?4C510001?cmp?????dword?ptr?[100514C],?edi0100216E??|.^?0F85?EAFAFFFF?jnz?????01001C5E
01002174??|.??8B45?14???????mov?????eax,?dword?ptr?[ebp+14]
01002177??|.??C1E8?10???????shr?????eax,?10
0100217A??|.??83E8?27???????sub?????eax,?27
0100217D??|.??C1F8?04???????sar?????eax,?4
01002180??|.??50????????????push????eax
01002181??|.??0FB745?14?????movzx???eax,?word?ptr?[ebp+14]
01002185??|.??83C0?04???????add?????eax,?4
01002188??|.??C1F8?04???????sar?????eax,?4
0100218B??|.??50????????????push????eax
0100218C??|.??E8?BE150000???call????0100374F
??? 那么
01002174??|.??8B45?14???????mov?????eax,?dword?ptr?[ebp+14]01002177??|.??C1E8?10???????shr?????eax,?10
0100217A??|.??83E8?27???????sub?????eax,?27
0100217D??|.??C1F8?04???????sar?????eax,?4
01002180??|.??50????????????push????eax
01002181??|.??0FB745?14?????movzx???eax,?word?ptr?[ebp+14]
01002185??|.??83C0?04???????add?????eax,?4
01002188??|.??C1F8?04???????sar?????eax,?4
0100218B??|.??50????????????push????eax
0100218C??|.??E8?BE150000???call????0100374F
??? 就是調用插旗函數的過程。然后把前面找到的跳轉01003536??|.?/75?50??? jnz??? short?01003588 更改成跳到一個空的地方然后平衡堆棧弄掉堆棧里多余的東西(我當時腦子發昏pop了8次,其實只要加ebp就好了)。然后jmp到 01002174??|.??8B45?14? 、mov? 、eax,?dword?ptr?[ebp+14] 保存。收工。
??? 接下來打開那個改過的掃雷后只需要一陣狂點可以創造記錄哦(原則上不贊成)~
轉載于:https://www.cnblogs.com/Xelloss/archive/2009/08/30/1637149.html
總結
- 上一篇: Swift 在淘宝商品评价的技术重构与实
- 下一篇: 极客观察:利用人性弱点的互联网服务