V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
pennai
V2EX  ›  问与答

游戏内存修改器是什么原理?

  •  
  •   pennai · 2023-01-23 16:20:28 +08:00 · 3328 次点击
    这是一个创建于 699 天前的主题,其中的信息可能已经有所发展或是发生改变。
    使用过 cheat engine 这种比较通用的内存修改器,貌似是通过数值变化(你的钱从 500 变到 300 ,游戏进程内存刚好有 500 变到 300 的变量)来知道某个指标(金钱、生命)存储在哪个内存地址。

    但是对于特定游戏的修改器,如风灵月影这种,似乎不需要通过数值变化,就能知道金钱变量存储在哪个地址(相对地址,进程空间内)?我理解进程很多内存空间都是动态分配与释放的,某个变量固定在某个相对地址不太可能?
    19 条回复    2023-01-25 04:33:40 +08:00
    mokeyjay
        1
    mokeyjay  
       2023-01-23 16:24:25 +08:00
    基址了解一下
    pennai
        2
    pennai  
    OP
       2023-01-23 16:37:47 +08:00
    @mokeyjay 我知道进程有基址,我的意思是一个进程里的变量相对于基址的相对地址也不会是固定的
    wangritian
        3
    wangritian  
       2023-01-23 16:40:55 +08:00
    进程都是从 0 开始的相对地址,实际物理地址是操作系统和硬件一起管理;分配到栈空间的变量相对地址固定,比如全局变量、函数内静态变量,角色属性多半是这种;堆空间虽然是动态分配,也可以找到某个定值的地址再通过固定的偏移找到目标变量吧
    kokutou
        4
    kokutou  
       2023-01-23 16:47:00 +08:00 via Android
    @pennai
    cheat engine 自带教程做完你就懂了。
    riggzh
        5
    riggzh  
       2023-01-23 16:47:24 +08:00
    @pennai 大部分游戏都是固定的。
    kokutou
        6
    kokutou  
       2023-01-23 16:48:45 +08:00 via Android
    基址 偏移 指针 特征
    icy37785
        7
    icy37785  
       2023-01-23 17:23:48 +08:00 via iPhone
    @pennai #2 实际上绝大多数情况下都是固定的。
    mingl0280
        8
    mingl0280  
       2023-01-23 17:26:19 +08:00 via Android   ❤️ 2
    风灵月影是人家找好了地址特征码的,当然不需要扫了,CE 的 Cheat Table 也是一个原理。
    crab
        9
    crab  
       2023-01-23 17:32:54 +08:00   ❤️ 1
    相对地址,比如获取模块地址再加偏移。再智能点直接动态特征码搜索匹配。
    pennai
        10
    pennai  
    OP
       2023-01-23 18:24:35 +08:00
    @mingl0280 学习了,谢谢
    rpish
        11
    rpish  
       2023-01-24 04:12:47 +08:00
    @pennai ELF 组成和装配过程可以了解一下。
    Mutoo
        12
    Mutoo  
       2023-01-24 05:57:56 +08:00
    在游戏开发过程中,从堆中申请变量是一种非常低效的过程,所以大部分游戏在性能优化的过程中都会把变量转移到栈上,于是地址就固定下来了。
    pennai
        13
    pennai  
    OP
       2023-01-24 06:16:42 +08:00
    @Mutoo “因为变量分配在栈上所以变量的地址会固定“ 这个说法感觉和我的认知有点出入?变量即使分配在栈上,从汇编的角度,一个函数调用( procedure )结束之后,栈指针寄存器就移动到了低位(类似于 leetcode 使用双指针实现栈,弹栈的过程);下一个 procedure 调用的时候栈指针寄存器移动到高位,将新内容覆盖掉旧内容,原来的变量已经不存在了,怎么能说是固定地址呢?

    还是说其实你想表达的概念是静态存储区与堆上分配变量的区别?类似 C 系语言的全局变量在静态存储区地址不变,malloc (或说 new )、局部变量在堆或栈上分配
    Mutoo
        14
    Mutoo  
       2023-01-24 06:59:19 +08:00   ❤️ 1
    @pennai 应该是在静态存储区的意思。另外有的游戏还会自己实现内存分配,初始化会预留一个内存区域来自己分配对象空间。然后各系统依次启动。这样一来,这个初始地址相对容易被找到,之后的地址也就相对固定了。例如玩家系统一般在固定位置被分配,之后也为会被销毁。
    Mutoo
        15
    Mutoo  
       2023-01-24 06:59:46 +08:00
    @Mutoo *也不会被销毁。
    ysc3839
        16
    ysc3839  
       2023-01-24 12:09:50 +08:00 via Android
    “似乎不需要通过数值变化,就能知道金钱变量存储在哪个地址”
    是的,因为那是一开始找的过程,已经找到了当然不需要了。

    “某个变量固定在某个相对地址不太可能”
    否的,一般没谁会故意把相对偏移量都给打乱,就算打乱了,仍然可以按照它打乱的规则去读取。
    pennai
        17
    pennai  
    OP
       2023-01-24 16:17:50 +08:00
    @Mutoo 原来如此,没想到游戏开发这么接近底层,受教了
    DeltaC
        18
    DeltaC  
       2023-01-24 20:34:01 +08:00
    levelworm
        19
    levelworm  
       2023-01-25 04:33:40 +08:00 via Android
    @pennai 游戏行业经常自己实现标准库里一些功能,比如内存分配函数或者字符串函数,就是为了增加性能。比如 ID 和 EA 都公开了一部分库的代码。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4104 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 05:19 · PVG 13:19 · LAX 21:19 · JFK 00:19
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.