Matrix-ApkChecker 的使用
java -jar ApkChecker.jar
Matrix-ApkChecker的命令行参数比较多,主要包括global参数和option参数两类:
global参数
--apk 输入apk文件路径(默认文件名以apk结尾即可)
--mappingTxt 代码混淆mapping文件路径 (默认文件名是mapping.txt)
--resMappingTxt 资源混淆mapping文件路径(默认文件名是resguard-mapping.txt)
--input 包含了上述输入文件的目录(给定--input之后,则可以省略上述输入文件参数,但上述输入文件必须使用默认文件名)
--unzip 解压apk的输出目录
--output 输出结果文件路径(不含后缀,会根据format决定输出文件的后缀)
--format 结果文件的输出格式(例如 html、json等)
--formatJar 实现了自定义结果文件输出格式的jar包
--formatConfig 对结果文件输出格式的一些配置项(json数组格式)
option参数
global参数之后紧跟若干个Option,这些Option是可选的,一个Option表示针对apk的一个检测选项。
有13个项目
ApkChecker
创建ApkJob,执行其run方法
ApkJob
解析参数,创建task,执行
1.先执行,preTasks包含解压功能,TASK_TYPE_UNZIP
2.readConfigFile里读取了config文件,将数据设置到JobConfig
JobConfig
/**
* Created by jinqiuchen on 17/6/15.
* apkPath = "/Users/admin/StudioProjects/demo/app/build/outputs/apk/demo/release/AndResGuard_app-demo-release/app-demo-release_aligned_signed.apk"
* unzipPath = "/Users/admin/StudioProjects/demo/app/build/outputs/apk/demo/release/AndResGuard_app-demo-release/app-demo-release_aligned_signed_unzip"
* outputPath = "/Users/admin/StudioProjects/demo/app/build/outputs/apk/demo/release/AndResGuard_app-demo-release/apk-checker-result"
* mappingFilePath = "/Users/admin/StudioProjects/demo/app/build/outputs/mapping/demoRelease/mapping.txt"
* resMappingFilePath = "/Users/admin/StudioProjects/demo/app/build/outputs/apk/demo/release/AndResGuard_app-demo-release/resource_mapping_app-demo-release.txt"
* outputConfig [{"name":"-countMethod","group":[{"name":"Android System","package":"android"},{"name":"java system","package":"java"},{"name":"com.tencent.test.$","package":"com.tencent.test.$"}]}]
*
* outputFormatList = {ArrayList@904} size = 2
* 0 = "mm.html"
* 1 = "mm.json"
*
* proguardClassMap
* com.newbilling.view.activity.VipActivity -> com.newbilling.view.activity.VipActivity
*
* resguardMap
* R.animator.e -> R.animator.mtrl_chip_state_list_anim
*
* entrySizeMap
* "res/color/abc_primary_text_material_light.xml" -> {Pair@1161} "Pair [first=464, second=229]"
*
* entryNameMap
* r/n/btn_normal.webp -> res/drawable-xhdpi-v4/btn_normal.webp
*/
public final class JobConfig {
private String inputDir;
private String apkPath;//ok
private String unzipPath;//ok
private String outputPath;//ok
private String mappingFilePath;//ok
private String resMappingFilePath;//ok
private JsonArray outputConfig;//ok countMethod
private List outputFormatList;//ok
private Map proguardClassMap;//ok
private Map resguardMap;//ok
private Map> entrySizeMap;//ok
private Map entryNameMap;//ok
}
UnzipTask
1.输入的Apk文件首先会经过UnzipTask处理,解压到指定目录,在这一步还会做一些全局的准备工作,
包括反混淆类名(读取mapping.txt)、反混淆资源(读取resMapping.txt)、统计文件大小等。
2.可以利用的技术
解压apk ZipFile
ManifestAnalyzeTask
todo Resources.arsc文件大家应该都知道是干什么的,它实际上就是App的资源索引表
todo AXmlResourceParser resourceParser;//解析类,需要传入arscFile
todo ApkResourceDecoder具体怎么操作
todo ApkUtil disassembleClass 干哈的,反汇编,将汇编变成smail?
1.ManifestParser
将AndroidManifest解析成Json数据格式
* "android:versionCode" -> {JsonPrimitive@1600} ""228""
* "android:versionName" -> {JsonPrimitive@1602} ""2.2.8""
* "android:compileSdkVersion" -> {JsonPrimitive@1604} ""29""
* "android:compileSdkVersionCodename" -> {JsonPrimitive@1606} ""10""
2.XmlPullResourceRefDecoder
* 遍历xml得到资源的引用名字set
* this.resourceRefSet = {HashSet@2647} size = 14
* 0 = "R.string.js"
* 1 = "R.string.k5"
* 2 = "R.string.jr"
* 3 = "R.array.c"
* 4 = "R.array.d"
CountClassTask
利用google开源的 com.android.dexdeps 类库来读取dex文件
可以利用的技术DexData,读取dex里的class,不过只是ClassName
CountRTask
可以利用的技术DexData,读取dex里的class,不过只是ClassName
DuplicateFileTask
可以利用的技术,求文件的MD5,MessageDigest
// "com.google.android.gms.gass.R" -> {Integer@2328} 0
// "androidx.activity.R" -> {Integer@2335} 171
// "com.google.firebase.analytics.connector.R" -> {Integer@2328} 0
// "com.example.lib_utils.R" -> {Integer@2338} 1707
FindNonAlphaPngTask
可以检测出apk中非透明的png文件
* 可以利用的技术:通过 java.awt.BufferedImage 类读取png文件并判断是否有alpha通道。
MethodCountTask
* 统计方法数
* 统计dex包含的方法数,并支持将输出结果按照类名(class)或者包名(package)来分组
* MethodCountTask 可以统计出各个Dex中的方法数,并按照类名或者包名来分组输出结果。
* 实现方法:利用google开源的 com.android.dexdeps 类库来读取dex文件,统计方法数。
UnusedAssetsTask
* UnusedAssetsTask 可以检测出apk中未使用的assets文件
* 可以利用的技术:搜索smali文件中引用字符串常量的指令,判断引用的字符串常量是否某个assets文件的名称
* 读取dex里的class
* DexBackedDexFile -》 ClassDef -》Smali
ResProguardCheckTask
查看是否使用ResProguard
原理:ResProguard会将res资源变成r,或者保留res,其他资源改为[a-z_0-9]{1,3}
MultiLibCheckTask
查看lib下有几个文件夹
ShowFileSizeTask
* 按文件大小排序列出apk中包含的文件
* 列出超过一定大小的文件,可按文件后缀过滤,并且按文件大小排序
UncompressedFileTask
* 直接利用UnzipTask中统计的各个文件的压缩前和压缩后的大小,判断压缩前和压缩后大小是否相等。
* 如果相等,说明没有压缩
* 如果不相等,说明有压缩了
MethodCountTask
*todo
UnusedResourcesTask
*todo
MultiSTLCheckTask
*todo
* CheckMultiSTLTask 可以检测apk中的so是否静态链接STL
* 实现方法:通过nm工具来读取so的符号表,如果出现 std:: 即表示so静态链接了STL。
UnStrippedSoCheckTask
*todo
* UnStrippedSoCheckTask 可以检测出apk中未经裁剪的动态库文件
* 实现方法:使用nm工具读取动态库文件的符号表,若输出结果中包含no symbols字样则表示该动态库已经过裁剪