.. APKPATCHER documentation master file, created by You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. Prerequisite ============ Apkpatcher need Java JDK installed on your machine and setup your JAVA_HOME. The following example is for a debian installation - apt install -y default-jre If you don't want to set your JAVA_HOME it would be guess but you can specify it manually. Then you need to set your java home to find where is you java home you could use these commands: For Linux and macOS, we’ll use grep: .. code-block:: bash java -XshowSettings:properties -version 2>&1 > /dev/null | grep 'java.home' For Windows, we’ll use findstr: .. code-block:: bash java -XshowSettings:properties -version 2>&1 | findstr "java.home" Then you could set your JAVA_HOME as follow: - JAVA_HOME=/usr/lib/jvm/java-11-openjdk-amd64/ apkpatcher If you want to not set JAVA_HOME at each command you can set up directly on your bashrc file Quickstart ========== In its minimal form, APK Patcher can be used to extract and repackage an application with your own signature, without making any modifications. To do this, use the following command: .. code-block:: bash apkpatcher -a -s -b Where: - `` refers to the APK file of the application you want to patch. - `` is the directory containing the Android SDK tools. For detailed instructions on how to install the SDK tools, refer to this step-by-step `tutorial `_ (https://asthook.ci-yow.com/how.install.html#setup-sdktools). - `` is the version of the Build Tools that was installed along with the Android SDK tools. If you correctly set "ANDROID_SDK_ROOT" you don't need to set "sdktools" and "version" the tool should take the most recent build tools of your system. You could also use it as docker if you don't want to install apkpatcher on your system with this command line: .. code-block:: bash docker run --rm -v .:/pwd -it madsquirrels/apkpatcher -a base.apk --download_frida_version 16.3.3 If you want to use your own sdktools you shoud overwrite the "/sdktools" volume as follow: .. code-block:: bash docker run --rm -v .:/pwd -v /usr/lib/android-sdk/:/sdktools -it madsquirrels/apkpatcher -a base.apk --download_frida_version 16.3.3 With this minimal version, you can patch an application without altering its behavior. If you're interested in making further modifications, such as changing the app's functionality, continue following the next steps in the tutorial. Handle splits applications -------------------------- Some applications are provisioned in multiple parts, known as splits. Each split is an APK file that is individually signed. These splits must be signed with the same key as the main application. To handle this, APK Patcher supports the `-m` parameter, allowing you to include one or more split APKs that will be signed simultaneously with the patched base application. Here's an example of how to use this feature: .. code-block:: bash apkpatcher -a base.apk -m split_config.arm64_v8a.apk split_config.en.apk split_config.xxhdpi.apk -b 30.0.3 -s /opt/android-sdk/ -o output.apk In this example: - The base application (base.apk) will be patched and signed. - The splits (split_config.arm64_v8a.apk, split_config.en.apk, split_config.xxhdpi.apk) will also be signed with the same key. - The patched base APK will be saved as output.apk, while the split APKs will retain their original names but will have a postfix: _new_signed.apk. To install the newly patched application and its corresponding splits, use the following adb command: .. code-block:: bash adb install-multiple base_patched.apk split_config.arm64_v8a_new_signed.apk split_config.en_new_signed.apk split_config.xxhdpi_new_signed.apk This ensures that both the base APK and its associated splits are properly installed on the device. Inject a library ie: frida-gadget --------------------------------- The `-g` option allows you to inject a library at the launch of an application. One of the most well-known examples of library injection is Frida, which enables powerful debugging and analysis without requiring privileged access (root) to the device. By simply injecting Frida into the application, it will run within the app's context. Frida is a dynamic instrumentation toolkit that is widely used to analyze Android applications for several reasons: Frida allows you to hook into an application at runtime, which means you can inspect or modify the app’s behavior as it is running. This is extremely useful when you want to: - Bypass security mechanisms (e.g., root detection, SSL pinning). - Inspect function calls, methods, and parameters in real-time. - Modify the app's internal logic dynamically without modifying its source code or binary. To inject a library, you need to download the appropriate Frida Gadget file, which follows the naming convention: .. code-block:: bash frida-gadget--android-.so You can then pass it as an argument to APK Patcher using the -g option. If the -a option for specifying architecture is not provided, the base name of the library must be common across all architectures and end with _.so, where denotes the architecture. For example, if you use -g gadget.so, the library paths must be: - gadget_x86_64.so - gadget_arm.so - gadget_arm64.so - gadget_x86.so If you need to inject Frida or another gadget, it's recommended to specify the architecture directly using -a , along with -g , where gadget.so is the exact path to the library for the selected architecture. For lazy configuration you could use the argument: "--download_frida_version" that download automatically the frida gadget online. you could use it as follow: .. code-block:: bash apkpatcher -a --download_frida_version 16.3.3 -b 34.0.0 Inject a Proxy certificate -------------------------- Certificate injection simplifies the setup of a proxy for monitoring network connections between an application and its server, especially when the connections are encrypted. There are two methods to achieve this: 1. **Allow User Certificates**: You can configure the application to accept user-installed certificates. Once this is done, simply install the proxy certificate on the device as a user certificate. To use this method, apply the -e option alone. This method does not modify the APK’s internal certificate handling but allows for easier monitoring. 2. **Embed Certificate in the Application**: Alternatively, you can directly inject the certificate into the application itself. For this, use the -c option, specifying the certificate file in PEM or DER format. This method embeds the certificate within the APK, enabling network monitoring without the need to manually install certificates on the device. Put a pause before continue the rebuid -------------------------------------- Sometimes, manual actions may be required before repackaging the application. In such cases, you can use the -p option. This option pauses the process just before repackaging, allowing the user to perform any necessary manual operations. Once the modifications are done, you can simply press Enter to continue with the packaging process. This feature is particularly useful if you need to manually edit resources, Smali code, or any other files within the APK before completing the patching. Enabling Debuggable Mode ------------------------ APKPatcher includes a feature to inject the ``android:debuggable`` option into an applications ``AndroidManifest.xml``, allowing users to debug applications even when they are in release mode. Enabling the Debuggable Option ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ To enable the ``debuggable`` mode, use the following flag during the patching process: .. code-block:: bash --enable-debug This modifies the ``AndroidManifest.xml`` to include the ``android:debuggable="true"`` attribute, making the application debuggable. Debugging an Application ~~~~~~~~~~~~~~~~~~~~~~~~~ Once the application has been patched and installed, follow these steps to debug it: 1. Set the application to be the debug target: .. code-block:: bash adb shell am set-debug-app --persistent Replace ```` with the package name of the application you want to debug. 2. Start the application\u2019s activity in debug mode: .. code-block:: bash adb shell am start -D -n / Replace ```` with the applications package name and ```` with the name of the activity you want to debug. Using a Specific Certificate for Signing ---------------------------------------- APKPatcher allows you to specify a custom certificate for signing the APK during the patching process. To do this, the following three options must be used together: - ``--keycertificate``: Specifies the path to the certificate file to be used. - ``--keyalias``: Specifies the alias name of the key within the certificate. - ``--keypass``: Specifies the password for the key. Generating a Certificate ~~~~~~~~~~~~~~~~~~~~~~~~ If you do not already have a certificate, you can generate one using the keytool utility. Below is an example command in bash: .. code-block:: bash keytool -genkey -keyalg RSA -keysize 2048 -validity 700 -noprompt -alias myalias -dname "CN=apk.patcher.com, OU=ID, O=APK, L=Patcher, S=Patch, C=BR" -keystore /path/to/certificate.keystore -storepass mypassword -keypass mypassword Replace /path/to/certificate.keystore with the desired file path for your keystore, myalias with your chosen alias, and mypassword with your chosen password. Keeping the Certificate ----------------------- The --keep-keycertificate option ensures that the automatically generated certificate is retained for future use. This can be useful for maintaining consistent signatures across multiple APKs. Using --keep-keycertificate When this option is specified, APKPatcher generates a certificate during the patching process and saves it for reuse. Using V4 Signature ------------------ The --v4 option enables the use of a V4 signature file for signing APKs. If this option is not specified, only V1, V2, and V3 signatures are used by default. Use an external script before repackaging ----------------------------------------- In a similar way, you can automate manual tasks by using a script with the --plugin option. This allows you to execute predefined tasks automatically, such as modifying Smali code or editing AXML files. For example, you can use a plugin to modify the AndroidManifest.xml file before repackaging. Here’s an example of how to modify the manifest using a plugin: Example of Command to Run the Plugin: .. code-block:: bash apkpatcher -a -s -b --plugin pyaxml_script.py Plugin Code Example: .. code-block:: python #!/usr/bin/env python import pyaxml import click @click.command() @click.argument('input_dir') def exploit_axmlfile(input_dir): path_manifest = input_dir + "/AndroidManifest.xml" axml_object, _ = pyaxml.axml.AXML.from_axml(open(path_manifest, "rb").read()) # Convert the AXML to regular XML xml = axml_object.to_xml() # Define the Android namespace for the "name" attribute android_name = "{http://schemas.android.com/apk/res/android}name" # Find the activity with name 'activity_name' and modify it for activity in xml.findall(f"./application/activity/[@{android_name}='activity_name']"): activity.attrib[android_name] = "new_activity_name" # Re-encode the XML back to AXML axml_object = pyaxml.axml.AXML() axml_object.from_xml(xml) # Write the modified AXML back to the manifest file open(path_manifest, "wb").write(axml_object.pack()) **Explanation**: - The input_dir is the directory where the application is unpacked. - The script opens the AndroidManifest.xml file, reads it using pyaxml, and converts it into a standard XML format. - It then searches for an activity named "activity_name" and replaces it with "new_activity_name". - Finally, the modified XML is re-encoded back into AXML format and written back to the manifest file. By automating tasks like these with the --plugin option, you can streamline repetitive actions such as modifying Smali code or AXML files without the need for manual intervention. Special case when apkpatcher don't find ENTRYPOINT -------------------------------------------------- In rare cases, APK Patcher may not be able to automatically identify the desired entry point for injecting a library. If you need to specify a different entry point for library injection, you can use the --entrypoint option to indicate the exact Smali function where you want the library to be injected. **Usage Example**: .. code-block:: bash apkpatcher -a -g --entrypoint -b -s -o **Explanation**: - is the APK file you want to patch. - is the path to the library you want to inject. - is the name of the Smali function where you want the library to be injected. - is the version of the Android Build Tools. - is the path to the Android SDK tools. - is the name of the resulting patched APK. By specifying the --entrypoint option, you can precisely control where the library injection occurs, ensuring that it integrates seamlessly with your application’s execution flow. Apkpatcher as library ===================== All of the previously mentioned options can also be utilized programmatically by integrating APK Patcher as a Python library. You need to import apkpatcher and instantiate the Patcher object with the required parameters: the APK file, the path to SDK tools, and the version of the Android Build Tools. Each of the previously discussed options is available through corresponding API functions. Once you’ve set up the required parameters, you can invoke the patching function to apply the modifications. Below is a minimalist example: .. code-block:: python import apkpatcher # Instantiate the Patcher object with the necessary parameters patcher = apkpatcher.Patcher(apk, version_android, sdktools) # Perform the patching process, specifying the output file patcher.patching(None, output_file=output_file) In this example: - apk is the APK file you wish to patch. - sdktools is the directory containing Android SDK tools. - version_android is the version of the Build Tools used during patching. - output_file is the name of the resulting patched APK. Smali Code Patching =================== A new feature has been added to apkpatcher that allows users to modify Smali code by replacing specific methods within an APK. This can be particularly useful for scenarios such as bypassing SSL pinning or application signature verification during security audits. Instead of using tools like Frida scripts, you can directly patch the application's behavior by modifying the Smali code. Example: Replacing a Method --------------------------- The following example shows how to replace a method in the Smali code of an APK: Define the method prototype and the new code to replace the original method: .. code-block:: python from apkpatcher.smalipatching import Method, get_smali_file_from_class, replace_methods prototype = ".method public setEndColor(I)V" patch = "return-void" m = Method(prototype, patch) directory = "/tmp/app/apktools/" classname = "com.github.mikephil.charting.model.GradientColor" fname = get_smali_file_from_class(directory, classname) with open(f"{directory}{fname}", "r") as f: content = f.read() with open(f"{directory}{fname}", "w") as f: text = apkpatcher.smalipatching.replace_methods([m], content) content = f.write(text) In this example: prototype specifies the method you want to replace. The method signature includes its visibility **(public)**, name **(setEndColor)**, and its argument types (**(I)** for an integer argument), and return type (**V** for void). patch contains the Smali code that will replace the method's original implementation. In this case, the method will be replaced with a simple return-void, which effectively removes its functionality. If you know the class but not the exact location of the Smali file, you can use the following helper function (get_smali_file_from_class) to find the file. - directory is the folder where the APK files were extracted using apktools. - classname is the full name of the class, for example: com.github.mikephil.charting.model.GradientColor. Once you have the Smali file, read its contents. Replace the method in the Smali file with the patch. In this step, replace_methods will take a list of method replacements (in this case, just m) and apply them to the file content. The modified Smali code will be stored in the text variable, ready to be written back to the APK. Use Cases --------- - Bypassing SSL Pinning: Modify methods responsible for SSL verification and replace them with return-void to bypass SSL pinning mechanisms. - Disabling Signature Verification: Replace methods that enforce signature checks to disable signature verification during security audits. - Custom Behavioral Modifications: Adjust the behavior of an app by altering specific methods, enabling more flexibility in testing and debugging. - This functionality is designed to streamline the process of Smali code manipulation, providing an efficient alternative to runtime instrumentation techniques like Frida. Indices and tables ================== * :ref:`genindex` * :ref:`modindex` * :ref:`search`