目录
一、导入工具
收费版:Obfuscator Pro | Utilities Tools | Unity Asset Store
免费版:Obfuscator Free | Utilities Tools | Unity Asset Store
Unity 2019.4.0f1 使用免费版
注意AssetStore点击添加到的是5.0版本,实际可能会不兼容你所在的Unity版本,故需要重启Unity,再次打开My Assets找到Obfuscator Free再Import,若网络不正常请检查是否开启了代理,需关闭代理。
导入成功后会看到如下内容
再导入一个NewtonsoftJson插件:com.unity.nuget.newtonsoft-json
准备一个查看dll的工具 ILSky(本次测试只看Window平台打包后的混淆代码)
https://sourceforge.net/projects/ilspy.mirror/files/v9.0/ILSpy_Installer_9.0.0.7889-x64.msi/download
注意这个ILSky也有版本区分,上面是是给window系统用的,其他系统对应找对应的版本下载。
创建Test.cs脚本添加如下常用代码,TestA是一个程序集文件
using Newtonsoft.Json;
using UnityEngine;
namespace TestA
{
public class Space
{
public int width;
public int height;
public int depth;
}
public class Test : MonoBehaviour
{
string json = "{\"width\":666,\"height\":777,\"depth\":1000}";
void Start()
{
Space space = JsonConvert.DeserializeObject<Space>(json);
PrintSpace(space);
}
void PrintSpace(Space space)
{
Debug.Log(space.width);
Debug.Log(space.height);
Debug.Log(space.depth);
}
}
}
二、各种混淆形式介绍
2.1 程序集混淆
混淆后
屏蔽TestA.dll混淆
2.2 命名空间混淆
将Test.cs脚本的命名空间从Test改为TestA_NameSpace(方便观察区分)混淆后
屏蔽TestA_NameSpace混淆
尚不清楚有何作用的选项,不需要开启这个。
2.3 类混淆
可能由于是免费版,故有这种黄底颜色的混淆无法使用。
屏蔽混淆泛型类,例如上面的Space_Generic<T>泛型类,其他类会正常混淆。
2.4 函数混淆
屏蔽Public类型函数
2.5 参数混淆
正常混淆
屏蔽混淆函数参数后会如下
2.6 字段混淆
2.7 属性混淆
屏蔽公共属性混淆
2.8 事件混淆
屏蔽公共事件混淆
三、安全混淆
四、兼容性处理
4.1 动画方法兼容
动画帧调用的脚本方法不会被混淆
测试取消这个兼容,也一样会忽略混淆。
4.2 GUI方法兼容
4.3 协程方法兼容
关闭兼容后
其中CoroutineFunc2和CoroutineFunc3会找不到报错,所以需要开启兼容,即不会对协程方法进行混淆处理。
即使添加传参,也是没有对参数进行混淆的,不过有些局部参数名有混淆。
因此如果想对协程方法进行混淆,要保证全部调用协程方法的形式是
StartCoroutine(CoroutineFunc1());
并关闭兼容协程方法处理
五、选项
5.1 调试日志输出目录定义
默认日志文件
5.2 标签属性设置
参考:Attributes | GuardingPearSoftware documentation
原有[DoNotRename]标签忽略混淆名称,现在可以自定义标签属性如下:name参数是非必要的
作为一个忽略混淆名称使用,例如忽略混淆这个方法名。
5.3 混淆映射文件
如上图我启动了映射文件,并设置了一个文本文件路径作为保存的文件路径,内容是保存各种映射关系。
测试映射文件作用,可以将错误日志反混淆显示;
案例:故意搞一个错误的代码,如下:
使用Log Viewer调试插件看打包后报错日志
Log Viewer | Integration | Unity Asset Store
导入后需要创建调试器物体在场景上
打包查看
打包运行 查看报错日志,发现是混淆名称
开启混淆映射文件
测试发现依旧没有变化,即并没有改动实际运行时的日志输出,只能通过这个工具查看反混淆后的日志
通过ILSpy查看ErrorStackEditor内容,可以通过如下方法动态执行上面这个过程来加速我们的反混淆日志文件速度。
public string Deobfuscate(string obfuscatorText)
{
//OPS.Obfuscator.Editor.dll是ErrorStackWindow所在的程序集文件
Assembly assembly1 = Assembly.LoadFile("Assets/OPS/Obfuscator/Editor/Plugins/OPS.Obfuscator.Editor.dll");
Type type = assembly1.GetType("OPS.Obfuscator.Editor.Gui.ErrorStackWindow");
var instance = EditorWindow.GetWindow(type);
//1、填写 File Path 字符串对象,如果想了解可以打开ILSky查看 可能不同版本的混淆情况不同
//1.1 从程序集找到232类型(相当于Text组件)
Type type232 = assembly1.GetType("232");
//1.2 找到232类型的1550属性(相当于Text.text属性)
var property232_1550 = type232.GetProperty("1550", BindingFlags.Instance | BindingFlags.Public);
//1.3 获取ErrorStackWindow类的名为1382的私有字段(相当于Text组件字段)
var field1382Info = type.GetField("1382", BindingFlags.Instance | BindingFlags.NonPublic);
//1.4 获取instance实例的1382字段(相当于获取ErrorStackWindow对象里的名为1382字段,它是一个Text组件对象)
var v1382 = field1382Info.GetValue(instance);
//1.5 将映射文件路径填充到v1382.text字段,v1382是一个Text对象
property232_1550.SetValue(v1382, @"E:\UnityProject\UnityHunXiaoObfuscatorProDemo\Assets\Scripts\TestA\ObMapFile.json");
//2 填写输入文本(混淆内容文本)
//2.1 获取程序集的221类型(相当于Area组件)
Type type221 = assembly1.GetType("221");
//2.2 获取221类型的1550属性(相当于Area.text属性)
var property221_1550 = type221.GetProperty("1550", BindingFlags.Instance | BindingFlags.Public);
//2.3 获取ErrorStackWindow类的名为1383的私有字段(相当于Area组件类型名为1383的字段)
var field1383Info = type.GetField("1383", BindingFlags.Instance | BindingFlags.NonPublic);
//2.4 获取instance实例的1383字段
var v1383 = field1383Info.GetValue(instance);
//2.5 将混淆内容文本填充到v1383.text字段,v1383是一个Area对象
property221_1550.SetValue(v1383, obfuscatorText);
//3 执行ErrorStackWindow的662方法,会将ObMapFile.json文件反序列化 准备解析混淆内容文件
var method662 = type.GetMethod("662", BindingFlags.Instance | BindingFlags.NonPublic);
method662.Invoke(instance, null);
//4 执行ErrorStackWindow的667方法,会将混淆内容文本解析完成输出到1384(Area组件)
var method667 = type.GetMethod("667", BindingFlags.Instance | BindingFlags.NonPublic);
method667.Invoke(instance, null);
//5 将Area组件的文本获取并返回
//获取1384(Area组件)的1550字段内容(Area.text)
var field1384Info = type.GetField("1384", BindingFlags.Instance | BindingFlags.NonPublic);
var v1384 = field1384Info.GetValue(instance);
return (string)property221_1550.GetValue(v1384);
}
使用方法:
Debug.LogError(Deobfuscate(@"NullReferenceException: Object reference not set to an instance of an object
at TestA_NameSpace.Test.cl (TestA_NameSpace.h`1[a] a) [0x00003] in <7a98e657ea8f45a0ac3ccc399b375f23>:0
at TestA_NameSpace.Test.Start () [0x00026] in <7a98e657ea8f45a0ac3ccc399b375f23>:0 "));
若无法正常使用,说明你的Obfuscator Free版本和我不一样,它的混淆情况也不一样。