击败反作弊 Rootkit¶
GameGuard 和其他一些反作弊套件带有用户模式 rootkit,不仅检测机器人,还主动阻止它们运行。要击败这种保护,与其跳出框外思考,你可以完整复制框并在副本内部工作。
例如,如果你想向游戏写入内存,你必须调用 kernel32.dll 导出的 WriteProcessMemory() 函数。调用这个函数时,它直接调用 ntdll.dll 的 NtWriteVirtualMemory()。GameGuard 钩住 ntdll.NtWriteVirtualMemory() 阻止你写入内存。但如果 NtWriteVirtualMemory() 从,比如说,ntdll_copy.dll 导出,GameGuard 就不会钩住那个函数。
这意味着你可以复制 ntdll.dll,并动态导入你需要的所有函数,如下所示:
// 复制并加载 ntdll
copyFile("ntdll.dll", "ntdll_copy.dll");
auto module = LoadLibrary("ntdll_copy.dll");
// 动态导入 NtWriteVirtualMemory
typedef NTSTATUS (WINAPI* _NtWriteVirtualMemory)
(HANDLE, PVOID, PVOID, ULONG, PULONG);
auto myWriteVirtualMemory = (_NtWriteVirtualMemory)
GetProcAddress(module, "NtWriteVirtualMemory");
// 调用 NtWriteVirtualMemory
myWriteVirtualMemory(process, address, data,
length, &writtenlength);
复制 ntdll.dll 后,这段代码以名称 myWriteVirtualMemory()从副本导入 NtWriteVirtualMemory()。从那里,机器人可以用这个函数代替 NtWriteVirtualMemory() 函数。它们实际上是同一库中相同的代码,只是以不同名称加载。
不过,复制反作弊软件钩住的函数只有在你调用该函数的最低级入口点时有效。如果这段代码复制kernel32.dll 并动态导入 WriteProcessMemory() 函数,反作弊 rootkit 仍然会阻止机器人,因为 kernel32_copy.dll 在调用 WriteProcessMemory() 函数时仍然依赖 ntdll.NtWriteVirtualMemory()。