commit 5ccc494c45f2c9e9a89cc112bdedbc1427614c47 Author: Mathieu Strypsteen Date: Mon Mar 4 16:50:14 2024 +0100 Initial commit diff --git a/Containerfile b/Containerfile new file mode 100644 index 0000000..24b73a2 --- /dev/null +++ b/Containerfile @@ -0,0 +1,11 @@ +FROM fedora +RUN dnf install -y java-latest-openjdk-headless xz +RUN curl -o apktool.jar -L https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.9.3.jar +RUN curl -o apk-signer.jar -L https://github.com/patrickfav/uber-apk-signer/releases/download/v1.3.0/uber-apk-signer-1.3.0.jar +RUN curl -o libfrida-gadget.so.xz -L https://github.com/frida/frida/releases/download/16.2.1/frida-gadget-16.2.1-android-arm64.so.xz +RUN unxz libfrida-gadget.so.xz +COPY libfrida-gadget.config.so / +COPY inject-frida.sh / +COPY patch-main.py / +WORKDIR /tmp +CMD /inject-frida.sh diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..b3dbff0 --- /dev/null +++ b/LICENSE @@ -0,0 +1,22 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. diff --git a/inject-frida.sh b/inject-frida.sh new file mode 100755 index 0000000..f2ff130 --- /dev/null +++ b/inject-frida.sh @@ -0,0 +1,13 @@ +#!/bin/sh +set -e +java -jar /apktool.jar d /data/app.apk +sed 's/android:extractNativeLibs="false"/android:extractNativeLibs="true"/' -i app/AndroidManifest.xml +if ! grep -q android.permission.INTERNET app/AndroidManifest.xml; then + sed 's/<\/manifest>/<\/manifest>/' -i app/AndroidManifest.xml +fi +/patch-main.py +mkdir -p app/lib/arm64-v8a +cp /libfrida-gadget.so /libfrida-gadget.config.so app/lib/arm64-v8a +java -jar /apktool.jar b -o patched.apk app +java -jar /apk-signer.jar --overwrite -a patched.apk +cp patched.apk /data diff --git a/libfrida-gadget.config.so b/libfrida-gadget.config.so new file mode 100644 index 0000000..a43205c --- /dev/null +++ b/libfrida-gadget.config.so @@ -0,0 +1,7 @@ +{ + "interaction": { + "type": "listen", + "address": "0.0.0.0", + "port": 27042 + } +} diff --git a/patch-main.py b/patch-main.py new file mode 100755 index 0000000..15a56ce --- /dev/null +++ b/patch-main.py @@ -0,0 +1,44 @@ +#!/usr/bin/python3 +import os +import xml.etree.ElementTree as ET + +def get_main_activity() -> str: + root = ET.parse("app/AndroidManifest.xml").getroot() + for activity in root.iter("activity"): + for action in activity.iter("action"): + if action.attrib.get("{http://schemas.android.com/apk/res/android}name") == "android.intent.action.MAIN": + return str(activity.attrib.get("{http://schemas.android.com/apk/res/android}name")) + raise Exception("No main activity found") + +def find_main_activity(classname: str) -> str: + classname = classname.replace(".", "/") + ".smali" + if classname.startswith("/"): + raise Exception("Invalid classname") + for path, _, files in os.walk("."): + for file in files: + result = os.path.join(path,file) + if result.endswith(classname): + return result + raise Exception("No file with classname found") + +def patch_class(path: str) -> None: + with open(path, "r") as file: + lines = file.readlines() + patched = False + with open(path, "w") as file: + matched = False + for line in lines: + if ".method static constructor ()V" in line: + matched = True + if matched and "return-void" in line: + file.write("const-string v0, \"frida-gadget\"\n") + file.write("invoke-static {v0}, Ljava/lang/System;->loadLibrary(Ljava/lang/String;)V\n") + matched = False + patched = True + file.write(line) + if not patched: + raise Exception("Failed to patch class") + +main_activity = get_main_activity() +path = find_main_activity(main_activity) +patch_class(path)