【Unity3D】Unity混淆工具Obfuscator使用
目录
一、导入工具
二、各种混淆形式介绍
2.1 程序集混淆
2.2 命名空间混淆
2.3 类混淆
2.4 函数混淆
2.5 参数混淆
2.6 字段混淆
2.7 属性混淆
2.8 事件混淆
三、安全混淆
四、兼容性处理
4.1 动画方法兼容
4.2 GUI方法兼容
4.3 协程方法兼容
五、选项
5.1 调试日志输出目录定义
5.2 标签属性设置
5.3 混淆映射文件
一、导入工具
收费版: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版本和我不一样,它的混淆情况也不一样。

相关文章:
【Unity3D】Unity混淆工具Obfuscator使用
目录 一、导入工具 二、各种混淆形式介绍 2.1 程序集混淆 2.2 命名空间混淆 2.3 类混淆 2.4 函数混淆 2.5 参数混淆 2.6 字段混淆 2.7 属性混淆 2.8 事件混淆 三、安全混淆 四、兼容性处理 4.1 动画方法兼容 4.2 GUI方法兼容 4.3 协程方法兼容 五、选项 5.1 调…...
C语言语法基础学习—动态分配空间(new和malloc的用法及区别)
前言 在 C 语言中,动态内存分配主要是通过 malloc() 和 free() 函数来完成的。而在 C 中是使用new和delete关键字,来动态分配内存。 虽然 C 语言没有 new,但 malloc() 和 new 在内存分配上的作用是相似的。下面我们详细解释 malloc() 和 ne…...
QT:控件属性及常用控件(3)-----输入类控件(正则表达式)
输入类控件既可以进行显示,也能让用户输入一些内容! 文章目录 1.Line Edit1.1 用户输入个人信息1.2 基于正则表达式的文本限制1.3 验证两次输入的密码是否一致1.4 让输入的密码可以被查看 2.Text Edit2.1 输入和显示同步2.1 其他信号出发情况 3.ComboBox…...
Hive SQL 执行计划解析
Hive SQL 执行计划解析 一、 explain用法 1. SQL 查询 EXPLAIN SELECT SUM(view_dsp) AS view_sum FROM ads.table_a WHERE p_day 2025-01-06;2. 执行计划 STAGE DEPENDENCIES:Stage-1 is a root stageStage-0 depends on stages: Stage-1STAGE PLANS:Stage: Stage-1Map …...
热更新杂乱记
热更新主要有一个文件的MD5值的比对过程,期间遇到2个问题,解决起来花费了一点时间 1. png 和 plist 生成zip的时候再生成MD5值会发生变动。 这个问题解决起来有2种方案: (1).第一个方案是将 png和plist的文件时间改…...
博客搭建 — GitHub Pages 部署
关于 GitHub Pages GitHub Pages 是一项静态站点托管服务,它直接从 GitHub 上的仓库获取 HTML、CSS 和 JavaScript 文件,通过构建过程运行文件,然后发布网站。 本文最终效果是搭建出一个域名为 https://<user>.github.io 的网站 创建…...
翻译:How do I reset my FPGA?
文章目录 背景翻译:How do I reset my FPGA?1、Understanding the flip-flop reset behavior2、Reset methodology3、Use appropriate resets to maximize utilization4、Many options5、About the author 背景 在写博客《复位信号的同步与释放(同步复…...
Linux 进程环境变量:深入理解与实践指南
🌟 快来参与讨论💬,点赞👍、收藏⭐、分享📤,共创活力社区。🌟 🚩用通俗易懂且不失专业性的文字,讲解计算机领域那些看似枯燥的知识点🚩 在 Linux 系统里…...
Linux探秘坊-------5.git
1.git介绍 1.版本控制器 为了能够更⽅便我们管理这些不同版本的⽂件,便有了版本控制器。所谓的版本控制器,就是能让你了解到⼀个⽂件的历史,以及它的发展过程的系统。通俗的讲就是⼀个可以记录⼯程的每⼀次改动和版本迭代的⼀个管理系统&am…...
Linux中的几个基本指令(二)
文章目录 1、cp指令例一:例二:例三:例四:例五: 2、mv 指令例一:例二: 3、cat指令例一: 4、tac指令5、which指令6、date指令时间戳:7、zip指令 今天我们继续学习Linux下的…...
Java入门笔记(1)
引言 在计算机编程的广袤宇宙中,Java无疑是一颗格外耀眼的恒星。那么,Java究竟是什么呢? Java是美国Sun公司(Stanford University Network)在1995年推出的一门计算机高级编程语言。曾经辉煌的Sun公司在2009年被Oracle&…...
设计模式的艺术-开闭原则
原则使用频率图(仅供参考) 1.如何理解开闭原则 简单来说,开闭原则指的是 “对扩展开放,对修改关闭”。 当软件系统需要增加新的功能时,应该通过扩展现有代码的方式来实现,而不是去修改已有的代码。 例如我…...
【C语言系列】深入理解指针(3)
深入理解指针(3) 一、字符指针变量二、数组指针变量2.1数组指针变量是什么?2.2数组指针变量怎么初始化? 三、二维数组传参的本质四、函数指针变量4.1函数指针变量的创建4.2函数指针变量的使用4.3两段有趣的代码4.4 typedef关键字 …...
three.js+WebGL踩坑经验合集:写在前面的话
笔者从2023年初开始参与一个基于three.js引擎的web项目的开发工作。本打算2024年春节就把期间踩过的坑写到博客上分享给大家,然而哪怕本专栏的各种构思和内容已经在笔者的脑海里翻滚了一年,得了严重拖延症患者的我还是一直拖到了现在,实在惭愧…...
利用Linux的工作队列(Workqueue)实现中断下半部的处理
本文代码在哪个基础上修改而成? 本文是在博文 https://blog.csdn.net/wenhao_ir/article/details/145228617 的代码基础上修改而成。 关于工作队列(Workqueue)的概念 工作队列(Workqueue)可以用于实现Linux的中断下半部的,之前在博文 https://blog.cs…...
LabVIEW处理复杂系统和数据处理
LabVIEW 是一个图形化编程平台,广泛应用于自动化控制、数据采集、信号处理、仪器控制等复杂系统的开发。它的图形化界面使得开发人员能够直观地设计系统和算法,尤其适合处理需要实时数据分析、高精度控制和复杂硬件集成的应用场景。LabVIEW 提供丰富的库…...
spring-springboot -springcloud
目录 spring: 动态代理: spring的生命周期(bean的生命周期): SpringMvc的生命周期: SpringBoot: 自动装配: 自动装配流程: Spring中常用的注解: Spring Boot中常用的注解: SpringCloud: 1. 注册中心: 2. gateway(网关): 3. Ribbon(负载均…...
DRG/DIP 2.0时代下基于PostgreSQL的成本管理实践与探索(下)
五、数据处理与 ETL 流程编程实现 5.1 数据抽取与转换(ETL) 在 DRG/DIP 2.0 时代的医院成本管理中,数据抽取与转换(ETL)是将医院各个业务系统中的原始数据转化为可供成本管理分析使用的关键环节。这一过程涉及从医院 HIS 系统中抽取患者诊疗数据,并对其进行格式转换、字…...
打造本地音乐库
文章目录 存储介质硬盘(NAS)媒体播放器(可视MP3、MP4)实体介质(CD光盘、黑胶片)注意事项为什么不使用在线音乐(App)和网盘打造一套HiFi系统的成本非常高 获取音乐正版音乐途径免费音…...
【2024 - 年终总结】叶子增长,期待花开
写在前面:本博客仅作记录学习之用,部分图片来自网络,如需引用请注明出处,同时如有侵犯您的权益,请联系删除! 文章目录 前言论博客创作保持2024的记录清单博客科研开源工作生活 总结与展望互动致谢参考 前言…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
论文解读:交大港大上海AI Lab开源论文 | 宇树机器人多姿态起立控制强化学习框架(二)
HoST框架核心实现方法详解 - 论文深度解读(第二部分) 《Learning Humanoid Standing-up Control across Diverse Postures》 系列文章: 论文深度解读 + 算法与代码分析(二) 作者机构: 上海AI Lab, 上海交通大学, 香港大学, 浙江大学, 香港中文大学 论文主题: 人形机器人…...
基于Java+MySQL实现(GUI)客户管理系统
客户资料管理系统的设计与实现 第一章 需求分析 1.1 需求总体介绍 本项目为了方便维护客户信息为了方便维护客户信息,对客户进行统一管理,可以把所有客户信息录入系统,进行维护和统计功能。可通过文件的方式保存相关录入数据,对…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
Oracle11g安装包
Oracle 11g安装包 适用于windows系统,64位 下载路径 oracle 11g 安装包...
数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...
React从基础入门到高级实战:React 实战项目 - 项目五:微前端与模块化架构
React 实战项目:微前端与模块化架构 欢迎来到 React 开发教程专栏 的第 30 篇!在前 29 篇文章中,我们从 React 的基础概念逐步深入到高级技巧,涵盖了组件设计、状态管理、路由配置、性能优化和企业级应用等核心内容。这一次&…...
数据库正常,但后端收不到数据原因及解决
从代码和日志来看,后端SQL查询确实返回了数据,但最终user对象却为null。这表明查询结果没有正确映射到User对象上。 在前后端分离,并且ai辅助开发的时候,很容易出现前后端变量名不一致情况,还不报错,只是单…...
