-
-
[原创]Windows系统时光机(副标题: 守望者逆向)
-
发表于:
2012-10-29 15:04
21262
-
[原创]Windows系统时光机(副标题: 守望者逆向)
【文章标题】: Windows系统时光机(副标题: 守望者逆向)
【文章作者】: root
【作者邮箱】: cppcoffee@gmail.com
【作者主页】: hi.baidu.com/cppcoffee
【软件名称】: 守望者
【下载地址】: 自己搜索下载
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
在6月份的时候已经逆向完守望者的核心驱动并还原成代码.由于一些事情迟迟没有发布(也许有些大牛手头上也有,由于一些原因没有公开吧,呵呵).
看到论坛有一些帖子有关守望者的讨论,希望这篇文章能够让大伙少走弯路:)
这是一个逆向游戏守望者的一个驱动,用来给整个系统进行加速处理.
目前是整个系统都加速,包括系统时钟也变快了.
备注: R3层要加载D3D9相关的DLL进行初始化,才会真正的体验到加速的效果.
跟踪守望者应用层程序使用宇宙加速功能的时候分别执行了如下操作:
1. 安装了名为 Gwken.dll 的驱动文件.
2. 打开的设备名: \\.\GWDRIVER_DeviceName
3. 调用 GWHookMan.dll 提供的两个接口
// 设置速度的函数 nSpeed速度值 初始化是100 (1倍)
BOOL __stdcall GwSetText(int nSpeed)
// 间隔刷新 (SetTimer 300毫秒调用一次,一直设置IOCTL)
BOOL __cdecl GwSdRefresh()
好了,到目前已经知道了驱动文件是哪个了,可以开始分析内核了.
在驱动层,用雪兔儿查看了下HOOK的内核钩子有两个,分别是 KeUpdateSystemTime 和 KeQueryPerformanceCounter.
插个题外话,分享下一点小常识,呵呵,起初参考的代码是ReactOS,发现 ReactOS 定义的 KeUpdateSystemTime __stdcall,结果我也用__stdcall,虚拟机就蓝屏了,后来才发现原来不是每个驱动函数都是用__stdcall的 - -b
后来用IDA看下 ntoskrnl.exe,才发现它是__cdecl.囧Orz...
进入正题.
使用兄弟工作室提供的那个加速公式:
Result := 上次返回时间 + Round((当前返回时间 - 上次正常时间) * Power(2,倍数));
在驱动里面inline HOOK KeUpdateSystemTime 和 KeQueryPerformanceCounter
然后定义两个数值,用来计算加速多少倍
---------------------------------华丽的分割线---------------------------------
// 变速基数
const DWORD g_dwSpeedBase = 100;
// 变速数值 (200 / 100 = 2倍速,驱动加载后,默认为2倍速)
DWORD g_dwSpeed_X = 200;
替换掉的 KeUpdateSystemTime 函数内容如下
// 必须是裸函数
VOID __declspec(naked) __cdecl Fake_KeUpdateSystemTime()
{
// 跳转到新函数去执行
__asm
{
// 参数是EAX和EDX传参的, 分别是 OUT PLARGE_INTEGER CurrentTime 的高位和低位
// 进行变速处理 (EAX * 当前速度值 / 速度基数)
mul g_dwSpeed_X
div g_dwSpeedBase
// 跳转到原来的函数去执行
jmp JmpOriginal_KeUpdateSystemTime
}
}
替换掉的 KeQueryPerformanceCounter
// 伪装KeQueryPerformanceCounter
LARGE_INTEGER __stdcall Fake_KeQueryPerformanceCounter( OUT PLARGE_INTEGER PerformanceFrequency )
{
LARGE_INTEGER liResult;
LARGE_INTEGER liCurrent;
// 调用原始函数
liCurrent = JmpOriginal_KeQueryPerformanceCounter( PerformanceFrequency );
// 上次返回时间 + Round((当前返回时间 - 上次正常时间) * Power(2,倍数));
liResult.QuadPart = g_liPreReturnCounter.QuadPart + (liCurrent.QuadPart - g_liPreOriginalCounter.QuadPart) * g_dwSpeed_X / g_dwSpeedBase;
// 保存当前的原始数值
g_liPreOriginalCounter.QuadPart = liCurrent.QuadPart;
// 保持返回值
g_liPreReturnCounter.QuadPart = liResult.QuadPart;
return liResult;
}
---------------------------------我是分割线---------------------------------
好了就写到这里了,由于感冒犯困,文章中可能避免不了笔误,请大家见谅.
本文末尾附上驱动源码和逆向的IDB文件,驱动使用WDK 7600.16385.1编译通过,在XP系统下面测试通过.
备注: 需要在加载驱动后,发现系统变卡了,请运行一个MP3播放器播放一首歌曲吧(或自己调用DX的初始化函数),就能够看到加速的效果了.守望者内部是加载了d3d9.dll的初始化函数来让驱动做的一些工作生效,由于没有DX的源码,无法分析到底是什么原理.还望感兴趣的人能够分享一下心得体会.
谢谢兄弟工作室提供的公式.
声明: 代码只用来学习交流用,请勿用于非法用途,否则后果自负.
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2012年10月29日 14:54:50
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)