Android重打包
Android重打包还是挺常用的,因为更为细致的修改可以直接用frida去hook,如果用修改APK,重打包的方式,还需要涉及到smali代码的修改,所以重打包比较适用于对资源的替换,或者一些常量的替换,比较方便
流程刨析
objection Patcher
重打包这种比较常见的需求,肯定有不少开源的项目,Objection里就有重打包的工具
Patching Android Applications · sensepost/objection Wiki (github.com)
其重打包的目的把frida-gadget.so重打包进去,好让objection在免root的手机上也能使用,其代码在
objection/android.py at master · sensepost/objection (github.com)
这里分析一些其中的比较重要的函数
_init
1 | def __init__(self, skip_cleanup: bool = False, skip_resources: bool = False): |
初始化操作过程中的路径,这里是用的tempfile,其是在tmp路径生成对应的temp文件夹,这里我们可以修改成我们常用的目录
unpack_apk
用的是apktool,decode是解包,-f清空解压目录,-r如果指定的话就是不解压资源,apk_temp_directory是解压目录,apk_source是apk
1 | def unpack_apk(self): |
_get_appt_output
1 | def _get_appt_output(self): |
badging是获得label和icon
_get_launchable_activity
1 | def _get_launchable_activity(self) -> str: |
方法是先尝试从aapt的output中获取,aapt获取app信息用的是
_get_appt_output,如果这里找不到,可能APP用的是别名的写法,所以这里手动解析AndroidMenifest,判断是不是launch activity是看有没有这个’android.intent.category.LAUNCHER’
_determine_smali_path_for_class
1 | def _determine_smali_path_for_class(self, target_class) -> str: |
首先是拼装目录,一般正常情况下,就存在于这个目录里面,但是如果multiDex的情形,apktool的命名是smali_classes2 smali_classes3这种方式
1 | # check if the activity path exists. If not, try and see if this may have been |
所以下面就是从smali_classes中遍历,去寻找目标activity的smali
inject_load_library
1 | def inject_load_library(self, target_class: str = None): |
首先是利用前面几个函数找到对应的smail,然后是确定插桩函数
,最后就是写入load library
1 | # search for the line starting with '# direct methods' in it |
Patch_smali_with_load_library
这个函数插桩分两种情况,如果smali里面有clinit即构造函数存在,就部分插入,即插入一个invoke就行
否则就要插入一个完整的构造函数clinit
_revalue_locals_count
负责修复local指令
add_gadget_to_apk
1 | def add_gadget_to_apk(self, architecture: str, gadget_source: str, gadget_config: str): |
把gadget.so拷贝到lib下面
上述都是解包的过程,下面是重打包的函数
build_new_apk
1 | def build_new_apk(self, use_aapt2: bool = False): |
build后面跟的就是要打包apk的目录,-o就是打包的生成文件名
下一步是对齐apk
zipalign_apk
1 | def zipalign_apk(self): |
用的是zipalign,没什么好说的
最后是sign_apk
sign_apk
1 | def sign_apk(self): |
签名需要先生成一个keystore,命令如下
1 | The keystore itself was created with: |
这里可以直接用objection的key
objection/objection/utils/assets at master · sensepost/objection (github.com)
签名命令具体什么意思 可以看这里
为应用签名 | Android 开发者 | Android Developers
抽取代码 MyRepackAPP.py
这里先只扣取objection里面的基本的解包打包流程,
1 | if __name__ == '__main__': |
所以只涉及到这几条命令
执行下面命令对 my.apk进行解包,解包结果会存放在同级目录下的apk_unpack里
1 | python3 MyRepackAPP.py unpack my.apk |
修改完毕后,执行下面命令重打包,最终生成的apk为apk_unpack.aligned.objection.apk
1 | python3 MyRepackAPP.py pack |
环境依赖
主要会用到下面工具
1 | # required tools |
其中apktool,最好不要直接用apt去安装,这样安装的版本不是最新的,可能会有些问题
Apktool - How to Install (ibotpeaches.github.io)
Release Apktool v2.6.1 · iBotPeaches/Apktool (github.com)
先把下面的wrapper脚本创建出来
https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool
然后再下载最新版本jar
最后再把两个都放在 /usr/local/bin里