天天看点

就是这么检查debug的啊!

闲来无事胡写些东西留给自己以后看,没有技术含量,想笑的人劳驾,飘过吧!

周末在家宅了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了!希望游戏程序员再接再厉,我会继续跟进...