zoukankan      html  css  js  c++  java
  • 学习逆向知识之用于游戏外挂的实现.第二讲,快速寻找植物大战僵尸阳光基址.以及动态基址跟静态基址的区别

                  通过游戏外挂,学习逆向技术之快速寻找植物大战僵尸阳光基址.以及动态基址跟静态基址的区别

    一丶静态基址. 动态基址. 基址的区别

     通过上一讲超级马里奥的游戏外挂技术制作.我们学习到了静态基址.以及观看内存区域得出相关偏移出的静态基址.

    那么什么是静态基址.什么是动态基址. 什么是基址.

    1.静态基址

      静态基址指的是.程序在启动后地址是不变的.游戏关闭后重新启动.那么地址也是不会变的.我们通过逆向技术直接对其修改那么则可以进行我们的外挂制作.

    2.动态地址.

      动态地址是指当前地址保存了我们想要的属性信息. 但是当游戏重新打开.的时候.其当前地址的信息已经不是我们的信息了.所以我们要寻找基址.

    3.基址

      基址指的就是最顶层的地址. 这个地址是不会改变的.除非游戏重新编译.或者增加减少成员.

    二丶以植物大战僵尸为例.寻找当前动态地址.

    植物大战僵尸这款游戏.相信我们大家都应该玩过.那么我们通过这款游戏.来学习 动态地址. + 基址的寻找方法. 

    文字简介:  CE附加植物大战僵尸进程 -> 搜索阳光数量(精确数值 4字节搜索) -> 改变阳光数值 -> CE再次搜索改变之后的数值.

    改变阳光数值.点击再次扫描.进行新的搜索.

    通过在次扫描之后.我们得出一个地址.这个地址是一个动态地址. 怎么判断是否是动态地址.

    1.我们首先修改这个地址里面的值. 看看是否能把阳光修改 (已经测试.可以修改.不截图说明了)

    2.我们重新打开游戏.看看当前地址里面的值是否是我们阳光的值. (不是,已经测试)

    经过上面两个步骤.我们可以得出.这个地址是一个动态地址.所以我们还要继续向上寻找.

    三丶寻找基址.

      通过上面的地址我们知道这一个是一个动态的地址.那么我们需要找到基址应该怎么寻找?

    思路: 如果找到一个动态地址.那么修改阳光肯定会修改这个地址这个地址里面的值. 所以我们可以下一个写入断点

    1.我们可以用CE 下写入断电. 找出什么修改了这个地址

    2.我们可以用OD / x32Dbg 下写入断点

    上面两种方式都是可以完成的.

    我们双击打开反汇编

    可以看到里面的值是 add[eax + 0x5560],ecx

    那么我们寻找到了一级偏移. 5560

    那么这里涉及到偏移. 我们讲下原理吧.

    其实很简单.植物大战僵尸编写的时候都是对象或者结构体成员.

    例如:

      

    struct Plant
    {
       
        ......
        int sunNumber;  
    }

    而在汇编指令中则是 结构体到地址 + 偏移 得出 阳光的个数.

    所以我们要继续寻找结构体首地址. 也就是谁保存了结构体首地址.所以根据上图汇编得出.我们需要继续寻找eax

    继续寻找eax

    CE 以16进制搜索eax的值

    根据上图可以得出. 一个地址里面保存了结构体的值. 那么猜想这个可能就是结构体的首地址了.我们使用CE的手动添加地址添加我们的偏移看一下.

    我们也不知道上面的地址那个是保存了结构体的地址. 不过CE一般都是前五个.当前也不一定.可以尝试一下.

    根据上图我们可以得出 0299a4a0地址的内容是结构体首地址. 根据CE的手动添加指针.我们加上我们的偏移.可以得出阳光的地址.(对地址取内容则是阳光的值)

    现在我们找的这个地址还是一个动态地址. 所以我们要找一下什么访问了这个地址为什么是访问? 因为要操作阳光.肯定会访问这个地址. 如果修改阳光则会修改这个阳光的值.

    因为这个地址保存了结构体首地址.那么他肯定不会改写了.所以肯定会访问.所以我们找一下访问的地址.

     根据上图的值, 看汇编代码得出 mov esi[edi + 0x768] 访问了这个地址.

    那么同理 [edi + 0x768]保存了结构体的地址. 那么edi 是一个新的结构体的地址. 而我们进行搜索的时候会发现其实这是一个结构体的嵌套.

    例如:

      

    struct aaa
    {
        .......
        struct plant plant    //0x768
        {
            int SunNumber;  //0x5560
        }
    }

    所以我们要继续寻找edi是谁保存了.

    继续寻找edi的值我们发现有几个绿色的值.一般遇到这个很有可能是基址了.

    那么我们尝试一下.使用CE自带的手动添加地址.

    确实是我们的地址.那么我们继续看谁访问.

    发现我们地址都是这样了.汇编指令 mov reg,[常量地址]   那么则确定我们找到了我们的基址了.

    原理:

      如果对基址不太熟悉.那么熟悉C++语法的大概能明白.

    struct aaa
    {
        struct plant
       {
              int SunNumber;
       }
    }
    
    
    aaa *p= new aaa;
    
    new aaa 是我们的结构体首地址
    
    new aaa + 768 = plant结构体的首地址
    
    new aaa + 768 + 5560 = 阳光个数的地址
    
    那么我们知道 new aaa是一个无名对象.所以肯定有一个变量保存着.
    所以 *p 这个变量就是我们寻找的基址.
    
    p + 768 + 5560 = 阳光个数地址
    *(p + 768 + 5560 ) = 阳光个数.
    所以我们找的基址就是p的地址. 而p保存的就是 new aaa的地址 new aaa中保存了 plant结构体的地址.

    如果不理解也可以滤过. 熟悉我们的寻找方法即可.

    通过上面我们的汇编指令.

    add [reg + 0x5560],ecx       注意reg代表是任何寄存器.   add指令在汇编中是增加的意思. []的意思是对这个地址的内容进行操作

    上面的汇编指令的意思是: 对 reg + 5560 的这个地址进行操作.因为带有中括号.[] 所以意思是对reg + 5560这个地址里面的值进行操作.

    mov reg,[reg + 0x768]. 内容同上.  mov 指令是传送指令.  也就是将这个地址里面的值辅赋值给左操作数.

    [[[6A9EC0] + 0x768] + 0x5560] = 阳光的地址.

    所以我们可以写程序来实现增加阳光跟减少阳光了

    C++ :  学习OpenProcess  WriteProcessMemory  //注意: 在调用OpenProcess获得进程句柄前.需要获得进程PID.  可以通过FindWindow 查找窗口句柄.然后通过GetWindowsThreadProcessID() 通过窗口句柄获取进程pID. 当前也可以通过 进程快照.遍历进程.得出进程PID.都是可以的.具体不在累赘. 

    易语言: 因为使用了超级模块所以 熟悉 取进程ID  十六到十 写内存整数型即可.

    因为易语言实现简单.所以直接使用易语言写一个了.

     总结:

      通过这一讲.我们学习了 add 汇编指令. mov 汇编指令. 以及结构体在汇编中表现的形式. 例如 [reg + 5560] 这样的其实是结构体偏移.

    学会了如果通过动态地址寻找基址.

    课堂资料下载:  链接:https://pan.baidu.com/s/1DDWfx68wi37Dc2OV2aTpqQ 密码:3w2x

  • 相关阅读:
    VUE中引入zTree
    如何获取别人提供的接口,获取他接口里面的数据。
    com.fasterxml.jackson.databind.exc.InvalidDefinitionException
    2.Elasticsearch环境安装配置
    1.Elasticsearch概述
    Java中如何操作Redis
    基于Redis实现分布式锁
    Mybatis插件--数据库读写分离
    Mybatis插件--自定义分页
    7. Mybatis日志
  • 原文地址:https://www.cnblogs.com/iBinary/p/9513105.html
Copyright © 2011-2022 走看看