Lua代码混淆-Prometheus方案教程
一.什么是代码混淆
代码混淆 是一种通过修改源代码或编译后的代码,使其变得难以理解和分析,但同时保留其原有功能不变的技术。其是一种重要的软件保护措施,通过在保持功能不变的前提下,降低代码的可读性,来对抗逆向工程和恶意篡改。
二.主要目的
2.1 提高破解成本
代码混淆可以防止被轻易破解、修改(如绕过付费验证、制作外挂)。
2.2 让游戏通过平台(如AppStore)审核
若游戏被下架,想再上架的话,需要让游戏内的资源和代码尽可能与之前不同,混淆可以满足这点需要
三.常见混淆做法
3.1标识符重命名
-
做法:将代码中有意义的类名、方法名、变量名替换成无意义的短字符串。
-
示例:
-
混淆前:
calculateTotalPrice(),userAccountBalance -
混淆后:
a(),b,c1
-
3.2 控制流混淆
-
做法:改变代码的执行流程,例如添加无用的条件语句、循环,或者将顺序执行的代码拆分成多个跳转块,从而制造“面条式代码”。
-
示例:一个简单的
if-else语句可能被转换成switch语句和goto跳转的复杂组合,使执行路径难以跟踪。
3.3 冗余代码插入
-
做法:在代码中插入永远不会被执行到的代码块,或者执行了但不对结果产生任何影响的代码,用以干扰分析者。
四.Prometheus混淆方案
4.1 初识Prometheus
Prometheus是由纯Lua实现的Lua代码混淆方案
gitHub:https://github.com/prometheus-lua/Prometheus
解压后目录如下图

4.2 SUMMARY.md
接下来首先要看doc目录下的所有文档,来获取有用信息

先来看SUMMARY.md,其介绍所有文档的作用

4.3 obfuscating-your-first-script.md
文档obfuscating-your-first-script,其展示使用命令进行混淆
lua ./cli.lua --preset Medium ./hello_world.lua
要掌握的是--preset Medium参数来设置混淆强度,有4个强度可选中
* Minify
* Weak
* Medium
* Strong

接下来进行实践,先创建一个hello_world.lua文件,打印Hello World;
执行命令行:lua ./cli.lua --preset Medium ./hello_world.lua
其会创建混淆后的脚本 hello_world.obfuscated.lua
执行新的脚本,其也是打印Hello World,功能没有改变
print("Hello World")

打开hello_world.obfuscated.lua查看混淆后内容,完全没有可读性

4.4 using-prometheus-in-your-lua-application.md
文档介绍在项目内把Prometheus-master目录用作一个代码库,具体用法是可以使用其内的文件和函数,将字符串加工成混淆后的不可阅读新字符串

五.Prometheus在Unity ToLua框架下的混淆实践
5.1.Unity中导入目录Prometheus-master
Prometheus-master放到哪个位置下是首先要考虑的问题,在Assets下全局搜索AddSearchPath可以帮我们做出决定

将Prometheus-master放到Lua目录下,并改名为PrometheusMaster

5.2.编辑Lua代码
将using-prometheus-in-your-lua-application.md的代码进行整理和编辑,我们需要一个方法接受一个文件的文本,返回混淆后的文本,代码如下
function Game.LuaFileConfuse(str)print("***************** do LuaFileConfuse", str)local Prometheus = require("prometheus")local pipeline = Prometheus.Pipeline:fromConfig(Prometheus.Presets.Minify)local result = pipeline:apply(str);return result
end
注意实测将local Prometheus = require("prometheus")这行放到文件最上面的话打包后的apk会有报错,故将其放到方法内
5.3.编辑C#代码
在某Editor下开发编辑器代码,该方法遍历指定目录下所有的lua文件,读取文本内容,传给Lua的混淆方法,再将返回的字符串写入文件
[MenuItem("Tools/Obfuscate Lua Files")]public static void ObfuscateLuaFiles(){string luaPath = Application.dataPath + "/LuaFramework/Lua/View2/";var files = Directory.GetFiles(luaPath, "*.lua", SearchOption.AllDirectories);foreach (var file in files){string originalCode = File.ReadAllText(file);string obfuscatedCode = Util.InvokeLuaMethod<string, string>("Game", "LuaFileConfuse", originalCode);File.WriteAllText(file, obfuscatedCode);}AssetDatabase.Refresh();}
5.4 解决报错
接下来执行菜单,会产生若干报错,需逐一解决

5.4.1 增加搜索目录
lua.AddSearchPath(rootPath + "/Lua/PrometheusMaster/src");
5.4.2 prometheus.lua

5.4.3 config.lua

5.4.4 pipeline.lua

六.混淆和运行测试
再次执行混淆菜单,可以看到View2下文件都产生变化了

随便点开一个文件查看变化,混淆效果已生效

运行游戏后,可以看到功能正常运行
