安全的取得syscall序号(windows)

声明:

本文基于 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呢?

答案是有的

windows中所有进程都会加载ntdll.dll,为了加速加载,有一套机制叫做KnownDlls,有很多dll(包括ntdll,kernel32等)都在一个内核名为 KnownDlls 的目录对象下,有一份预加载的副本,这个副本被叫做KnownDll

为了使所有进程都能正确使用此副本,

  • windows会在所有 KnownDll 在不同进程 第一次 加载时,都加载到同一虚拟内存地址
  • windows允许R3程序打开KnownDlls对象

那问题就很简单了,如果我们要获得干净的Ntdll,只需要

  1. OpenDirectory KnownDlls
  2. OpenSection Ntdll.dll
  3. MapViewOfSection

如果Hacker不知道此方法的话,不论Hook CreateFile函数 还是MapViewOfSection,都没有办法定位清楚你的syscall初始化逻辑啦

发表评论

电子邮件地址不会被公开。

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据