Oo0代码混淆实现方法
Oo0代码混淆实现方法
Bin MT管理器v MT管理器v
微信号BinMtPlus
功能介绍MT管理器2.0官方公众号
2017-11-15
看过 MT 的 dex 文件的朋友们肯定都发现了它的所有类名、方法名、字段名都成了 Oo0 的各种混合体,这虽然不能起很好的保护作用,但还是可以恶心一下反编译你软件的人。
最开始我是通过给 Proguard 设置字典的方式来实现这个效果,也就是提前生成 N 个不同的 Oo0 组合保存到 txt 文件,然后在混淆配置中设置下即可。
不过这个方法存在一些局限性,首先你要手动生成字典文件,不能在每次混淆时随机生成名字,其次你要确保字典名字中数量要够用,否则又会变回 abcd 的组合了。
另外 Android Studio 默认的 Pruguard 配置是不区分名称大小写,也就是像 OO|Oo|oO|oo 会被过滤得只剩下一个,其它三个由于在不区分大小写的情况下是相同的被删掉了。
最后我打起了修改 Proguard 源码的主意。
首先我们先去看看 Android Studio 使用的 Proguard 版本,Mac 上是在 Finder 的应用程序中找到 Android Studio,右键-显示包内容,接着进入
Contents/gradle/m2repository/net/sf/proguard/proguard-base
Windows 版本如果我没记错是先进入 Android Studio 的安装目录,然后再进入
gradle/m2repository/net/sf/proguard/proguard-base
最后你可以看到下面几个文件夹:
最高版本是5.3.3,所以现在我们去下载 Proguard-5.3.3 的源码,网址在 https://sourceforge.net/projects/proguard/files/proguard/
然后我们用 Intellij IDEA 来创建个 Java 项目,就取名 Oo0Proguard,创建完成后,解压 Proguard 的源码,把 src 文件夹复制过来。
由于我们只需要编译 proguard-base.jar 包给 Android Studio 使用,所以删掉先一些不需要的源代码,分别为下面五个包:
proguard/ant
proguard/gradle
proguard/gui
proguard/retrace
proguard/wtk
同时把 proguard/MANIFEST.MF 也删掉,最终效果:
现在来配置一下项目的 Artifacts,用来将源码打包成 jar。点击菜单 File - Project Structrue,然后如下图操作:
重命名输出的 jar 文件名为 proguard-base-5.3.3,操作如下:
最后点击 OK 保存设置。我们再点击菜单 Build - Build Artifacts - Oo0Projuard:jar - Build,然后就可以看到打包好的 jar 了。
OK,到这边我们完成了第一步,可以编译出原版的 proguard-base.jar 了。
现在开始对 Proguard 进行修改。我研究了半天源码才找到下面这些修改位置的,具体过程就不多说了,直接给你们。
修改版本名称
具体在 proguard.Proguard.VERSION,这样方便我们在 Android Studio 的编译日志中确定是否调用了我们修改的 Proguard。
强制名称混合大小写
Android Studio 默认的 Proguard 配置中有一条
-dontusemixedcaseclassnames
可以修改源码忽略掉这条规则。
定位到 proguard/obfuscate/ClassObfuscator.java 的 125 行
this.useMixedCaseClassNames = useMixedCaseClassNames;
修改为
this.useMixedCaseClassNames = true;
强制不保留内部类
Android Studio 默认的 Proguard 配置中有一条
-keepattributes *Annotation*,Signature,InnerClasses,EnclosingMethod
其中 InnerClasses 和 EnclosingMethod 会导致混淆后可能出现 Oo0$1 之类的名称,可以修改源码忽略掉这两个值。
打开 proguard/ConfigurationParser.java,搜索KEEP_ATTRIBUTES_OPTION,给该行的 if 语句加对大括号,然后添加代码删掉 configuration.keepAttributes 内的 InnerClasses 和 EnclosingMethod,如下图,红色框出来的是添加的代码。
创建Oo0名称工厂
具体代码放在 Github 上,在 src/proguard/obfuscate/ONameFactory.java,其中我使用了 Random 来让每次运行生成的名称顺序不一样。
使用Oo0名称工厂
打开 proguard/obfuscate/ClassObfuscator.java,把全部
new SimpleNameFactory(useMixedCaseClassNames)
替换为
new ONameFactory()
打开 proguard/obfuscate/Obfuscator.java,把全部
new SimpleNameFactory()
替换为
new ONameFactory()
如果后续的 Proguard 版本出现变化,你们搜一下 SimpleNameFactory 的引用,把除了出现在 main 方法中的,其它全部都替换掉就行了。
修改源文件名
我们在编写应用时总难免会出现 bug,当程序奔溃后,主要是通过异常堆栈、源文件名、行号来定位代码,由于类名和源文件名基本一样,既然我们混淆了类名,自然也不希望源文件名暴露出去。
第一种方法是通过 Proguard 来删除源文件名,这样奔溃日志中也是看不到源文件名的,我们可以通过混淆时生成的 mapping.txt 文件来恢复。但使用这种方法的话,你需要保存各个版本的 mapping.txt 文件,相当不方便。
第二种方法是对源文件名进行加密,这样我们在奔溃日志中看到的是加密后的名称,只需要解密一下就行了,直接上修改方法:
定位到 proguard.obfuscate.SourceFileRenamer 的 visitSourceFileAttribute 方法,将方法中的全部代码替换为
String sourceFile = clazz.getString(sourceFileAttribute.u2sourceFileIndex);
if (!(clazz.getName() + ".java").endsWith(sourceFile))
sourceFile = encrypt(sourceFile);
sourceFileAttribute.u2sourceFileIndex =
new ConstantPoolEditor((ProgramClass) clazz).addUtf8Constant(sourceFile);
其中的 if 判断是过滤掉类名没变化的类,例如所有 Activity 的类名是不会被混淆的,其源文件名自然也不需要加密。encrypt 方法用于加密字符串,具体实现由你们自行设计。
然后我们在定位到 SourceFileRenamer 的唯一调用处,在 proguard/obfuscate/Obfuscator.java 的 467 行,把 if 判断注释掉。
到这边我们已完成了所有的修改,再次点击菜单 Build - Build Artifacts - Oo0Projuard:jar - Build,编译出 proguard-base-5.3.3.jar 文件。
现在来替换 Android Studio 的 Proguard,在这之前记得先退出 Android Studio,然后回到我们刚刚打开的目录
打开 5.3.3,把 proguard-base-5.3.3.jar 重命名为 proguard-base-5.3.3_bak.jar,再把我们编译好的 proguard-base-5.3.3.jar 复制进来。注意,当我们通过补丁升级 Android Studio 前需要还原文件,否则无法升级。
现在我们再次打开 Android Studio,打开项目,进入 app 下的 build.gradle,把 minifyEnabled 设为 true,开启 Proguard 混淆功能。
然后再打开 proguard-rules.pro 混淆配置文件,加入下面的内容:
# 修改包名
-repackageclass ""
# 忽略访问修饰符,配合上一句使用
-allowaccessmodification
# 不要删除源文件名和行号
-keepattributes SourceFile,LineNumberTable
配置完成,编译发行版的 APK,然后点击右下角的 Gradle Console,当开始混淆时会看到一行 ProGuard, version 5.3.3(Oo0),这是我修改后的版本名称,说明我修改的 Proguard 已经成功被 Android Studio 调用了。
编译完成后,点击菜单 Build- Analyze APK,打开我们刚刚编译好的 apk 文件,然后点击 classes.dex,就可以看到类名、方法名、字段名都被混淆成了各种 Oo0 了。
把 apk 复制到手机,使用 MT 打开里面的 classes.dex 文件,随便打开一个类,可以看到源文件名也更改成功了,这边我没有加密,只是在后面加了 -encrypt
全部代码已上传到 Github
https://github.com/L-JINBIN/Oo0Proguard
也可以点击下面的阅读原文查看
Oo0代码混淆实现方法相关推荐
- 记录一次Oo0代码混淆实现方法
配置Oo0代码混淆,只需要2步: 1,修改Proguard源文件 2,将新的Proguard文件配置给项目 ###开始: 关于修改Proguard源文件的方法和如何导出jar包,请参考Oo0代码混淆实 ...
- 代码混淆是什么?代码混淆的方法有哪些?
一.什么是代码混淆? 代码混淆 (Obfuscated code)是将计算机程序的代码,转换成一种功能上等价,但是难于阅读和理解的形式的行为.代码混淆可以用于程序源代码,也可以用于程序编译而成的中间 ...
- 去除js代码混淆的方法,亲测有效
步骤: 1.新建一个js.html 2.页面新建一个dev,id=divTest 3.写一段script脚本,document.getElementById('divTest').innerText= ...
- Android代码混淆官方实现方法
首先查看一下 "project.properties" 这个文件: # This file is automatically generated by Android Tools. ...
- 代码混淆的原理是什么?常见代码混淆方法介绍
移动应用代码安全非常重要,代码逆向会导致代码逻辑被获取,进一步导致控制流被hook,安全防线被破,给APP安全带来巨大风险,因此开发者一般都会进行代码混淆保护.本文主要介绍了代码混淆的原理.方法.以及 ...
- 关于ios代码混淆的一些注意事项
最近参照念茜大神的博客练习代码混淆,又看了一下其他人做代码混淆的方法,总结起来就是把变量名.方法名.类名.文件名都改成难看的无意义字符串,恶心他人.一些大神提供了一些混淆脚本,但是执行后还是需要根据编 ...
- Android代码混淆及反编译apk
序言: 经常听开发提起代码混淆引起的BUG,混淆后在测试一下有没有问题,那问题来了什么是代码混淆,怎么确认代码混淆成功了,带着问题读下文吧~~ 一.代码混淆的原理 代码混淆是将程序中的代码,等价转换为 ...
- WinRT C#代码混淆
众所周知,C#代码是极易被反编译的,所以当一些工程有涉及到公司知识产权的代码时,我们就有必要对代码进行混淆.因为我这段时间在研究win8,所以接下来讲讲windows store applicatio ...
- Android笔记:防反编译、代码混淆中,解决第三方jar包不被混淆的一些心得,及gson防混淆方法...
为了防止代码被反编译,一般在签名导出前需要对代码进行混淆.最近发现自己的一个项目工程在代码混淆后,使用中出现了异常.以下是自己这几天在解决代码混淆以及引入第三方jar包导致混淆出现的问题处理的一些心得 ...
最新文章
- LeetCode 968. 监控二叉树
- no copy constructor available or copy constructor is declared #39;explicit#39;
- java实现rsa欧几里得算法求d_RSA算法中利用欧几里得算法求d详细过程
- Python-import导入上级 本级 目录文件
- 白日门传奇手游源码端
- android 手机主题制作,怎么制作手机主题?
- 林子雨大数据技术原理总结
- Mysql 导出表结构或数据
- linux内核 精简 编译,精简LINUX内核配置及快速编译的方法收集
- win10桌面右键一直转圈_吐血推荐:掌握这些技巧,win10工作效率提升9999%
- win7网上邻居无计算机一栏,Win7在网上邻居上看不到别的电脑怎么办?-电脑自学网...
- 计算机符号mi,在线特殊符号大全
- 2020年3月20日阿里内推笔试题
- 三峡大学c语言上机考试题库,[专题]三峡大学计算机基础考试题库.doc
- 大数据运维实战第一课 大话 Hadoop 生态圈
- 【Java SE】数组的打印方式
- Python机器学习基础教程(1)Irises(鸢尾花)分类之新手上路
- 实施工程师面常见问题
- Windows下MySQL5.5安装,配置与卸载
- 3.2 搞懂小红书算法运营逻辑,只需要5分钟【玩赚小红书】