When trying to modify an android application, Frida comes really handy. However, on non-rooted devices it can sometimes be difficult to inject the gadget into the apk.
With single, fat, APKs, that's not much of an issue because there are already several tools that work really well, and it can also be done manually with
This is in my experience less and less true, since I encounter every time more APKs that, one way or another, break something along the process.
Since apktool
.apktool
decodes all resources, just a missing reference makes the whole process fail.
On the other hand, split APKs (those that come with not only a base.apk
, but also other files like *_config.xxhdpi.apk
et
al.) are harder to recompile, because there are certain dependencies between those different files, and fixing all the resource IDs (which has to be done before apktool
lets
you merge all into a fat APK) is a pain that not always fully works.
This script aims to help with the injection task, by modifying the least amount of files possible so there are no issues later with the resources.
It's advised to create a virtualenv to install the dependencies:
$ virtualenv venv
$ . venv/bin/activate
(venv) $ pip install -r requirements
Additionally, the following Java libraries must be present for the patcher to work end-to-end:
- ./java_libs/apksig-8.7.0-alpha04.jar
- ./java_libs/dexlib2-3.0.8.jar
- ./java_libs/guava-33.2.1-jre.jar
- ./java_libs/zipalign-java-v1.1.3.jar
- ./Java/APK patcher/app/build/libs/app.jar
Just run the script and read the help message:
$ python apk-patcher.py -h
usage: APK patcher [-h] [-f FIX_MANIFEST] [-c GADGET_CONFIG] [-v] [-l frida_script] base_path
Script to automate the decompilation, patch and rebuild of any Android split applications (those apps that have base.apk, plus .config.<something>.apk) to inject the provided Frida script.
positional arguments:
base_path Common prefix for all the split apk files.
For example, if we have:
- com.example.1234.apk
- com.example.1234.config.armeabi_v7a.apk
- com.example.1234.config.en.apk
- com.example.1234.config.xxhdpi.apk
'base-name' must be "com.example.1234." (note the dot at the end)
options:
-h, --help show this help message and exit
-f, --fix_manifest If set, the script will attempt to modify AndroidManifest.xml to set extractNativeLibs=true.
ATTENTION: it may cause problems like 'INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION' on installation.
-c GADGET_CONFIG, --config GADGET_CONFIG
Path to a custom Gadget config ( https://frida.re/docs/gadget/ )
-v, --verbose Increase the verbosity. Can be specified up to 3 times.
-l frida_script, --load frida_script
The JS file to patch into the apk.
There are other tools which aim to do the same thing. For example:
- APK patcher - not related to this project; I only discovered it while researching for libraries to modify AXML
- Apktool
- objection
- ... and many, many others
However, as far as my research goes, all of them rely on OS commands to execute the same tools in the background:
This poses two problems from my point of view:
- If one of those base tools fail (for example,
zipalign
on Kali has been giving me quite a lot of errors like undefined symbol), all tools will fail at the same step. - Relying on executing OS commands poses the risk of something going wrong (for example, the output format changes slightly, and the parsing is off from there) without noticing, for example.
Therefore, I decided to implement all using those tools as libraries; or, when not possible, using alternative libraries which perform the same task.
If you want to contribute, you can take a look into the following open topics:
- Add more Frida scripts. For example:
- Remove common ads and trackers
- Disable cert pinning (besides the common methods). A good idea is to inject our own root CA)
- Disable root detection
- Introduce proper logging
- Dafuq is Revolut (com.revolut.revolut) to detect Frida even before it even loads ??
This tool wouldn't have been possible without the invaluable research and effort of the third-party libraries I'm relying on, besides the regular ones (Java and Python standard libs, requests
, ...):
- androguard, to parse AXML (to decode the AndroidManifest.xml) and DEX files.
- pyaxml, to patch AXML.
- JPype, to run the Java methods from within Python.
- baksmali / smali, to inject the custom instructions into the appropriate DEX files.
- zipalign-java, to align the Zip files like the Android Runtime expects.
- apksig, to sign the final APKs.
- And, of course, the other (probably) dozens of libraries that each of those tools rely on...