吾爱破解 - LCG - LSG |安卓破解|病毒分析|www.52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 83676|回复: 189
收起左侧

[游戏安全] Win7x64系统过TP的一些尝试和目前遇到的问题

    [复制链接]
Asuna 发表于 2014-10-6 18:14
本帖最后由 Asuna 于 2014-10-6 19:42 编辑

其实渣新学内核编程不过半个月时间,帖中难免有幼稚的想法和错误,遇到的问题我会用蓝色文字表述,还请各位前辈指正,感激不尽!

我把自己目前的进展和遇到的问题一起说说吧:
x64系统过TP大概分两步,首先要过双机调试,然后要过应用层调试。

1、过双机调试,这里也分两步
(1)首先要保证debug模式下启动游戏不蓝屏。

我也是第一次研究TP,对这之前的保护不了解,不过看网上所说这个启动蓝屏似乎是最近几个月新加的。
要过这个需要对内核调试引擎有一定的了解,不过还好我们是站在巨♂人♀的肩膀上,在看雪找到了篇帖子,比较详细的分析了系统启动时内核调试引擎初始化的几个标志。
TP只是检测了其中一个(待定),KdEnteredDebugger,它通过MDL映射来判断这个标志是不是True,如果是就蓝屏,解决方法我照抄了那篇帖子,直接在Hook一下IoAllocateMdl,
把判断的地址改到一个恒为False的地方这样就可以绕过了
[C++] 纯文本查看 复制代码
PMDL newIoAllocateMdl(
        __in_opt PVOID  VirtualAddress,
        __in ULONG  Length,
        __in BOOLEAN  SecondaryBuffer,
        __in BOOLEAN  ChargeQuota,
        __inout_opt PIRP  Irp  OPTIONAL)
{

        if (VirtualAddress == KdEnteredDebugger)
        {
                //DbgPrint("[KdEnteredDebugger] address: %p\n", KdEnteredDebugger);
                VirtualAddress = (PUCHAR)KdEnteredDebugger + 0x30;  //据观察,+0x30 的位置恒为0
        }

        return oldIoAllocateMdl(VirtualAddress, Length, SecondaryBuffer, ChargeQuota, Irp);
}

不过这样做带来一个问题,蓝屏是不蓝屏了,TP的驱动模块也能加载,但只能启动登陆客户端Client.exe,在登陆后启动DNF.exe时TP会再进行一次检测,
这次就会造成虚拟机卡死,估计还是和调试模式的检测有关。


我用了个折中的解决办法,就是用户态调试的时候不进入Debug模式,这样就能启动DNF.exe了,不过实在是不方便

(2)使双机调试能下断点
关于双机调试中断点原理和异常的处理流程,我是看了《软件调试》这本书和http://www.xfocus.net/articles/200412/765.html这片帖子,有了些了解。
对于TP来说,他是不断调用KdDisableDebuger()这个函数来清零KdDebuggerEnabled,调试引擎就是在KeUpdateSystemTime()这个函数里不断检测这个标志来确定异常处理的流程

解决方法,一开始我是直接HooK KdDisableDebuger(),开头
[Asm] 纯文本查看 复制代码
xor rax, rax
ret
直接STATUS_SUCCESS然后返回,不让它做其他处理,但是毫无效果,还是下不了断点,不知道是怎么回事……

后来想了个办法,直接修改KeUpdateSystemTime()里面检测的地方,和上面一样,让它检测其它地址……
[C++] 纯文本查看 复制代码
        //替换KeUpdateSystemTime函数中两个KdDebuggerEnabled变量地址为DummyKdDebuggerEnabled
        KUSTPatchAddr1 = SearchAddressBySig((PUCHAR)KeUpdateSystemTimeAddr + 0x100, 0x100, UPSig1, sizeof(UPSig1)) ;
        if (KUSTPatchAddr1 != NULL)
        {
            KUSTPatchAddr1 += sizeof(UPSig1);
            //64位汇编,变量均为相对rip地址,下同
            DisableWriteProtect64();
            *(PULONG)KUSTPatchAddr1 = (PUCHAR)pDummyKdDebuggerEnabled - ((PUCHAR)KUSTPatchAddr1 - 2) - 6; //指令长度为6
            EnableWriteProtect64();
        }

要改的地方有3处,我只贴了一处的代码。这样就能下各种断点了。

2、双机调试之后就是用户态调试了
x64系统上TP目前做的保护还不是特别多,这也是我选x64入手的原因之一
TP修改了
DebugObject中ValIDAccessMask一项,这个就是调试权限,代码中我们恢复下就可以了。

windbg下输入以下命令就可以定位到
ValidAccessMask,下硬件断点就能找到ValidAccessMask清零的地方。
至于如何在自己的代码中定位这个变量,我是通过SSDT表查找NtCreateDebugObject这个内核函数地址,里面定位
DbgkDebugObjectType
再根据下面的结构体加几个偏移地址(
+0x040 + 0x01c)来找到ValidAccessMask。应该有更好的定位方法……

[Asm] 纯文本查看 复制代码
dq DbgkDebugObjectType
dt _OBJECT_TYPE fffffa80`24e33250

清零前:

1: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`24e33250+0x040
nt!_OBJECT_TYPE_INITIALIZER
   +0x000 Length           : 0x70
   +0x002 ObjectTypeFlags  : 0x8 ''
   +0x002 CaseInsensitive  : 0y0
   +0x002 UnnamedObjectsOnly : 0y0
   +0x002 UseDefaultObject : 0y0
   +0x002 SecurityRequired : 0y1
   +0x002 MaintainHandleCount : 0y0
   +0x002 MaintainTypeList : 0y0
   +0x002 SupportsObjectCallbacks : 0y0
   +0x004 ObjectTypeCode   : 0
   +0x008 InvalidAttributes : 0
   +0x00c GenericMapping   : _GENERIC_MAPPING
   +0x01c ValidAccessMask  : 0x1f000f
   +0x020 RetainAccess     : 0
   +0x024 PoolType         : 0 ( NonPagedPool )
   +0x028 DefaultPagedPoolCharge : 0
   +0x02c DefaultNonPagedPoolCharge : 0x58
   +0x030 DumpProcedure    : (null) 
   +0x038 OpenProcedure    : (null) 
   +0x040 CloseProcedure   : 0xfffff800`01f0ddb0     void  nt!DbgkpCloseObject+0
   +0x048 DeleteProcedure  : 0xfffff800`01d66fe0     void  nt!CmpConfigureProcessors+0
   +0x050 ParseProcedure   : (null) 
   +0x058 SecurityProcedure : 0xfffff800`01dd25f0     long  nt!SeDefaultObjectMethod+0
   +0x060 QueryNameProcedure : (null) 
   +0x068 OkayToCloseProcedure : (null) 


清零后:
0: kd> dt _OBJECT_TYPE_INITIALIZER fffffa80`24e51250+0x040
nt!_OBJECT_TYPE_INITIALIZER
   +0x000 Length           : 0x70
   +0x002 ObjectTypeFlags  : 0x8 ''
   +0x002 CaseInsensitive  : 0y0
   +0x002 UnnamedObjectsOnly : 0y0
   +0x002 UseDefaultObject : 0y0
   +0x002 SecurityRequired : 0y1
   +0x002 MaintainHandleCount : 0y0
   +0x002 MaintainTypeList : 0y0
   +0x002 SupportsObjectCallbacks : 0y0
   +0x004 ObjectTypeCode   : 0
   +0x008 InvalidAttributes : 0
   +0x00c GenericMapping   : _GENERIC_MAPPING
   +0x01c ValidAccessMask  : 0
   +0x020 RetainAccess     : 0
   +0x024 PoolType         : 0 ( NonPagedPool )
   +0x028 DefaultPagedPoolCharge : 0
   +0x02c DefaultNonPagedPoolCharge : 0x58
   +0x030 DumpProcedure    : (null) 
   +0x038 OpenProcedure    : (null) 
   +0x040 CloseProcedure   : 0xfffff800`01eb5db0     void  nt!DbgkpCloseObject+0
   +0x048 DeleteProcedure  : 0xfffff800`01d0efe0     void  nt!CmpConfigureProcessors+0
   +0x050 ParseProcedure   : (null) 
   +0x058 SecurityProcedure : 0xfffff800`01d7a5f0     long  nt!SeDefaultObjectMethod+0
   +0x060 QueryNameProcedure : (null) 
   +0x068 OkayToCloseProcedure : (null) 

清零代码:
fffff880`0bcdc4cc 54              push    rsp
fffff880`0bcdc4cd 33c0            xor     eax,eax
fffff880`0bcdc4cf 87434c          xchg    eax,dword ptr [rbx+4Ch]
fffff880`0bcdc4d2 33c0            xor     eax,eax
fffff880`0bcdc4d4 874350          xchg    eax,dword ptr [rbx+50h]
fffff880`0bcdc4d7 33c0            xor     eax,eax
fffff880`0bcdc4d9 87435c          xchg    eax,dword ptr [rbx+5Ch] // ValidAccessMask  
fffff880`0bcdc4dc 833d9585000000  cmp     dword ptr [fffff880`0bce4a78],0
fffff880`0bcdc4e3 0f8544feffff    jne     fffff880`0bcdc32d
fffff880`0bcdc4e9 33c9            xor     ecx,ecx
fffff880`0bcdc4eb ff15df6b0000    call    qword ptr [fffff880`0bce30d0]
fffff880`0bcdc4f1 488b4c2440      mov     rcx,qword ptr [rsp+40h]
fffff880`0bcdc4f6 4833cc          xor     rcx,rsp
fffff880`0bcdc4f9 e822570000      call    fffff880`0bce1c20
fffff880`0bcdc4fe 488b5c2468      mov     rbx,qword ptr [rsp+68h]
fffff880`0bcdc503 4883c450        add     rsp,50h
fffff880`0bcdc507 5f              pop     rdi
fffff880`0bcdc508 c3              ret


从清零代码那里的windbg信息来看,没有地址标号的提示(TesSafe+xxxx),这代码似乎不是在一个驱动模块里?
关于恢复的方法,大体上能想到3种:
1、开一个IoTimer或者DpcTimer或者干脆开个线程,不断对
ValidAccessMask地址写入它原来的值
2、自己代码内利用调试寄存器下硬件断点,然后hook IDT 1号中断服务子程,在里面恢复
ValidAccessMask
3、
自己代码内利用调试寄存器下硬件断点,定位到上面的清零代码,nop之(我在windbg里直接nop掉是可以的,没有模块自校验)
目前我尝试了第一种方法,开了个IoTimer,虽说1s一次会造成一些概率问题,但测试而已,简单粗暴就好。
[C++] 纯文本查看 复制代码
VOID OnTimer(DEVICE_OBJECT  *DeviceObject, PVOID  Context)
{
        DisableWriteProtect64();
        *g_pValidAccessMask = 0x1f000f;
        EnableWriteProtect64();
}

至于为什么会有后两种想法,是因为我觉得其作用不仅仅在于次,通过调试寄存器和1号中断应该还可以作很多事情,不仅仅是写个0x1f000f而已……
不过虽说想法很好,我还没开始实践……这中间似乎涉及到多核CPU还有用户栈内核栈切换的许多知识……

好了,现在可以开OD附加了,那么问题来了,学挖掘……哦不…………
还是先请前辈们看看效果图:
这是开另一个任意程序调试的OD,一切正常:
捕获.PNG
这是附加了DNF.exe,反汇编窗口基本全是0,右键看不到模块信息……
这个就是传说中的DebugPort清零吗?如果是的话,我在自己研究下恢复,如果不是,哪是什么问题造成了这种现象?

捕获2.PNG
另外从图上游戏界面可以看到,DNF检测到了非法模块,这个不知道会有什么影响……


免费评分

参与人数 9热心值 +9 收起 理由
が吻が + 1 谢谢@Thanks!
hong_sun + 1 大牛!!!!
20101010 + 1 大牛 膜拜
菜鸟也想飞 + 1 谢谢@Thanks!
爱瑞1314 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩.
Hello.World + 1 我很赞同!<span id="transmark"&g
我是who + 1 不由感叹楼主的电脑配置好高啊!
aisht + 1 我很赞同!
Rck红月破夜 + 1 表示恢复几个钩子干两个线程就能附加了

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

头像被屏蔽
xiaowenyu520 发表于 2014-10-6 18:17
表示很强大
广告位出租。
销售 瓜子 矿泉水。
ii丶BigBreast 发表于 2014-10-6 18:20
gmh5225 发表于 2014-10-6 18:18
头像被屏蔽
开心happy 发表于 2014-11-4 13:50
我一个人默默的看完了,但是看见那些代码我真心一个看不懂,我一直都是看的中文!新人能达到你这个成就,我觉的你好厉害啊,对于我来说,我真的不懂啊!希望大牛加油!
隋义 发表于 2014-10-6 19:11
膜拜大牛啊{:1_931:}
 楼主| Asuna 发表于 2014-10-29 14:30
Raker 发表于 2014-10-29 12:41
楼主一看就是技术宅,吾爱有你更精彩

技术宅拯救世界

免费评分

参与人数 1热心值 +1 收起 理由
那年我高三 + 1 我也想搞dnf,但是还没那技术。我还只是想.

查看全部评分

1373518468 发表于 2014-10-6 19:20
看的都快晕了
 楼主| Asuna 发表于 2014-10-6 19:23

开篇就说了,我是渣新而已,接触内核不过半个月……
 楼主| Asuna 发表于 2014-10-6 19:37

你们这签名都屌爆了……
 楼主| Asuna 发表于 2014-10-6 19:51
本帖最后由 Asuna 于 2014-10-6 20:13 编辑

@Rck红月破夜
前辈还求详细
线程能想到是调用KdDisableDebuger()的线程,主要怕线程有通讯,另外的呢?
还有钩子都有哪些?
最后那个附加不正常是怎么回事?
1924065517 发表于 2014-10-6 20:02
水滴不就稳妥了?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则 警告:本版块禁止灌水或回复与主题无关内容,违者重罚!

快速回复 收藏帖子 返回列表 搜索

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-4-24 03:18

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表