android 混淆成中文,Android ProGuard解析,能够混淆成中文?

本文详细解析了ProGuard的shrink、optimize、obfuscate和preverify流程,介绍了混淆逻辑,以及如何定制混淆字符集。重点在于混淆技术的应用和自定义设置,以增强Android应用的安全防御能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

ProGuard是一个压缩、优化和混淆Java字节码文件的免费的工具,是Android平台重要的防御手段之一。java

ProGuard功能

ProGuard主要功能及执行流程以下图所示: android

11c81880f278f36301c06afa257c2485.png

输入jar或者aar等格式的java字节码文件集合而且传入自定义配置

shrink流程删除无用的类、方法和属性

optimize流程进一步优化字节码,主要表现为优化逻辑

obfuscate流程对优化后的字节码进行混淆,将类、方法和属性名称从新命名为短的且无心义的名字,缩减包大小而且进行防御

preverify为提早校验的过程,而且将校验的信息添加到类文件中

重点介绍一下上述流程的工做机制安全

Shrink

Shrink是压缩字节码的过程,主要是删除Java字节码集合中没用的类、方法和属性定义。该过程和Java的GC判断流程很像,从ROOT搜索,走过的路径可被称为调用链,经过调用链判断哪些类、方法和属性没有被使用,而后删除掉。那么这些ROOT到底是怎么被定义的? 先看下Android中proguard文件中的配置片断:

-keepattributes *Annotation*

-keepclasseswithmembernames class * {

native ;

}

-keepclassmembers public class * extends android.view.View {

void set*(***);

*** get*();

}

复制代码

看到这里是否是忽然明白,在proguard文件中都是输入到ProGuard库中的参数集合,全部添加keep标签的类、方法以及属性都是ROOT,被认为调用入口。bash

Optimize

Optimize进一步优化字节码,该过程主要优化代码逻辑,好比if判断中条件始终为true,则能够把false分之的逻辑删除,好比一个类中的只有一个方法且只被调用一次,这个时候就能够将方法块移到调用处而且删除原来的类和方法。该过程也须要知道调用链,确认好调用链才能优化代码逻辑。

Obfuscate

Obfuscate将类、方法和属性重命名成简短且无心义的名字,这一过程进一步压缩字节码大小,别切混淆逻辑,是经常使用的防御手段。

Preverify

Preverify为提早校验,而且将校验的类信息添加到类文件中,该过程在Android里默认是关闭的。

混淆分析

目前在Android中主要使用ProGuard库中的混淆功能,经过混淆压缩字节码大小而且进行防御,以前分析一个样本,经过JADX打开后以下: app

85894dd2375c3f1f3ad12ba0a2d716d7.png 上图中成员变量被混淆成中文,而且方法中有中文也有英文,这里主要分析一下ProGuard混淆逻辑及如何订制本身的混淆字符库。

ProGuard混淆逻辑

使用JADX打开ProGuard.jar而且找到入口类: 工具

b75b6cd568152b5ea757499d221f944d.png 这里分享一个找入口的技巧:运行jar包且不输入任何参数,这个时候jar包确定会输出错误信息而且退出,全局搜索错误信息就能找到入口类,如上图中会输出“Usage: java proguard.ProGuard [options ...]”错误。

经过上面的main方法找到以下处理:

f8538cb68a45c14154fdd4f3a0512c9f.png

这里能够很清晰看出ProGuard按顺序执行shrink,Optimize,Obfuscate,Preverify过程,直接看obfuscate方法:

bdc1030c9d72b11ea5ec414a27a564ab.png 在类Obfuscator中的execute方法找到上图设置NameFactory过程,先判断外部是否设置了NameFactory,若是有就使用外部设置,若是没有则使用SimpleNameFactory做为库输出名子,先看下SimpleNameFactory输出名字的逻辑,外部调用nextName获取名称,重点看下newName方法:

private String newName(int i) {

int i2 = this.generateMixedCaseNames ? 52 : CHARACTER_COUNT;

int i3 = i / i2;

char charAt = charAt(i % i2);

if (i3 != 0) {

return new StringBuffer().append(name(i3 - 1)).append(charAt).toString();

}

return new String(new char[]{charAt});

}

复制代码

其中CHARACTER_COUNT值为26,这里的意思为是否只使用a-z共26字符仍是使用a-z和A-Z共52字符,生成名字的逻辑也很简单:如如今使用26字符集合且生成的名字为z,则下一个名字为aa,依次类推当字符用到最后则增长一位。

上面SimpleNameFactory分析完成,再分析一下另外一个分支DictionaryNameFactory中生成名字的方法:

测试

54c35c1a119d25306a2b34483fee41b5.png 这里逻辑很简单,若是当前list中有足够的字符就使用当前,若是不够了则使用nameFactory的字符生成方法,这里有2个事情须要搞清楚:

list字符集合怎么生成?

nameFactory的字符生成方法?

看下DictionaryNameFactory的构造方法:

优化

1bbf2f4eb60a9ef64c34e5adff498c34.png 看到这里就明白:list字符是从文件中读取的而且去重,nameFactory是外面传过来的, 全局搜一下DictionaryNameFactory构造方法被调用处,最后找到3处调用:

79cbebd7c30dbe7af0cd74a03905f0a0.png

传入的NameFactory都是SimpleFactory,文件参数分别是packageNameFactory,classNameFactory和ObfucationDictionary,再跟进去看发如今Configuration中有以下定义:

public static final String OBFUSCATION_DICTIONARY_OPTION = "-obfuscationdictionary";

public static final String CLASS_OBFUSCATION_DICTIONARY_OPTION = "-classobfuscationdictionary";

public static final String PACKAGE_OBFUSCATION_DICTIONARY_OPTION = "-packageobfuscationdictionary";

复制代码

看到这里应该明白了,能够经过设置字符集配置完成包名,类名,方法名以及属性名配置。

这里总结一下:ui

若是不设置混淆字典,则默认使用a-z 26位英文字母混淆包名,类名,方法名,属性名

能够经过配置分别设置包名,类名,方法名,属性名混淆字符集,当配置的字符集不够用时,会使用a-z命名

混淆升级

上面介绍了混淆的机制以及设置自定义混淆字符集的方法,这里介绍两种设置字符集的方法而且对比优缺点。this

直接在配置文件中设置字符集

在DEMO工程中的proguard-rules.pro中添加以下信息:

-obfuscationdictionary ./dictionary

-classobfuscationdictionary ./dictionary

-packageobfuscationdictionary ./dictionary

复制代码

而后再在同级目录建立dictionary文件,里面设置测试字符集:

_

__

___

____

_____

______

复制代码

这里是下划线,看下最后的效果:

e3f00385589039f66a06972229f5f178.png 哈哈哈,看看如今这个混淆结果,你得有多大的耐心才能分析这样的样本。

修改ProGuard.jar

直接修改SimpleNameFactory中生成字符的方法生成新的ProGuard.jar

修改ProGuard.jar方案我没有亲自试,修改也比较简单。

这里对比一下上述两种方案:

方案

优势

缺点

配置中设置字典

方便配置

当字符集使用完会使用默认的a-z

修改ProGuard.jar

可以彻底掌握字符集使用

须要修改库

总结

本篇主要介绍ProGaurd库的功能,重点讲解了一下混淆相关,以及如何利用混淆功能提升应用安全防御, 这里提醒一下:设置字符集的时候也要注意包大小,原生a-z都是占用1个字节,若是设置中文或者其余字符就要衡量一下了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值