首页
社区
课程
招聘
6
[旧帖] [原创]TP驱动保护-浅谈-总结 0.00雪花
发表于: 2012-5-15 18:25 4464

[旧帖] [原创]TP驱动保护-浅谈-总结 0.00雪花

2012-5-15 18:25
4464

今天写一篇关于某款游戏的TP保护学习总结(分析谈不上)吧,搞这驱动大概弄了2个星期,中间有点事情等于断断续续的加起来搞了2个星期,因为TP、HP、GPK等等,当前比较流行的游戏保护,都有很多大牛已经研究透了,并且非常潇洒的公布出来了。所有对我们的学习有了很大的帮助,在这里向他们致敬!你们永远活在我们的心中。。。


        类似的文章也已经有很多了,都写的非常好,超越他们是很难的了,之所以写这篇文章,主要有几点,一来我最近没有在搞驱动保护,算是个复习吧,所以想写一篇文章总结梳理下驱动那点事儿,二来在驱动中我还是有很多地方有些不明白,还有些问题,写出来大家想想,帮我想想,也帮自己想想,指不定哪天也遇到了可以迅速的解决。


        好了,进入正题:


        如果想学习驱动保护或者驱动方面的技术,你首先要补充下自己的知识,否则你会一头雾水,不知去向。建议大家如果是想做windows驱动方面的 就学习下Win32汇编,因为Windows底层不是完全开源的,有些东西必须反汇编才能看到,然后就是Windows底层实现原理,也就是了解下Windows是怎么协调工作的其中就包括我们要用到的SSDT,如果你在学习windows底层的话 这个你就会明白的,还有就是编程语言了,C、C++、delphi、汇编  根据自己擅长的用。语言只是工具而已。当然了,调试工具你还是要会用的。WinDBG、syser、等。根据自己需要。


        上面说了一些相关的东西,现在我们来说说TP保护。TP保护我就不介绍了,各种百度。。。。。


        TP需要处理的内容:


        SSDT HOOK:


        NtOpenProcess


        NtOpenThread


        NtReadVirtualMemory


        NtWriteVirtualMemory


        KiAttachPRocess


        清零和监控:


        两处清零和一处监控


        因为不是D*F 所有清零不是4处


        注意在检查调试的时候一定要等游戏全部进入到账号登陆的时候,因为TP会运行两次,第一次是假的,所以我们必须至少等游戏进入账号登陆那个界面才行。


        首先解决前两个因为 NtOpenProcess和NtOpenThread的处理是一样的,但后面三个是不一样的,这样个有一点点的难度,其实都一样。。。。


        如果,大家不知道TP都现在这些函数的那些部分,那你就那TP没运行直接的函数体和运行后的函数体进行文本对比就行了。


         push    dword ptr [ebp-34h]


         push    dword ptr [nt!PsProcessType (8055b258)]


         push    ebx


         call    nt!ObOpenObjectByName (805b1f7a)


        通过对比你会发现就是这里出来问题。。上面的代码是没有运行TP之前的。


        TP的做法是:把call    nt!ObOpenObjectByName (805b1f7a) 替换成他自己的函数名字。也就是说,TP来控制什么时候调用ObOpenObjectByName函数,所以TP就机会对我们做一些处理了,具体TP在调用ObOpenObjectByName函数之前都做了什么,我也没有具体的读代码(主要是技术不到家。。)但大牛们都说是和游戏客户端进行通信用的。比如:游戏调用OpenProcess的时候他需要给某个全局变量赋值。然后再调用ObOpenObjectByName函数让系统正常的走下去,如果游戏端在检测这个变的时候发现没有变动,或者值不对,那么TP就会认为,没有按照他的步骤走,就报异常了。。。这是打个比方,主要是让大家明白,我们不能直接把他改回去,所以,我们需要在进入他的CALL之前先进入我们的CALL,我们先判断下,是谁在调用这个OpenProcess 如果是游戏进程的话,我们就让他进入他CALL(也就是让它去修改那个全局变量,保证游戏的验证)如果是我们的调试器的话就直接调用ObOpenObjectByName函数就可以了。、。。。这是解决OpenProcess、OpenThread HOOK的思路,以前都已经有人写过了,我今天只是加了一点我自己的理解,希新手朋友们能够理解这点。下面发下具体实现:


        代码可以分为两部分看:一部分是在OpenProcess函数中插入我们的CALL ,另一部分是到我们CALL里面的处理代码。


        修改OpenProcess:


        __asm


           {


                //我们写入OpenProcess的被HOOK地址  


              mov ebx,p_MyOpenProcessHook//我们自己的函数地址


                  mov byte ptr [ebx+0],0xe9 //jmp


                  lea eax,My_NtOpenPrcoess //通过公式计算


                  sub eax,p_MyOpenProcessHook


                  sub eax,5


                  mov [ebx+1],eax


                  mov [ebx+5],0x90        //nop


           }


              __asm


           {


                //我们写入OpenThread的被HOOK地址  


              mov ebx,p_MyOpenThreadHook//我们自己的函数地址


                  mov byte ptr [ebx+0],0xe9 //jmp


                  lea eax,My_NtOpenThread //通过公式计算


                  sub eax,p_MyOpenThreadHook


                  sub eax,5


                  mov [ebx+1],eax


                  mov [ebx+5],0x90        //nop


           }


        第二部分:我们的函数实现:


        //我们自己的:NtOpenPrcoess 处理函数


        __declspec(naked) VOID My_NtOpenPrcoess()


        {  


                //获得调用者的EPROCESS


                  processEPROCESS = IoGetCurrentProcess();


                RtlInitAnsiString(&p_str1,SG_EXE);


                //获得调用者的EPROCESS


                  RtlInitAnsiString(&p_str2,(PCSZ)((ULONG)processEPROCESS+0x174));


                  if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)


                  {


                            __asm


                            {


                                  push  dword ptr [ebp-38h]


                                push  dword ptr [ebp-24h]


                                mov   eax,p_TpHookAddress // CALL B2165421 ;


                                jmp   eax


                            }                   


                     }else


                    


                       {


                        __asm


                            {


                                        push    dword ptr [ebp-38h]


                                        push    dword ptr [ebp-24h]


                                        push    p_ReturnAddress  //8BF8 MOV EDI,EDI 0x80572907


                                        mov     eax,ObOpenObjectByPointerAddress


                                        jmp     eax                


                        }


                       }


        }


        //我们自己的NtOpenThread 实现函数


        __declspec(naked)VOID My_NtOpenThread()


        {  


                //获得调用者的EPROCESS


                  processEPROCESS = IoGetCurrentProcess();


                RtlInitAnsiString(&p_str1,SG_EXE);


                //获得调用者的EPROCESS


                  RtlInitAnsiString(&p_str2,(PCSZ)((ULONG)processEPROCESS+0x174));


                  if (RtlCompareString(&p_str1,&p_str2,TRUE) == 0)


                  {


                            __asm


                            {


                                push    dword ptr [ebp-34h]


                                push    dword ptr [ebp-20h]


                              mov     eax,p_TpHookAddress_Thread


                              jmp     eax


                            }


            }else


                    


                       {


                        __asm


                        {


                         push    dword ptr [ebp-34h]


                         push    dword ptr [ebp-20h]


                         push    p_ReturnAddress_Thread


                         mov     eax,ObOpenObjectByPointerAddress


                       jmp     eax       


                               


                        }       


                        }       


        }


       


下面开始处理剩下的三个函数


1.NtReadVirtualMemory


2.NtWriteVirtualMemory


3.KiAttachPRocess


这三个函数非常好处理,他们都是函数头部有个JMP跳转,处理的方法直接对照着没有HOOK之前用汇编写回去就可以了。。


直接上代码:


        /**


[招生]科锐逆向工程师培训(2025年3月11日实地,远程教学同时开班, 第52期)!

收藏
免费 6
支持
分享
赞赏记录
参与人
雪币
留言
时间
伟叔叔
为你点赞~
2024-5-31 04:47
心游尘世外
为你点赞~
2024-5-31 01:30
QinBeast
为你点赞~
2024-5-31 01:19
飘零丶
为你点赞~
2024-3-28 00:56
shinratensei
为你点赞~
2024-1-29 04:26
PLEBFE
为你点赞~
2023-3-7 00:43
最新回复 (12)
雪    币: 297
活跃值: (280)
能力值: ( LV4,RANK:55 )
在线值:
发帖
回帖
粉丝
2
支持一个。  楼主加油
2012-5-15 19:45
0
雪    币: 85
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶一个,拿到邀请码就羡煞人也
2012-5-16 08:59
0
雪    币: 75
活跃值: (39)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
4
估计不会给吧。。。
2012-5-18 15:55
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
谢谢楼主,这文章真是好
2012-5-19 06:25
0
雪    币: 0
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
谢谢你多多写好文章指导新手
2012-5-19 14:26
0
雪    币: 8
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
就算把,也能调试了,断点等都过了了。

再被混淆的代码中,又要怎么做能得到有用的数据呢?
2012-5-19 20:38
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
这能过才见鬼了,port123都是变量。每次更新都变,你搞虾米啊。现在的人啊发贴都是乱来
2012-5-28 00:06
0
雪    币: 219
活跃值: (878)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
9
。。。。。这样子就精华了
     没源码    至少给个DOC
2012-5-29 14:05
0
雪    币: 48
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
现在的人咋都这个鸟样?
你指责别人的不对,那就你把不对的理由说一下,列出你的理由,而不是随便一句话了事了。
到底是你在误导,还是别人在误导,该相信谁呢
2012-8-10 17:28
0
雪    币: 508
活跃值: (202)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
11
我想这位朋友说的是~~~~~~~~
清0的偏移是会变的~~~~~~~~~
而且也没有给出偏移,或给出找到偏移的方法
有点虎头蛇尾的感觉不过可以过掉保护应该不错了
2012-8-18 13:36
0
雪    币: 508
活跃值: (202)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
12
兄弟的破文和这个朋友的有8成相同~~~~~~~~~~~~
http://bbs.pediy.com/showthread.php?t=126802&highlight=dnf
2012-8-18 14:32
0
雪    币: 3836
活跃值: (4142)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
13
还是V大的AGP牛叉,一个大招TP就没了。。。
2012-8-31 16:14
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册