游戏逆向实战:我会梯云纵

游戏逆向实战:我会梯云纵

引言:从手残到空中舞者

作为一个又菜又爱玩的玩家,我经常在游戏里遇到复杂地形时频频扑街,严重影响心情。尤其是我钟爱的平台跳跃类和银河恶魔城类游戏,往往几个难度极高的跳跃点就能硬控我一整周。

有没有什么办法能让跳跃变得简单一些?

今天我们就来讨论如何让游戏主角学会武当轻功 "梯云纵" ------也就是 二段跳 ,让手残的我也能顺利通关。

研究对象依然是 Cheat Engine 自带的 Tutorial Game 3。我们将通过逆向分析二进制代码,找到控制跳跃的核心逻辑并修改,最终实现下面这样在空中二次起跳的效果:

第一步:从按键状态函数入手

最直接的想法是:找到跳跃按键的处理逻辑,分析它判断了哪些条件,然后有针对性地修改。

说干就干,祭出大杀器 ------ IDA Pro

检查导入函数表

逆向分析二进制文件时,第一步通常是查看 导入函数表(Imports) ,从中寻找合适的切入点。

在 Windows 系统中,键盘相关的 API 大多集中在 User32.dll 里。我们先去看看有没有熟悉的按键相关函数:

果然,在导入表中找到了按键相关函数 GetKeyState 。双击进入反汇编视图,使用交叉引用(Xrefs) 看看谁在调用它:

函数调用跟踪

顺着调用链一路追踪,我们发现了一个功能为IsKeyPressed 的函数(函数名是笔者自己加的),用于判断某个键是否被按下。

继续查看 IsKeyPressed 的交叉引用,我们来到了一个非常可疑的函数 ------ 它包含了大量的按键检测逻辑:

C 复制代码
if ( !IsKeyPressed(a1, 87) || !IsKeyPressed(a1, 73) || !IsKeyPressed(a1, 78) ) // WIN
{
    if ( IsKeyPressed(a1, 68) && IsKeyPressed(a1, 73) && IsKeyPressed(a1, 69) ) // DIE
    {
        // 调用虚函数偏移 288
        LOBYTE(v8) = (*(__int64 (__fastcall **)(_QWORD))(**(_QWORD **)(a1 + 40) + 288LL))(*(_QWORD *)(a1 + 40));
        return v8;
    }
    if ( IsKeyPressed(a1, 70) && IsKeyPressed(a1, 67) && IsKeyPressed(a1, 75) ) // FCK
    {
        // ...
    }
    // 继续处理常规按键...
}

啊哈!居然发现了隐藏的作弊码!

  • W + I + N → WIN(直接胜利)
  • D + I + E → DIE(自杀或重置)
  • F + C + K → FCK(貌似处理用户注入的代码,没仔细研究)

当然,我们的目标是二段跳,作弊码先放一边。继续往下看:

C 复制代码
if ( !a3 )
{
    sub_100039ED0();
    if ( keyCode < 0x20u )
        goto LABEL_52;
    if ( keyCode == 32 )           // 空格 → 跳跃
        goto LABEL_36;
    if ( keyCode != 37 )
    {
        if ( keyCode == 38 )       // 上箭头 ↑ → 跳跃(我们的目标!)
            goto LABEL_36;
        if ( keyCode == 39 )       // 右箭头 →
            goto LABEL_34;
        if ( keyCode != 65 )       // 'A'
        {
            if ( keyCode != 68 )   // 'D'
            {
                if ( keyCode != 80 ) // 'P'
                {
                    if ( keyCode != 87 ) // 'W'
                        goto LABEL_52;
LABEL_36:
                    *(_BYTE *)(a1 + 116) = 1;
                    if ( !*(_BYTE *)(a1 + 124) )
                        *(_DWORD *)(a1 + 120) = 0x3FB9999A;
                    goto LABEL_52;
                }
                // 'P' 键处理...
            }
            // 'D' 键处理...
        }
        // 'A' 键处理...
    }
    // 左箭头处理...
}

其中 keyCode == 38 就是我们的目标 ------ 38 是方向键"上"的虚拟键码(VK_UP) ,也是游戏中的跳跃键(W 键和空格同样会触发跳跃)。

按下跳跃键后,程序跳转到 LABEL_36

C 复制代码
LABEL_36:
    *(_BYTE *)(a1 + 116) = 1;           // 设置"跳跃请求"标志
    if ( !*(_BYTE *)(a1 + 124) )        // 关键!只有在"未跳跃"时才执行
        *(_DWORD *)(a1 + 120) = 0x3FB9999A;  // 设置跳跃力度(1.45f)
    goto LABEL_52;

第二步:分析跳跃逻辑

如果你也是游戏开发者,那么一定清楚跳跃逻辑的伪代码大概长这样:

scss 复制代码
if ( 跳跃按键按下 )
{
    if ( !是否在空中 )   // 只有在地面才能跳
    {
        是否在空中 = true;
        修改Y轴速度;
    }
}

对照伪代码我们的发现:

偏移 含义 推测
a1 + 116 跳跃请求标志 按键按下时设为 1,主循环检测后执行跳跃
a1 + 124 是否在空中 0 = 在地面,1 = 在空中 → 这就是我们要改的目标!
a1 + 120 跳跃力度参数 0x3FB9999A = 1.45f(单精度浮点数)

结论 :a1 + 124 就是阻止二段跳的"元凶"。只要让程序不再检查这个标志,二段跳就实现了。

第三步:动手术

3.1 定位关键指令

在 IDA 中找到判断 a1 + 124 的汇编指令:

图中可以看到,关键跳转指令位于地址 1000434EC

asm 复制代码
loc_1000434EC:
    cmp     byte ptr [rcx+7Ch], 0   ; 检查 a1+124 是否为 0
    jnz     loc_100043598           ; 如果不为 0(在空中),跳过跳跃逻辑

3.2 用 Cheat Engine 打补丁

打开 Cheat Engine,附加游戏进程,跳转到地址 1000434EC:

我们的目标是让程序永远认为"在地面" ,即无论 a1+124 是什么值,都不跳转。

最简单的方法:把 jnz(条件跳转)替换为 NOP(无操作)

在 CE 中右键 → "Replace with code" → 输入 NOP,然后确认:

3.3 验证效果

回到游戏,起跳,在空中再次按下跳跃键------

成功了!

现在角色可以在空中任意跳跃,真正的"梯云纵"神功已成。再复杂的地形也拦不住我了!

总结与思考

步骤 操作 工具
定位按键处理函数 IDA Pro + 交叉引用
找到跳跃逻辑(LABEL_36) IDA Pro 伪代码分析
识别"空中判断"标志(a1+124) 代码逻辑推理
定位关键跳转指令(1000434EC) IDA Pro 汇编视图
将 jnz 替换为 NOP Cheat Engine 内存补丁

核心收获:

  1. 二段跳的本质是绕过"是否在空中"的判断
  2. jnz → NOP 是绕过条件判断的通用技巧
  3. 同样的方法可以用于修改"冲刺次数"、"技能冷却"等限制

下期预告

这次我们让角色学会了二段跳,下次挑战更进阶的修改------

《突破限制:修改空洞骑士护符槽,实现"全都要"》

如果你也喜欢这类游戏逆向的内容,欢迎在评论区告诉我你想修改哪款游戏的什么机制,说不定下期就是为你量身定制的!

感谢阅读,我们下期见!

相关推荐
k3x1n3 天前
三星安卓系统BUG排查记录:云闪付、铁路12306、个人所得税、中国移动等App,长期闪退的根本原因分析
android·逆向
_Achelous4 天前
BlueArchive蔚蓝档案国际服剧情文本取得
逆向
玫幽倩11 天前
2026黄河流域公安院校-电子物证单项赛(程序逆向分析+服务器取证)
运维·服务器·python·电子取证·逆向·程序分析·服务器取证
小小工匠14 天前
当 Agent 遇上逆向:拆解 reverse-skill 的技能路由架构
架构·逆向·reverse-skill
枝头玉2 个月前
新160个CrackMe048-monkeycrackme1、049-THraw-crackme8、050-daxxor逆向分析
安全·逆向·crackme·reserve
夜猫逐梦2 个月前
【UE基础】01.环境与引擎心智模型
游戏·逆向·ue·unreal·actionrpg
嫂子的姐夫2 个月前
047-MD5:飞卢网
爬虫·python·js逆向·逆向
嫂子的姐夫2 个月前
050-wx小程序合肥住房
爬虫·python·小程序·逆向
Android小码家3 个月前
白帽子之逆向Crackme2.apk - 反调试(一)
逆向