吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 1047|回复: 16
上一主题 下一主题
收起左侧

[C&C++ 原创] 使用SandboxiePlus加速植物大战僵尸游戏

[复制链接]
跳转到指定楼层
楼主
暴龙兽 发表于 2025-4-20 16:19 回帖奖励
本帖最后由 暴龙兽 于 2025-4-20 16:23 编辑

前言

前几天偶然发现一篇使用变速齿轮来加速植物大战僵尸的文章,这几天在研究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);
}

上述的代码是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了六个函数,如下:

// kernel32.dll
DWORD GetTickCount();
BOOL QueryPerformanceCounter([out] LARGE_INTEGER *lpPerformanceCount);
// user32.dll
LONG GetMessageTime();
UINT_PTR SetTimer([in, optional] HWND hWnd, [in] UINT_PTR  nIDEvent,
  [in] UINT uElapse, [in, optional] TIMERPROC lpTimerFunc);
// winmm.dll
DWORD timeGetTime();
MMRESULT timeSetEvent(UINT  uDelay, UINT  uResolution,
  LPTIMECALLBACK lpTimeProc, DWORD_PTR dwUser, UINT  fuEvent);

上述函数可以分为两类:

  • 类型一:设置基于时间的定时器回调函数,加速思路直接修改uDelay为uDelay/加速倍数。这类函数有SetTimer和timeSetEvent函数两个函数。





  • 类型二:时刻做差获取时间。获取两个时刻t1和t2,然后t2 - t1作为具体代码消耗的时间。加速思路是在GearNTKe.dll加载的时候获取一个基点t,然后按照
    "t + (tt - t) * 加速倍数"公式计算返回值。其中tt是获取时刻函数,这类函数有GetTickCount、GetMessageTime和timeGetTime。下面是timeGetTime的hook函数的伪代码:




另外一个有意思的点是变速齿轮的加速刻度,每一个刻度为0.5,因为它使用的加速倍数公式倍数 = pow(2.0, (double)(距离原点的距离) / 10.0) * (2^22)(2^22)扩大的倍数,倍数越大越精确。当a1等于0.5和1时加速倍数分别为1.41和2倍,加速倍数如下:




SandboxiePlus代码修改

SandboxiePlus的代码已经实现了hook功能,我们所要做的就是实现上述的hook函数即可。

类型一

  • 修改SetTimer,该函数的hook函数如下:
    _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;
    }
  • 修改timeSetEvent,该函数的hook函数如下:

    _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;
    }

    类型二

  • 修改GetTickCount,该函数的hook函数如下:
    _FX DWORD Kernel_GetTickCount() 
    {
    ULONG add = SbieApi_QueryConfNumber(NULL, L"AddTickSpeed", 1);
        ULONG low = SbieApi_QueryConfNumber(NULL, L"LowTickSpeed", 1);
        ULONG64 count = __sys_GetTickCount();
        if(add != 0 && low != 0) {
                count = Dll_FirstGetTickCountValue + (count - Dll_FirstGetTickCountValue) * add / low; // multi
    }
    return (DWORD)count;
    }
  • 修改timeGetTime,该函数的hook函数如下:

    _FX DWORD Wimm_timeGetTime()
    {
    ULONG add = SbieApi_QueryConfNumber(NULL, L"AddTimerSpeed", 1), low = SbieApi_QueryConfNumber(NULL, L"LowTimerSpeed", 1);
    ULONG64 time = __sys_timeGetTime();
    
    if(add != 0 && low != 0) {
      time = Dll_FirsttimeGetTimeValue + (time - Dll_FirsttimeGetTimeValue) * add / low; // multi
    }
    
    return (DWORD)time;
    }

    注意:QueryPerformanceCounter使用的是一个64位值,使用"t + (tt - t) * 加速倍数"可能会出现溢出,使用SandboxiePlus原来的hook函数。

    测试

  • 创建一个标准的box,修改box的配置,添加如下内容:


  • 编译SandboxiePlus的SboxDll项目,生成32位和64位版本的SbieDll.dll,并替换SandboxiePlus安装目录中的SbieDll.dll。
  • 运行植物大战僵尸主程序PlantsVsZombies.exe,可以感觉到阳光和僵尸的速度变快了。效果的话,可以在代码中加些日志。
    PlantsVsZombies.exe (5864, 5548) - 14:29:41.906   Hook (U)          SetTimer => oldEplase=300, newElapse=200
    PlantsVsZombies.exe (5864, 5548) - 14:29:41.906   Hook (U)          SetTimer => oldEplase=100, newElapse=66
    PlantsVsZombies.exe (5864, 5548) - 14:30:43.375   Hook (U)          GetTickCount => oldCount=54518792, newCount=54549719
    PlantsVsZombies.exe (5864, 5548) - 14:30:43.381   Hook (U)          timeGetTime => oldTime=54518869, newTime=54549795

    结论

    通过修改SandboxiePlus的SboxDll,实现了和变速齿轮相同的加速效果,理论上变速齿轮加速的软件,现在的SandboxiePlus都可以加速。

免费评分

参与人数 7吾爱币 +17 热心值 +5 收起 理由
苏紫方璇 + 10 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
hitholy + 1 + 1 我很赞同!
chao0927 + 1 我很赞同!
daxz + 1 + 1 谢谢@Thanks!
156608225 + 2 + 1 用心讨论,共获提升!
complex + 1 我很赞同!
TADYCB + 1 + 1 我很赞同!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

推荐
 楼主| 暴龙兽 发表于 2025-4-21 22:09 |楼主
加速功能已经合入master分支,后面新发布的版本会带有加速功能的。https://github.com/sandboxie-plu ... 1ba17012ab62354156b

免费评分

参与人数 1吾爱币 +3 热心值 +1 收起 理由
感冒的猪baby + 3 + 1 用心讨论,共获提升!

查看全部评分

沙发
TADYCB 发表于 2025-4-20 16:27
3#
xjjlcp 发表于 2025-4-20 16:29
感谢缘分,感谢遇见,感谢陪伴,感谢时光,感谢你的包容,感谢你的帮助🙏
4#
walykyy 发表于 2025-4-20 16:33
我都是在游戏里面看见变速齿轮
5#
 楼主| 暴龙兽 发表于 2025-4-20 16:48 |楼主
TADYCB 发表于 2025-4-20 16:27
理论上能更快吧?

可以更快,我这里设置的1.5倍,再快可能需要加其他的修改器才好玩些。
6#
 楼主| 暴龙兽 发表于 2025-4-20 16:49 |楼主
walykyy 发表于 2025-4-20 16:33
我都是在游戏里面看见变速齿轮

我把变速齿轮的功能挪到了SandboxiePlus里面
7#
wei666123 发表于 2025-4-20 16:53
植物大战僵尸有没有好玩的版本啊,哈哈,多年没玩过了
8#
 楼主| 暴龙兽 发表于 2025-4-20 16:58 |楼主
wei666123 发表于 2025-4-20 16:53
植物大战僵尸有没有好玩的版本啊,哈哈,多年没玩过了

其他的老游戏应该也可以的
9#
Yifan2007 发表于 2025-4-20 17:11
这个变速齿轮使用起来有点bug,,,还是ce自带的好用,lz可以写一个用ce实现的
10#
Yifan2007 发表于 2025-4-20 17:12
GearNT在加速一些复杂游戏来回变速感觉容易卡死,ce就没这个问题
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-5-28 05:02

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表