三国群英传4吧 关注:2,494贴子:38,482

三国群英传4 so文件研究

只看楼主收藏回复

一楼。
BFScript.so


IP属地:云南1楼2024-08-16 14:19回复
    so文件在Script\BFScript.so,需要自行解包出来。
    工具:WinHex,010Editor,IDA Pro 结合使用,各有优点。
    先来一类最简单的,以日月斩系列的日月轮斩为例:

    在BFMagic.ini中找到日月轮斩的编号为115,用WinHex打开BFScript.so,按Ctrl+F搜索文本BFMagic115 。
    选中这个文本的第一个位,记住它的偏移地址是78261,十六进制完整写法是0x00078261,接下来按Ctrl+Alt+X搜索十六进制数值,输入61820700,每两位数是一个字节,把这个地址倒过来写。 相关知请自行百度【小端存储】,这个必须知道不然后面头大。
    如果是用的010Editor,按Ctrl+F搜索十六进制数值。
    如果是用IDA Pro,在Hex-View窗口按Alt+B搜索,但每组数要用空格分开如此处要搜索61 82 07 00
    所有的搜索都建议键入完整的8位数值搜索,以减少值重复造成检索结果过多。
    这一步可以使用IDA Pro搜索,它会将所有搜索结果列出来,对于有重复结果的值较方便处理。

    以上总结:
    函数对应的代码在SO中的存放方式为: 函数代码指针地址+函数参数个数+函数名称指针地址+00000000
    因此我们要先搜索函数名称,获得它的偏移地址,然后搜索这个地址,找到上图函数名对应的函数代码块地址。


    IP属地:云南2楼2024-08-16 14:25
    回复
      按ALT+G跳转到BFMagic115代码块


      选中部分是日月轮斩的代码,日月斩这个系列的代码都在这片,绿框是对应技能编号,蓝框是在这个技能是增幅,默认是1轮月斩,可进游戏中看,这类技能是一个>样式,三日月斩的蓝色是1,就是上下各加一轮日月斩,共三个日月斩,而最多的就是D0这个编号208的日月轮斩2,上下各加3,共7个日月斩。调大蓝框的值,就会在默认的一轮日月斩上下各增加相应数量的日月斩。 最后这几个技能都会转入0x00038C28这个地址,执行后续部分,如伤害范围,动画加载等设定。等大家进一步研究。


      IP属地:云南3楼2024-08-16 14:27
      回复
        目前部分代码解读总结:
        3D000000 标识此处有Return,后面会接Ture返回值。否则跳到3D000000后面的False指针
        04000000 理解为call 调用它后面的函数
        06000000 理解为Push 传入后面的参数
        2C000000 大于 一般配合上面的push 某个值用,如 06000000 04000000 2C000000 为大于4
        2F000000 大于等于
        35000000 小于等于
        32000000 为小于
        0B000000 =赋值,后面一般会接变量标识符。 如 06000000 04000000 0B000000 01000000 给第一个变量赋值为4。
        26000000 ==,等于
        08000000 理解为push一个变量标识, 而06000000是push一个常量数值。
        03000000 声明局部变量数量,如果函数有局部变量基本会以03000000开头,后面跟局部变量数量。
        在函数代码中,以正数来标记局部变量,以负数来标记传进来的参数,FEFFFFFF为最后一个传参,FDFFFFFF为倒数第二个传参,以此类推。判断第一个传参是多少结合之前【函数地址+参数数量+函数名地址】映射处来推算。
        也就是看到08000000 FEFFFFFF这种数就是函数的参数,如果是08000000 01000000 这种就是第一个局部变量。


        IP属地:云南5楼2024-08-16 14:57
        收起回复
          另一例


          IP属地:云南6楼2024-08-16 15:13
          回复

            比如选中的代码就是 如果第三个局部变量小于等于0,就返回紫色的值0。否则跳转到0x000734BC


            IP属地:云南7楼2024-08-16 15:19
            回复
              一些固定的设置知道定义后可直接搜索 140000002F0000000,即大于等于20,全so就两处,再结合上下有血量判定的是挑斩,另一处为生擒,进游戏测试正确。 当然也可以按上面跑函数一直跑到这一块代码


              IP属地:云南10楼2024-08-16 18:33
              回复
                Switch语句例子:


                IP属地:云南11楼2024-08-16 23:46
                回复
                  另外一种不同于日月斩的,本来想传SJ的,老河蟹了。看看伏兵的


                  IP属地:云南14楼2024-08-16 23:56
                  回复
                    厉害


                    IP属地:广西来自Android客户端15楼2024-08-17 00:22
                    回复
                      BFScript.so文件结构分析


                      IP属地:云南16楼2024-08-17 10:27
                      回复
                        命令汇总:
                        0F000000 加
                        12000000 减
                        14000000 乘
                        16000000 除
                        1D000000 ++ 后面跟自增对象
                        20000000 -- 后面跟自减对象
                        3F000000 >> 右移 08000000 01000000 06000000 01000000 3F000000 0B000000 FEFFFFFF 局部变量1右移1位赋值给变量FEFFFFFF
                        3E000000 << 左移
                        2C000000 大于 一般配合上面的push 某个值用,如 06000000 04000000 2C000000 为大于4
                        2F000000 大于等于
                        32000000 小于
                        35000000 小于等于
                        26000000 ==,等于
                        29000000 ≠,不等于
                        0B000000 =,赋值,后面接要赋值的变量标识符。 如 06000000 04000000 0B000000 01000000 给第一个变量赋值为4。
                        1A000000 表示前面push的是负数 如 06000000 02000000 1A000000 表示-2
                        06000000 理解为Push 传入后面的参数 ,push一个常量数值
                        07000000 push一个so中的字符串编号,后面接编号,再接3个4字节的数,目前不清楚这3个dword的含义。
                        08000000 理解为push 一个变量标识, 而06000000是push一个常量数值。
                        3D000000 if判断 前面的条件如果为否跳转后面接着的指针地址,如果为真就跳到否指针后的位置继续执行
                        3B000000 理解为jmp,强制跳转到后面接着的指针地址
                        04000000 理解为call so中的其他函数,后面跟so函数偏移地址
                        05000000 表示call exe主程序中定义的函数,后面跟的是函数的编号。 很多重要的函数都在exe中,so上做一些简单的判断后push各种参数到主程序中的函数
                        01000000 return,返回前面push的常量或者变量并退出该函数,后面接该函数的参数个数。
                        03000000 标识局部变量个数。出现在函数最开头(如果该函数有局部变量)。在so函数代码中,以正数来标记局部变量,以负数来标记传进来的参数,如FEFFFFFF为最后一个传参,FDFFFFFF为倒数第二个传参,以此类推。判断第一个传参是多少要结合之前标识的函数参数量来推算。 如08000000 01000000表示第一个局部变量 , 08000000 FEFFFFFF 表示一个接收到的第一个参数
                        如果遇到连续的40000000 + 常数 + 偏移地址, 最后0E000000的结构 是 Switch结构,每个40对应一个case和对应的跳转地址, 0E是Default接3B跳转出switch。


                        IP属地:云南17楼2024-08-17 11:17
                        收起回复
                          做一个简单的改代码的举例,这里不要去管so的文件结构,因为程序就按给定的指针运行代码,直接改变指针地址即可。
                          实验对象,更改必杀技判断代码,让它直接返回否。
                          思路:
                          1、在SO文件末新增一段空白区域,此例只需要增加16个字节,用于返回0, 即返回假,让程序判定不能使用必杀。这里要记住新增的偏移地址是:0x7FFF0。
                          增加06000000 00000000 01000000 02000000,大意就是push 0 ,然后返回0这个值。最后的02是参数个数,这里对应映射表处的参数数量即可,不重要。
                          2、搜CanUseThisSuperAttack对应的代码指针映射,是0x6F3CC,注意不能直接在映射表这里把6F3CC改成7FFF0,因为必杀调用的是0x6F3CC这一地址的代码,不是调用CanUseThisSuperAttack。
                          3、转到偏移0x6F3CC的偏移地址,直接将前面修改为3B000000 F0FF0700,就是jmp到0x7FFF0,文件末尾新增的代码。
                          4、进游戏测试发现必杀已经都发不了,实验成功。
                          5、如果你想看看对比可以将第一项的开头改成06000000 01000000就是返回真,再进游戏就发现必杀又能用了。
                          6、这只是一个简短而又简单的测试,用来验证扩充so文件代码内容的可行性。


                          IP属地:云南18楼2024-08-17 13:14
                          回复
                            分析一个拖刀:


                            IP属地:云南19楼2024-08-30 11:30
                            收起回复
                              来一个最直观的对比代码对比:


                              IP属地:云南20楼2024-09-05 19:12
                              回复