Lua 5.1中如何获取未文档化内置函数的参数数量与名称
Lua 5.1环境下探测游戏内置C绑定函数签名的可行方案
所有依赖debug库解析Lua字节码的参数探测方案,仅对纯Lua编写的函数生效。《Harvest: Massive Encounter》内置的
harvest.*接口都是C/C++侧注入到Lua环境的绑定函数,debug.getinfo对这类函数只会返回what = "C"的基础信息,不存在字节码层的参数元数据,针对纯Lua函数的参数名获取方案对这类接口完全无效。
1. 参数数量无侵入探测方法
可通过错误信息反推法获取C绑定函数的期望参数个数,全程在Lua层实现,不需要修改游戏文件:
C侧实现的Lua函数普遍内置参数数量校验,参数个数不匹配时会抛出固定格式的错误文本。逐次增加传参个数调用目标函数,通过pcall捕获错误后从文本中提取参数数量上限即可。
参考实现代码:
local function getCFuncParamCount(targetFunc) local maxTestArg = 20 -- 游戏Mod API参数个数不会超过该阈值 local testArgPack = {} local expectedCount = nil for i = 0, maxTestArg do local callOk, errMsg = pcall(function() targetFunc(unpack(testArgPack)) end) if not callOk then -- 匹配Lua C函数默认参数报错格式 local matchFixed = string.match(errMsg, "expects (%d+) argument") local matchRange = string.match(errMsg, "expected up to (%d+)") expectedCount = tonumber(matchFixed or matchRange) if expectedCount then break end end table.insert(testArgPack, nil) end return expectedCount or 0 end -- 调用示例 local actionBtnParamNum = getCFuncParamCount(harvest.defineActionButton) harvest.print("harvest.defineActionButton参数数量:" .. tostring(actionBtnParamNum))
如果该方法匹配不到错误文本(少数自定义实现的C函数未使用Lua默认的参数校验报错逻辑),可逐次传入不同类型的占位值,观察报错信息变化手动判断参数个数。
2. 参数名与参数语义的获取方式
Lua层没有任何方法可以直接拿到C绑定函数的参数名——这类函数的参数名只存在于游戏原生代码逻辑中,不会暴露到Lua运行环境,只能通过两种方式确认:
- 逆向游戏主程序:用逆向工具定位Lua接口注册逻辑,找到
lua_register调用对应的C函数实现,顺着函数栈读取的顺序(例如lua_tostring(L, 1)、lua_tocfunction(L, 3)这类调用),即可确认每个参数位置的类型和作用,再结合已文档化接口的命名规则对应出参数名 - 对照同类接口测试:已文档化接口
defineUpgradeButton和defineActionButton属于同组UI交互接口,Harvest库同组接口的参数顺序保持统一,可先按照已文档化接口的参数顺序传值测试运行效果,逐步验证每个位置的参数作用,效率远高于纯逆向。
内容的提问来源于stack exchange,提问作者Davey van Tilburg
相关产品推荐
相关产品推荐

