diff --git a/APK.py b/APK.py index e7615c7..81be8c9 100644 --- a/APK.py +++ b/APK.py @@ -77,7 +77,7 @@ def assemble(self, target : str = None) -> str: self.apk_path = out_apk return out_apk - def apply_patches(self, version: Optional[str] = None, frida_gadget: bool = True, enable_user_certs: bool = True) -> str: + def apply_patches(self, version: Optional[str] = None, frida_gadget: bool = True, enable_user_certs: bool = True, gadget_config: Optional[str] = None, script_source: Optional[str] = None) -> str: apkdir = self.decoded @@ -97,6 +97,10 @@ def apply_patches(self, version: Optional[str] = None, frida_gadget: bool = True if frida_gadget: Log.info("Adding Frida gadget") + if gadget_config: + Log.info(f"Adding Frida gadget configuration: {gadget_config}") + if script_source: + Log.info(f"Adding Frida gadget script source: {script_source}") # Ensure INTERNET has_inet = any(el.tag == "uses-permission" and el.attrib.get(ns + "name") == "android.permission.INTERNET" for el in root) @@ -133,7 +137,7 @@ def apply_patches(self, version: Optional[str] = None, frida_gadget: bool = True tree.write(manifest, encoding="utf-8", xml_declaration=True) fg = FridaGadget() - fg.copy_android_gadgets(apkdir, version=version) + fg.copy_android_gadgets(apkdir, version=version, gadget_config=gadget_config, script_source=script_source) else: Log.warn("Not adding Frida Gadget.") diff --git a/FridaGadget.py b/FridaGadget.py index 734c1f5..e7cb59f 100644 --- a/FridaGadget.py +++ b/FridaGadget.py @@ -106,12 +106,16 @@ def copy_android_gadgets( self, dest_root: Path | str, version: Optional[str] = None, + gadget_config: Optional[Path | str] = None, + script_source: Optional[Path | str] = None, ) -> List[Path]: """ Copy cached gadgets into an APK-like layout under dest_root: dest_root/ lib//libfrida-gadget.so + lib//libfrida-gadget.config.so (optional) + lib//libfrida-gadget.script.so (optional) """ dest_root = Path(dest_root).expanduser().resolve() @@ -167,6 +171,20 @@ def copy_android_gadgets( if self.verbose: Log.info(f"Copied: {src_so} -> {dest_so}") + if gadget_config: + dest_config = dest_so_dir / "libfrida-gadget.config.so" + shutil.copyfile(gadget_config, dest_config) + copied.append(dest_config) + if self.verbose: + Log.info(f"Copied config: {gadget_config} -> {dest_config}") + + if script_source: + dest_script = dest_so_dir / "libfrida-gadget.script.so" + shutil.copyfile(script_source, dest_script) + copied.append(dest_script) + if self.verbose: + Log.info(f"Copied script: {script_source} -> {dest_script}") + if not any_found: Log.abort(f"No cached libfrida-gadget.so found under {tag_dir}") diff --git a/README.md b/README.md index 96d32e4..f48c16b 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,10 @@ An APK patcher, for use with [objection](https://github.com/sensepost/objection) ### Changelog +* **7th September 2026:** + * Added `-c` / `--gadget-config` parameter to provide custom Frida Gadget configuration JSON + * Added `-l` / `--script-source` parameter to bundle and run a custom Frida script with the gadget + * **11th August 2026:** * Added Certificate Transparency bypass for Android 17+ * Added `--apk` parameter to load a local APK instead of pulling from device @@ -48,7 +52,7 @@ Install the target Android application on your device and connect it to your com ``` $ patch-apk.py -h -usage: patch-apk.py [-h] [--serial SERIAL] [--user USER] [--gadget-version GADGET_VERSION] [--no-user-certs] [--no-gadget] [--extract-only] [--disable-styles-hack] [--no-install] [--keep-splits] [--save-apk SAVE_APK] [-v] pkg_pattern +usage: patch-apk.py [-h] [--serial SERIAL] [--user USER] [--gadget-version GADGET_VERSION] [--no-user-certs] [--no-gadget] [--extract-only] [--disable-styles-hack] [--no-install] [--keep-splits] [-c GADGET_CONFIG] [-l SCRIPT_SOURCE] [--save-apk SAVE_APK] [-v] pkg_pattern Pull, merge/patch, add gadget, build, align, sign, install. @@ -68,6 +72,10 @@ options: Skip duplicate