前几天偶然发现一篇使用变速齿轮来加速植物大战僵尸的文章,这几天在研究SandboxiePlus的源码,其中也有加速的设置,但加速部分的代码写的很乱。举个例子:
上述的代码是SleepEx的hook函数。按照changelog中介绍,AddSleepSpeed和LowSleepSpeed分别表示加速和降速的配置,AddSleepSpeed/LowSleepSpeed表示加速倍数,但上述的SleepEx hook函数中dwMiSecond * add / low其实增加了SleepEx的数值,正确应该修改为dwMiSecond * low / add。本文将变速齿轮的加速原理移植到SandboxiePlus中,实现了植物大战僵尸游戏的加速。
我使用的变速齿轮中有三个文件,分别是:GearNT.exe、GearNTKe.dll和Hook.dll。其中加速部分的实现在GearNTKe.dll中,该DLL中hook了六个函数,如下:
上述函数可以分为两类:
SandboxiePlus的代码已经实现了hook功能,我们所要做的就是实现上述的hook函数即可。
注意:QueryPerformanceCounter使用的是一个64位值,使用"t + (tt - t) * 加速倍数"可能会出现溢出,使用SandboxiePlus原来的hook函数。
通过修改SandboxiePlus的SboxDll,实现了和变速齿轮相同的加速效果,理论上变速齿轮加速的软件,现在的SandboxiePlus都可以加速。成品可以在"安全狗的开发日常"公众号中回复PlantsVsZombie关键字获取相关文件的下载链接,文件下载后替换SandboxiePlus安装目中的文件即可。
_FX DWORD Kernel_SleepEx(DWORD dwMiSecond, BOOL bAlert)
{
ULONG add = SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1);
ULONG low = SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1);
if (add != 0 && low != 0)
return __sys_SleepEx(dwMiSecond * add / low, bAlert);
return __sys_SleepEx(dwMiSecond, bAlert);
}
_FX DWORD Kernel_SleepEx(DWORD dwMiSecond, BOOL bAlert)
{
ULONG add = SbieApi_QueryConfNumber(NULL, L"AddSleepSpeed", 1);
ULONG low = SbieApi_QueryConfNumber(NULL, L"LowSleepSpeed", 1);
if (add != 0 && low != 0)
return __sys_SleepEx(dwMiSecond * add / low, bAlert);
return __sys_SleepEx(dwMiSecond, bAlert);
}
DWORD GetTickCount();
BOOL QueryPerformanceCounter([out] LARGE_INTEGER *lpPerformanceCount);
LONG GetMessageTime();
UINT_PTR SetTimer([in, optional] HWND hWnd, [in] UINT_PTR nIDEvent,
[in] UINT uElapse, [in, optional] TIMERPROC lpTimerFunc);
DWORD timeGetTime();
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution,
LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent);
DWORD GetTickCount();
BOOL QueryPerformanceCounter([out] LARGE_INTEGER *lpPerformanceCount);
LONG GetMessageTime();
UINT_PTR SetTimer([in, optional] HWND hWnd, [in] UINT_PTR nIDEvent,
[in] UINT uElapse, [in, optional] TIMERPROC lpTimerFunc);
DWORD timeGetTime();
MMRESULT timeSetEvent(UINT uDelay, UINT uResolution,
LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent);
_FX UINT_PTR Gui_SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc)
{
ULONG add = SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1), low = SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1);
if (add != 0 && low != 0) {
UINT64 newElapse = uElapse;
newElapse = newElapse * low / add;
return __sys_SetTimer(hWnd, nIDEvent, (UINT)newElapse, lpTimerFunc);
}
return 0;
}
_FX UINT_PTR Gui_SetTimer(HWND hWnd, UINT_PTR nIDEvent, UINT uElapse, TIMERPROC lpTimerFunc)
{
ULONG add = SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1), low = SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1);
if (add != 0 && low != 0) {
UINT64 newElapse = uElapse;
newElapse = newElapse * low / add;
return __sys_SetTimer(hWnd, nIDEvent, (UINT)newElapse, lpTimerFunc);
}
return 0;
}
_FX MMRESULT Wimm_timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent)
{
ULONG add = SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1), low = SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1);
if (add != 0 && low != 0) {
UINT64 newDelay = uDelay;
newDelay = newDelay * low / add;
return __sys_timeSetEvent((UINT)newDelay, uResolution, lpTimeProc, dwUser, fuEvent);
}
return 0;
}
_FX MMRESULT Wimm_timeSetEvent(UINT uDelay, UINT uResolution, LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT fuEvent)
{
ULONG add = SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1), low = SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1);
if (add != 0 && low != 0) {
UINT64 newDelay = uDelay;
newDelay = newDelay * low / add;
return __sys_timeSetEvent((UINT)newDelay, uResolution, lpTimeProc, dwUser, fuEvent);
}
return 0;
}
[培训]Windows内核深度攻防:从Hook技术到Rootkit实战!