原神反调试分析

您所在的位置:网站首页 原神15开发端 原神反调试分析

原神反调试分析

2023-08-19 07:05| 来源: 网络整理| 查看: 265

打开CE,打开原神启动器。 至此,游戏未加载驱动。启动器可以被CE正常读写。 在这里插入图片描述

打开原神,CE中选择YuanShen.exe,发现原神并不能被读写。 在这里插入图片描述

尝试分析不能读写的原因。

CE调用的读取内存函数是NtReadVirtualMemory 猜测有三种可能 1.NtReadVirtualMemory被HOOK 2.ObCallBack 3.infinityhook 第一种情况因为X64系统PatchGuard的存在排除。当然VT也是有可能的,现在先不考虑。 第二种情况是最有可能的。 第三种情况感觉不大靠谱。

为了验证猜测,打开ARK工具。 在这里插入图片描述好家伙,果然注册了线程和进程的ObCallBack,同样也注册了下图三个回调用于收集信息云云 在这里插入图片描述 直接把内存dump下来,修复好,直接拖IDA。 直接定位到Process ObCallback函数。 在这里插入图片描述 继续跟进。 F5大法失败。只是为了初步分析,没必要看头疼的汇编,而且Thread和Process的处理八九不离十,去康康Thread先

进Thread ObCallback F5

在这里插入图片描述

发现这里判断了是否操作的是游戏进程就把句柄读权限抹掉。 抹除写权限之前先判断了操作进程是不是csrss.exe如果是就不抹除。

因此可以利用更改进程名为csrss.exe来绕过写内存ObCallback保护,但还是没有读的权限。

游戏是通过句柄降权的方式保护游戏,那么我们也可以注册ObCallback直接把权限升回去。 在我们的回调中执行,当然执行之前需要判断操作游戏的是不是我们的调试器,如果不是就别把提权了。

pOperationInformation->Parameters->CreateHandleInformation.DesiredAccess = PROCESS_ALL_ACCESS_THREAD; pOperationInformation->Parameters->CreateHandleInformation.OriginalDesiredAccess = PROCESS_ALL_ACCESS_THREAD;

加载驱动后上游戏,发现CE读出了错误的内存。猜测是用了假的CR3导致读了错误的物理页 在回调中读取CR3,与eprocess中的DirectoryTableBase进行比较发现并不相同。哦吼

1: kd> dt _KPROCESS nt!_KPROCESS +0x000 Header : _DISPATCHER_HEADER +0x018 ProfileListHead : _LIST_ENTRY +0x028 DirectoryTableBase : Uint8B

那就纠正回去。

if (MmIsAddressValid((PVOID)((ULONG64)pe + 0x28))) { if (__readcr3() != *(PULONG64)((ULONG64)pe + 0x28)) { PULONG64 FakeCR3 = Mapped_Memory_Addr(*(PULONG64)((ULONG64)pe + 0x28), 0x1000, 0); PULONG64 TrueCR3 = Mapped_Memory_Addr(__readcr3(), 0x1000, 0); if (FakeCR3[0] != TrueCR3[0]) { _disable(); if (FakeCR3 != NULL && TrueCR3 != NULL) { RtlCopyMemory(FakeCR3, TrueCR3, 0x1000); } MmUnmapIoSpace(FakeCR3, 0x1000); MmUnmapIoSpace(TrueCR3, 0x1000); _enable(); } } }

上游戏测试。已经能显示正常数据了。至此读写保护绕过。 PS:禁止读写的保护在后面分析驱动的时候我是没发现痕迹(我可能太菜了)。 在这里插入图片描述 有读写权限了,VEH可以正常附加调试。当然这不代表没有检测,至少硬件断点没有处理,还是很容易利用NtGetContextThread检测的。 PS:瞄了眼驱动发现了遍历进程模块基址、名称,并将信息返回给R3层的代码,想不封号VEH调试、注入估计还是得处理下。当然还有其他检测。 在这里插入图片描述 CE换成Windows调试器。调试直接闪退。看遍了驱动代码也没发现在哪里有能阻止调试器附加的地方。驱动层先放着,去康康用户层

想了想调试流程,发现用户层关键代码被处理的可能性很大,直接扫描HOOK,发现DbgUiRemoteBreakin被处理了。 在这里插入图片描述 此处跳转到了原神的代理函数。代理函数会执行记录信息并退出游戏操作。

无法附加的原因找到了,直接恢复HOOK。在这里插入图片描述调试器成功附加,并在此处下内存断点,查找校验。 在这里插入图片描述 并未发现校验。

至此用户调试器已经能正常附加。想要实现不封号调试还需处理其他检测,例如校验 PEB+2、NtQueryInformationThread等等。

下面粗略讲讲关于内核调试器检测 在这里插入图片描述驱动在这里创建了个线程,跟进去 在这里插入图片描述

发现驱动通过KdDebuggerEnabled置0,调用 KdDisableDebugger 实现禁用双机调试。把调用KdDebuggerEnabled的KdDebuggerEnabled操作移位即可轻松绕过。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3