前几天偶然发现一篇使用变速齿轮来加速植物大战僵尸的文章,这几天在研究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;
}
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课