閑來無事胡寫些東西留給自己以後看,沒有技術含量,想笑的人勞駕,飄過吧!
周末在家宅了2天很是無聊,下午把以前玩過的一個網遊拿出來調試,用OD挂上遊戲,不一會彈出來一個MessageBox說,什麼網警檢測到非法調試,弄的還挺吓人的,因為之前開着抓包工具,看了一下沒有往發發送什麼可疑資料。看來真的是吓人的,呵呵!
以前調試的時候都很順利沒遇到過什麼情況,是以懷疑這公司反外挂技術獲過獎是塗有虛名,真的勾起我的好奇了。因為咱這技術也不太好,小菜一個,是以還是懷疑自己的能力啊,姑且試試吧......
用OD重加載遊戲運作,在MessageBoxA上下斷點,程式運作在斷點停下,确實是那條赫人的資訊
0C71A4FD /. 55 push ebp
0C71A4FE |. 8BEC mov ebp, esp
0C71A500 |. 51 push ecx
0C71A501 |. C745 FC 8C227>mov dword ptr ss:[ebp-4], 0>
0C71A508 >|. 6A 00 push 0 ; /Style = MB_OK|MB_APPLMODAL
0C71A50A |. 68 BC22750C push 0C7522BC ; |Title = "網警:****
0C71A50F |. 8B45 FC mov eax, dword ptr ss:[ebp-4] ; |
0C71A512 |. 50 push eax ; |Text = "程式檢到***********如有疑問請聯**"?
0C71A513 |. 6A 00 push 0 ; |hOwner = NULL
0C71A515 |. FF15 7CC1740C call near dword ptr ds:[<&USER32.Mess>; /MessageBoxA
0C71A51B |. 8BE5 mov esp, ebp
0C71A51D |. 5D pop ebp
0C71A51E /. C3 retn
看了一下調用堆棧是空的,堆棧裡的資料也都是假的,汗了,有點摸不到頭緒了。看來宅在家裡能讓人情緒緊張。
分析一下:起初以為這裡做了什麼高深的處理,後來看到調用堆棧和棧裡的資料都做了處理,也沒什麼可利用的。很迷糊中...
總還是有希望的,因為想到調用這個函數無非就是用jmp或者call指令完成,是以一定會在程式中留下痕迹的,在程式中搜尋了一下jmp0C71A4FD未果,call 0C71A4FD 未果。一定還有痕迹留下的,最終找到一處
mov eax,0C71A4FD.呵呵就是這裡了。
0C73B156 /$ 55 push ebp
0C73B157 |. 8BEC mov ebp, esp
0C73B159 |. B8 FDA4710C mov eax, 0C71A4FD
0C73B15E |. 35 AAAAAAAA xor eax, AAAAAAAA '還做了以下xor迷惑人的
0C73B163 |. A3 98C3750C mov dword ptr ds:[C75C398], eax '應該是存到全局變量裡了吧
0C73B168 |. 5D pop ebp
0C73B169 /. C3 retn
找到這裡就有希望了,用OD重新運作程式,這次在執行完0C73B163處指令後,在C75C398的位置下記憶體通路斷點。繼續運作程式,在0C73B1DD斷下,看了一下調用堆棧,知道這是一個Timer的過程入口,這裡有幾處判斷,多次調用了0C7399F9函數,跟進看一下。
0C73B1C2 /. 55 push ebp ; check debug timer proc
0C73B1C3 |. 8BEC mov ebp, esp
0C73B1C5 |. 83EC 14 sub esp, 14
0C73B1C8 |. C745 EC 00000>mov dword ptr ss:[ebp-14], 0
0C73B1CF |. E8 0FE9FFFF call 0C739AE3 ;不貼這個函數過程了就是通過ZwQueryInformationProcess檢查是否被調試,總之傳回eax=1就完蛋了,幾處檢測類似隻貼主要函數了(下同)
0C73B1D4 |. 8945 F4 mov dword ptr ss:[ebp-C], eax
0C73B1D7 |. 837D F4 00 cmp dword ptr ss:[ebp-C], 0
0C73B1DB |. 74 15 je short 0C73B1F2
0C73B1DD |. A1 98C3750C mov eax, dword ptr ds:[C75C398]
0C73B1E2 |. 35 AAAAAAAA xor eax, AAAAAAAA
0C73B1E7 |. 50 push eax
0C73B1E8 |. E8 0CE8FFFF call 0C7399F9
0C73B1ED |. 83C4 04 add esp, 4
0C73B1F0 |. EB 56 jmp short 0C73B248
0C73B1F2 |> FF15 68C0740C call near dword ptr ds:[<&KERNEL32.Ge>; [GetCurrentProcessId
0C73B1F8 |. 8945 F0 mov dword ptr ss:[ebp-10], eax
0C73B1FB |. 8B4D F0 mov ecx, dword ptr ss:[ebp-10]
0C73B1FE |. 51 push ecx
0C73B1FF |. E8 3DEAFFFF call 0C739C41 ;CheckRemoteDebuggerPresent
0C73B204 |. 83C4 04 add esp, 4
0C73B207 |. 8945 F8 mov dword ptr ss:[ebp-8], eax
0C73B20A |. 837D F8 00 cmp dword ptr ss:[ebp-8], 0
0C73B20E 74 17 je short 0C73B227
0C73B210 |. 8B15 98C3750C mov edx, dword ptr ds:[C75C398]
0C73B216 |. 81F2 AAAAAAAA xor edx, AAAAAAAA
0C73B21C |. 52 push edx
0C73B21D |. E8 D7E7FFFF call 0C7399F9
0C73B222 |. 83C4 04 add esp, 4
0C73B225 |. EB 21 jmp short 0C73B248
0C73B227 |> E8 8EE8FFFF call 0C739ABA ; IsDebuggerPresent
0C73B22C |. 8945 FC mov dword ptr ss:[ebp-4], eax
0C73B22F |. 837D FC 00 cmp dword ptr ss:[ebp-4], 0
0C73B233 74 13 je short 0C73B248
0C73B235 |. A1 98C3750C mov eax, dword ptr ds:[C75C398]
0C73B23A |. 35 AAAAAAAA xor eax, AAAAAAAA
0C73B23F |. 50 push eax
0C73B240 |. E8 B4E7FFFF call 0C7399F9
0C73B245 |. 83C4 04 add esp, 4
0C73B248 |> 8BE5 mov esp, ebp
0C73B24A |. 5D pop ebp
0C73B24B /. C2 1000 retn 10
看一下0C7399F9函數,哇!豁然開朗了!想明白的東西終于明白了,這個函數還是很簡單的,就是把堆棧中的資料摸去,然後修改傳回位址為0C71A4FD(其實傳回位址後邊還有幾個連續的0C71A4FD可能是為了ret的時候安全調用吧),這樣修改完0x200個堆棧空間後(真下功夫的),直接ret就飛向0C71A4FD了,就是開始那個調用MessageBox的函數了,不細說了。
仔細看一下這一大堆代碼,呵呵還有傳說中的花指令吧,不過真不太高明啊!
0C7399F9 $ 55 push ebp
0C7399FA . 8BEC mov ebp, esp
0C7399FC . 6A FF push -1
0C7399FE . 68 20B1740C push 0C74B120 ;
0C739A03 . 64:A1 0000000>mov eax, dword ptr fs:[0]
0C739A09 . 50 push eax
0C739A0A . 64:8925 00000>mov dword ptr fs:[0], esp
0C739A11 . 51 push ecx
0C739A12 . 83EC 10 sub esp, 10
0C739A15 . 53 push ebx
0C739A16 . 56 push esi
0C739A17 . 57 push edi
0C739A18 . 8965 F0 mov dword ptr ss:[ebp-10], esp
0C739A1B . C745 EC 00000>mov dword ptr ss:[ebp-14], 0
0C739A22 . 8B45 08 mov eax, dword ptr ss:[ebp+8]
0C739A25 . 8945 E0 mov dword ptr ss:[ebp-20], eax
0C739A28 . 837D 08 00 cmp dword ptr ss:[ebp+8], 0
0C739A2C . 75 08 jnz short 0C739A36
0C739A2E . E8 25490000 call 0C73E358
0C739A33 . 8945 E0 mov dword ptr ss:[ebp-20], eax
0C739A36 > 8D4D EC lea ecx, dword ptr ss:[ebp-14]
0C739A39 . 894D E4 mov dword ptr ss:[ebp-1C], ecx
0C739A3C . C745 E8 00000>mov dword ptr ss:[ebp-18], 0
0C739A43 . C745 E8 00000>mov dword ptr ss:[ebp-18], 0
0C739A4A . EB 09 jmp short 0C739A55
0C739A4C > 8B55 E8 mov edx, dword ptr ss:[ebp-18]
0C739A4F . 83C2 01 add edx, 1
0C739A52 . 8955 E8 mov dword ptr ss:[ebp-18], edx
0C739A55 > 837D E8 0A cmp dword ptr ss:[ebp-18], 0A
0C739A59 . 7D 0E jge short 0C739A69
0C739A5B . 8B45 E8 mov eax, dword ptr ss:[ebp-18]
0C739A5E . 8B4D E4 mov ecx, dword ptr ss:[ebp-1C]
0C739A61 . 8B55 E0 mov edx, dword ptr ss:[ebp-20]
0C739A64 . 891481 mov dword ptr ds:[ecx+eax*4], edx
0C739A67 .^ EB E3 jmp short 0C739A4C
0C739A69 > E8 EA480000 call 0C73E358
0C739A6E . 8945 E0 mov dword ptr ss:[ebp-20], eax
0C739A71 . EB 09 jmp short 0C739A7C
0C739A73 > 8B45 E8 mov eax, dword ptr ss:[ebp-18]
0C739A76 . 83C0 01 add eax, 1
0C739A79 . 8945 E8 mov dword ptr ss:[ebp-18], eax
0C739A7C > 817D E8 00020>cmp dword ptr ss:[ebp-18], 200
0C739A83 . 7D 24 jge short 0C739AA9
0C739A85 . C745 FC 00000>mov dword ptr ss:[ebp-4], 0
0C739A8C . 8B4D E8 mov ecx, dword ptr ss:[ebp-18]
0C739A8F . 8B55 E4 mov edx, dword ptr ss:[ebp-1C]
0C739A92 . 8B45 E0 mov eax, dword ptr ss:[ebp-20]
0C739A95 . 89048A mov dword ptr ds:[edx+ecx*4], eax
0C739A98 . EB 06 jmp short 0C739AA0
0C739A9A . B8 A09A730C mov eax, 0C739AA0
0C739A9F . C3 retn
0C739AA0 > C745 FC FFFFF>mov dword ptr ss:[ebp-4], -1
0C739AA7 .^ EB CA jmp short 0C739A73
0C739AA9 > 8B4D F4 mov ecx, dword ptr ss:[ebp-C]
0C739AAC . 64:890D 00000>mov dword ptr fs:[0], ecx
0C739AB3 . 5F pop edi
0C739AB4 . 5E pop esi
0C739AB5 . 5B pop ebx
0C739AB6 . 8BE5 mov esp, ebp
0C739AB8 . 5D pop ebp
0C739AB9 . C3 retn
總結一下,其實感覺我是舍近求遠了,因為無聊啊,可以直接從ZwQueryInformationProcess,CheckRemoteDebuggerPresent ,IsDebuggerPresent函數入手,這種檢測調試的方法就是《加密解密》上介紹的,地球人都知道了。直接幹掉那個timer就可以了,應該是這樣的!
補充一下:上次幹掉了那個Timer,更狠的東西來了,沒多一會OD都結束了,呵呵!再跟蹤了一下發現有可疑線程,它檢查是否程式被調試,如果發現被調試就調用C:/WINDOWS/System32/ntsd.exe結束掉這個調試程序,具體代碼就不貼了,調用太多,不過原理就是這樣的,呵呵!ntsd.exe讓我想起了有的病毒是通過它結束防毒軟體的,挺有意思,真是先禮後兵啊,先提示你一下,最後直接kill了!希望遊戲程式員再接再厲,我會繼續跟進...