声明:
本文基于 CC-BY-NC-ND 协议发表 https://creativecommons.org/licenses/by-nc-nd/4.0/
本文代码基于 MIT 协议发布
为了不被攻击
游戏R3保护一般都会采用主动调用syscall的方式防止调用的函数被ring3级hook
直接调用syscall需要syscall序号,为了取得这个序号,已被使用的方法大约有以下几种
直接读取内存中的ntdll.dll的内存,取得序号
这种方法最原始,最容易被发现或污染
- IW系列
CreateFile ntdll.dll 后 NtMapSection 取得干净的内存
此方法有一定隐蔽性,但是有一定经验的Hacker会直接Hook NtCreateFile函数
且由于游戏本身实现有一定问题,此syscall可直接被ring3层Hook
- 拳头系列
CreateFile ntdll.dll 后 ReadFile 取得内存
这个方法也算是中规中矩,但是
且由于游戏本身实现有一定问题,此syscall可直接被ring3层Hook
可以看到比较高端的实现,IW与拳头,都使用到了CreateFile这个函数,
这个函数被Hook就GG了,那么是否有一种取得干净的Ntdll的方式,且不需要CreateFile呢?
答案是有的
- https://github.com/MoePus/SPiCall #(MIT LICENSE)
windows中所有进程都会加载ntdll.dll,为了加速加载,有一套机制叫做KnownDlls,有很多dll(包括ntdll,kernel32等)都在一个内核名为 KnownDlls 的目录对象下,有一份预加载的副本,这个副本被叫做KnownDll
为了使所有进程都能正确使用此副本,
- windows会在所有 KnownDll 在不同进程 第一次 加载时,都加载到同一虚拟内存地址
- windows允许R3程序打开KnownDlls对象
那问题就很简单了,如果我们要获得干净的Ntdll,只需要
- OpenDirectory KnownDlls
- OpenSection Ntdll.dll
- MapViewOfSection
如果Hacker不知道此方法的话,不论Hook CreateFile函数 还是MapViewOfSection,都没有办法定位清楚你的syscall初始化逻辑啦