这里写目录标题
一、前言
提供apk给到外部,外部对apk进行二次处理后重新给我们一个新apk。尝试分析源apk文件和处理后的apk文件区别,根据其中区别推测外部的混淆处理方案,尽可能还原外部对apk的处理方式。以下对处理和未处理的apk文件用新、旧apk名称表示。
1.1 相关工具
二、Apk 分析
2.1 apk 解压文件
通过Beyond Compare 比对可以发现,新旧 apk 解压出来的文件中 apk 签名信息、AndroidManifest.xml
、dex、resources.arsc 文件存在差异。其中 resources.arsc
文件存储了应用程序中所有资源的信息,字符串、布局、图像等都会被编译成二进制格式打包到 apk 文件内,暂时先不管这个文件。
2.2 apk 签名信息
从上面几张图可以看出旧 apk 和新 apk 的签名信息是不一样的。旧 apk 的签名信息只包含v1、v2签名,而新 apk 则拥有v1、v2、v3的签名方案。由此可以推断出外部在对apk处理过后对apk进行了重新签名的操作。
2.3 apk AndroidManifest.xml
通过 对比新旧 apk 的 AndroidManifest 文件可以发现新 apk 的 AndroidManifest
文件中多出了一大段代码,这段代码的格式都基本一致。
<activity android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:name="com.cleronomybouhdg.wyomissingmludvzc.g756Z5WBuO" android:taskAffinity="" android:launchMode="standard" android:screenOrientation="landscape" android:configChanges="screenSize|orientation|keyboardHidden"/>
2.4 apk code
找到反编译后自己的代码,通过包名以及代码内容去判断路径位置。例如新旧 apk
内我们自己的代码路径是在com.cleronomybouhdg.wyomissingmludvzc 目录。
通过对比 com.cleronomybouhdg.wyomissingmludvzc
目录下的文件可以发现新apk增加了大概六十多个类文件,并且这六十多个类文件的名称和 AndroidManifest.xml
文件中新增的一大堆代码的名称是一样的
在对新 apk
内新增的这些类文件进行全局搜索可以发现并没有被使用过,而且这些新增的类文件和原本的代码文件一样都被特殊的字符串做了混淆处理。由此可以推断出外部是先在
我们的代码内增加了一堆垃圾文件,然后对整个dex 文件做了混淆处理的操作。
三、Apk 处理
尝试对 Apk 分析的推断进行还原处理,进一步验证猜测是否和外部处理方案一致。
3.1 添加垃圾文件
先用 AndroidStudio 生成一堆垃圾文件,这些垃圾文件都是java文件。我们需要的是 dex
格式的文件,打包可以将dex文件获取到。
拿到包含垃圾文件的 dex 文件后,再使用 baksmali 工具执行下方命令对 dex 文件进行处理得到 smali 文件。
java -jar baksmali-2.5.2.jar disassemble junkcode.dex -o junkcode
接下来使用 apktool 工具对旧ap进行解包操作
java -jar apktool_2.9.1.jar d `apk` -f
执行完命令后解包成功得到一个同旧apk名字一样的文件夹
将前面的垃圾文件的smali 文件直接拷贝到 旧apk解包得到的相应目录下
3.2 AndroidManifest.xml 处理
新apk的 清单文件内新增了对垃圾文件的 activity 参数配置的垃圾代码,这里仅增加部分参考。
<activity android:theme="@android:style/Theme.NoTitleBar.Fullscreen" android:name="com.cleronomybouhdg.wyomissingmludvzc.Buxqxjb35" android:taskAffinity="" android:launchMode="standard" android:screenOrientation="landscape" android:configChanges="screenSize|orientation|keyboardHidden"/>
<meta-data android:name="com.android.dynamic.apk.fused.modules" android:value="base"/>
<meta-data android:name="com.android.stamp.source" android:value="https://play.google.com/store"/>
<meta-data android:name="com.android.stamp.type" android:value="STAMP_TYPE_STANDALONE_APK"/>
<meta-data android:name="com.android.vending.splits" android:resource="@xml/splits0"/>
<meta-data android:name="com.android.vending.derived.apk.id" android:value="2"/>
3.3 dex 混淆处理
将 3.1 添加完垃圾文件的旧apk目录使用 apktool 工具进行重新打包操作
java -jar apktool_2.9.1.jar b rvv51_1705-5-6_v0.5101.0.57_vc1_crazy-teenpatti_20231215T170031_096da99efa8ac8d3280f2eb75edcf668 -o app-new.apk
使用 jadx-gui 查看下刚刚打包出来的apk文件会发现增加进去的垃圾文件已经可以在反编译后看见了,重新打包出来的 apk
签名是有问题的,如果直接拿去在手机上安装会提示”安装包异常“安装失败。
证明垃圾代码已经成功添加到重新打包的apk后,将apk修改后缀为zip格式解压出来后能够直接拿到 dex 文件。
接下来使用 BlackObfuscator-GUI 工具对 dex 进行混淆操作,推测外部也是使用这个工具进行的类似操作。
BlackObfuscator-GUI 环境需要 JDK11以上才能够正常运行!
Input 要混淆的apk或者dex的路径,可点击右侧图标跳转选择
Output 输出保存的apk或者dex的路径,可点击右侧图标跳转选择
Depth 混淆深度
Rules 要混淆的包名,可换行输入多行
混淆处理完成后可以得到一个我们命名为 classes.dex 的文件,按以下流程操作
- 将 classes.dex 文件转成 smali 文件
- 将 smali 文件覆盖掉 rvv51_1705-5-6_v0.5101.0.57_vc1_crazy-teenpatti_20231215T170031_096da99efa8ac8d3280f2eb75edcf668
目录下的 smali 文件- 重新对 rvv51_1705-5-6_v0.5101.0.57_vc1_crazy-teenpatti_20231215T170031_096da99efa8ac8d3280f2eb75edcf668
打包操作。
3.4 zipalign对齐
签名前先对包做对齐操作,MyGame-release-new-signed.apk是源文件,MyGame-release-new-signed-2.apk是对齐后的文件
zipalign -p -f -v 4 MyGame-release-new-signed.apk MyGame-release-new-signed-2.apk
zipalign -c -f -v 4 被检查的apk文件
3.5 apk 重新签名
使用 apksigner 工具对 dex混淆处理后的apk文件进行重签名处理,不能使用 jarsigner
进行签名操作,虽然也能签名成功但仅仅只有v1签名,这样重签后的操作也是无法安装成功运行的。 apksigner 路径在
C:\Users\xxx\AppData\Local\Android\Sdk\build-tools\xx.x.x (xx.x.x
表示版本),这里使用的my.keystore 签名是我测试生成的签名,正常应该是使用我们旧apk的签名进行重签操作
apksigner sign --ks my.keystore --out app-new-signed.apk --v2-signing-enabled true --v3-signing-enabled true app-new-2.apk
将重签后的apk和未签名的apk进行对比可以发现,签名验证成功了。
3.6 apk 安装测试
对比外部处理和自己处理的apk可以发现代码混淆方面相差无几。
四、总结
通过反编译工具分析可以得出外部处理的新 app 操作主要是对 dex 文件增加了垃圾代码提高主包的相似度,避免被Google
识别,然后进行了混淆处理。处理 dex 利用 BlackObfuscator-GUI 等工具处理后对 apk
进行重新打包签名处理方案是可行的。