金鱼师父 发表于 2017-4-6 23:14

关于2.07的mod失效问题调查 以及解决(提供可用的反编译工具,4月13上传反编译工具luadec),附带示例mod代码

本帖最后由 金鱼师父 于 2017-4-30 10:27 编辑

今晚研究了一下,基本确定2.07的在lua字节码层面不再兼容
昨天下好了游戏,今天开始写mod,然后发现论坛介绍的方法都失效了,表现为无法反编译源文件。
通过对比文件头和调试luadec:github.com(不)/(能)viruscamp/(发链接)luadec,
以及从新版lua文件头可正常读取的信息判断,有两个变化:
1 2.07的lua版本从5.1升到了5.3
2 供应商自己修改了文件头校验规则

问题2我自己通过简单修改lua源码解决了,下边百度盘是新编译的luadec
问题1没能解决,luadec可以反编译但错误多,unluac我找到的版本最多支持到5.2

对于一般玩家,你们只需要知道,所有字节码mod都失效了。
既然有人还能用之前mod,那么说明未编译的mod依然有效,剩下的问题无非是 1 兼容新源码的其他文件 2 兼容lua5.3新语言特性
lua5.3有setfenv->_ENV等几处变化,具体请自查。

因为luadec对5.3反编译的bug太多,我决定不再通过修改源码的方式来实现mod,改为挂钩函数或修改全局数据等方法。


是我修改过的luadec,可以反编译2.07的字节码:
pan.blacksheepgame.com(删除)/s(删除)/1bG8HPG
要注意反编译可能有错,错误参考:
github.com(删除)/viruscamp(删除)/luadec(删除)/issues
所以这个工具大家用来读源码就是了,编译结果务必慎用----------------
补充:为什么我不直接将2.06的lua.hpk替换掉2.07的呢,因为地图文件也带lua脚本,我还没确认2.06的脚本和2.07的地图有无兼容问题---------------
2.06和2.07代码确实有些不同,比如loottable里项的格式。2.06的一项是{1,1,1,func},2.07则变为{1,1,1,'',func},增加了一个字符串。这就可能导致修改掉落表的mod失效。
另外如果mod运行错误,2.07不会给出任何提示,要么不加载mod,要么不能正常进入游戏,请modder自己加好日志功能,用pcall捕捉错误

使用本版mod教程方式安装lua,下边是我的示例文件

ZZZ.lua

local logfl = false
local function log(...)
      logfl=logfl or io.open('D:/ErrorLog.txt','w') --日志文件路径
      logfl:write(...)
      logfl:flush()
end

local function floor(v)--因为游戏lua虚拟机禁用了math库,游戏参数又需要是整数,所以自己实现一个math.floor
      if v < 1then return 0 end
      
      local n=128

      while n < v do
                n = n << 1
      end
      
      while n > v do
                n = n >> 1
      end
      
      local r=n
      
      while n > 1 and r < v do
                n = n>>1
                local i=r+n
                if i <= v then
                        r=i
                end
      end
      
      return r
end

local function main()
      local function multi_g(t)--挂钩函数示例,效果,物品数量x10
                local fun=t[#t]
                t[#t] = function(...)
                        local r=fun(...)
                        if r then
                              r.stack = r.stack*10
                        end
                        return r
                end
      end

         local function genmod(m)
                local l = m.obj.Level

                assert(l and l > 0, 'Invaild self.obj.Level')
                m.obj:SetModifiers(m.equip_id,{                              movement_speed = floor(l^0.5 * 25),                              attack_speed=floor(l^0.8 * 15),                              weapon_lifesteal = floor(l^0.5),                              max_overdrive_add = OverdriveBar*floor(l/5),                              overdrive=floor(100 * l^0.6),                              health=200*l,                              armor=10*l,                              adm=10*l,                              armor_penetration=5*l})

      end
--自定义modifyer,作为等级1的效果,卡片和升级奖励都通过modifyer实现      
      DefineClass.SA_YOURMOD = {
                __parents = {"SA_Effect"},
                proc_events = {"recalc"},

                Proc=function(self)
                        local suc,m = pcall(genm,self.obj.Level)
                        if not suc then
                              log('ERROR:\r\n'..m)
                        end
                        return true
                end
      }

      multi_g(LootTable.Gold)
      multi_g(LootTable.Gold_small)
      multi_g(LootTable.Gold_medium)
      multi_g(LootTable.Gold_large)
--金钱 x 10
      table.insert(LevelRewards.effects,'SA_YOURMOD ')
--修改升级奖励      
      SA_Level_5_E1.modifiers.destiny_points = 6
      SA_Level_10_E1.modifiers.destiny_slots = 2
      SA_Level_11_E1.modifiers.destiny_points = 6

--修改掉落率      
      local function avgloot(t,weight)
                for _,v in ipairs(t) do
                        v = floor(sqrt(v)) + weight
                end
      end
      
      avgloot(LootTable.DefaultLoot,32)
      avgloot(LootTable.DefaultChest,8)

      for name, it in pairs(LootTable) do
                --log('\r\n'..name..'-----')
                if type(it) == 'table' and name:sub(1+#name-#'Minion') ~= 'Minion' then
                        for nth, v in pairs(it) do
                              if type(v)=='table' and v == 'none' then
                                        assert(#v==5, '#v==5')
                                        --log(name..':'..nth..'='..v..'')
                                        v=Max(1,floor(v/10))
                              end
                        end
                end
      end


end

local suc,msg=pcall(main)
if not suc then
      log('ERROR:\r'..msg)
end-----------------------------------
首先感谢
junwenqing




同学给我的旧版代码,然后补充:最近发现那个java版的unluac也有反编译错误,有的地方把...参数给反编译没了

那么现在可以说,对于所有的luaMod,无论2.07还是之前,都不建议修改原来的文件,因为你反编译出来的源码就可能错了


金鱼师父 发表于 2017-4-7 23:14

修改lua的lundump.c搞定了文件头匹配等问题,现在编译的特供版luadec可以看个大概了,虽然因为luadec自身的问题充满大量decomplier error,但现在代码大体可读了。就是不知道论坛怎么上传exe。

宅下大人 发表于 2017-4-9 14:45

这里变鬼区了?

金鱼师父 发表于 2017-4-10 16:48

宅下大人 发表于 2017-4-9 14:45
这里变鬼区了?

新人不清楚,mod问题不发这里吗,我看还有个mod简易教学啊

宅下大人 发表于 2017-4-10 17:08

那你现在的V2.07用什么MOD呢我的也都不好使了目前在裸奔:)

金鱼师父 发表于 2017-4-10 19:21

宅下大人 发表于 2017-4-10 17:08
那你现在的V2.07用什么MOD呢我的也都不好使了目前在裸奔

什么都没用,这两天有空就给luadec排错。现在可以得到正确的lua字节码,但逆向成lua代码错误太多。

junwenqing 发表于 2017-4-11 23:38

本帖最后由 junwenqing 于 2017-4-11 23:47 编辑

http://pan.blacksheepgame.com/s/1c4DCRG 这是旧的,哪个版本的不清楚
2.06 2.07 的MOD可以用旧版本反编译的源码
改过的覆盖掉游戏目录里的Lua.hpk生效

金鱼师父 发表于 2017-4-13 17:35

junwenqing 发表于 2017-4-11 23:38
http://pan.blacksheepgame.com/s/1c4DCRG 这是旧的,哪个版本的不清楚
2.06 2.07 的MOD可以用旧版本反编译的源码
改 ...

多谢,我现在采取比较费劲的办法,不再修改源代码,而是通过mod在加载时修改原本数据(比如loottable)和挂钩原本函数来实现修改

junwenqing 发表于 2017-4-14 21:30

本帖最后由 junwenqing 于 2017-4-14 21:40 编辑

此区已鬼:lol

问下:用了LZ工具为什么反编译结果不能输出到文件?



金鱼师父 发表于 2017-4-15 20:35

junwenqing 发表于 2017-4-14 21:30
此区已鬼

问下:用了LZ工具为什么反编译结果不能输出到文件?

加上 >文件名。看附带bat,或者搜索一下重定向这个古老的命令行技巧

宅下大人 发表于 2017-4-24 08:47

楼主研究出结果了别忘了造福一方百姓,虽说这一方也没几个人:lol

金鱼师父 发表于 2017-4-30 10:24

宅下大人 发表于 2017-4-24 08:47
楼主研究出结果了别忘了造福一方百姓,虽说这一方也没几个人

已经研究好了啊,示例代码也贴了,哪儿不明白我来解释

lf8850789 发表于 2017-6-10 09:55

楼主有做好的么,小白是在看不懂

昊巍 发表于 2017-6-10 16:49

楼主,可不可以求个简单的,就修改下命运卡槽和命运点数的mod就行了。

qwe369696 发表于 2017-7-2 01:56

楼主发布的内容相当不错

w4334417 发表于 2017-7-4 16:43

关注楼主   有没有最新的进展或者楼主有没有好的成品能瞻仰下吗?

翼在天 发表于 2017-7-15 22:18

一头雾水:L

919235953 发表于 2017-8-4 00:19

本帖最后由 金鱼师父 于 2017-4-30 10:27 编辑

今晚研究了一下,基本确定2.07的在lua字节码层面不再兼容
昨天下好了游戏,今天开始写mod,然后发现论坛介绍的方法都失效了,表现为无法反编译源文件。
通过对比文件头和调试luadec:github.com(不)/(能)viruscamp/(发链接)luadec,
以及从新版lua文件头可正常读取的信息判断,有两个变化:
1 2.07的lua版本从5.1升到了5.3
2 供应商自己修改了文件头校验规则

问题2我自己通过简单修改lua源码解决了,下边百度盘是新编译的luadec
问题1没能解决,luadec可以反编译但错误多,unluac我找到的版本最多支持到5.2

对于一般玩家,你们只需要知道,所有字节码mod都失效了。
既然有人还能用之前mod,那么说明未编译的mod依然有效,剩下的问题无非是 1 兼容新源码的其他文件 2 兼容lua5.3新语言特性
lua5.3有setfenv->_ENV等几处变化,具体请自查。

因为luadec对5.3反编译的bug太多,我决定不再通过修改源码的方式来实现mod,改为挂钩函数或修改全局数据等方法。


是我修改过的luadec,可以反编译2.07的字节码:
pan.blacksheepgame.com(删除)/s(删除)/1bG8HPG
要注意反编译可能有错,错误参考:
github.com(删除)/viruscamp(删除)/luadec(删除)/issues
所以这个工具大家用来读源码就是了,编译结果务必慎用----------------
补充:为什么我不直接将2.06的lua.hpk替换掉2.07的呢,因为地图文件也带lua脚本,我还没确认2.06的脚本和2.07的地图有无兼容问题---------------
2.06和2.07代码确实有些不同,比如loottable里项的格式。2.06的一项是{1,1,1,func},2.07则变为{1,1,1,'',func},增加了一个字符串。这就可能导致修改掉落表的mod失效。
另外如果mod运行错误,2.07不会给出任何提示,要么不加载mod,要么不能正常进入游戏,请modder自己加好日志功能,用pcall捕捉错误

使用本版mod教程方式安装lua,下边是我的示例文件

ParfoisMeng 发表于 2018-4-22 21:58

厉害厉害。。目前github已经5.3.4了,请我咋制作exe和bat的?

卧龙千雪 发表于 2018-5-11 03:00

对于小白的我完全是一脸懵逼状态

webber2020 发表于 2018-10-9 10:08

看不懂啊

webber2020 发表于 2018-10-9 12:51

太复杂了

webber2020 发表于 2018-10-9 17:26

不行,最新版无法反编译
页: [1]
查看完整版本: 关于2.07的mod失效问题调查 以及解决(提供可用的反编译工具,4月13上传反编译工具luadec),附带示例mod代码