diff --git a/patcher/Cargo.lock b/patcher/Cargo.lock index 5d6da14..0657664 100644 --- a/patcher/Cargo.lock +++ b/patcher/Cargo.lock @@ -35,7 +35,7 @@ dependencies = [ [[package]] name = "androscalpel" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=c0152e7#c0152e76089b7a51ce28e19c1828cdbdd435271a" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=615f7a8#615f7a8f526e04e5c6d15dac00205a9c18879cfd" dependencies = [ "adler", "androscalpel_serializer", @@ -51,7 +51,7 @@ dependencies = [ [[package]] name = "androscalpel_serializer" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=c0152e7#c0152e76089b7a51ce28e19c1828cdbdd435271a" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=615f7a8#615f7a8f526e04e5c6d15dac00205a9c18879cfd" dependencies = [ "androscalpel_serializer_derive", "log", @@ -60,7 +60,7 @@ dependencies = [ [[package]] name = "androscalpel_serializer_derive" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=c0152e7#c0152e76089b7a51ce28e19c1828cdbdd435271a" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=615f7a8#615f7a8f526e04e5c6d15dac00205a9c18879cfd" dependencies = [ "proc-macro2", "quote", @@ -129,7 +129,7 @@ dependencies = [ [[package]] name = "apk_frauder" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=c0152e7#c0152e76089b7a51ce28e19c1828cdbdd435271a" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=615f7a8#615f7a8f526e04e5c6d15dac00205a9c18879cfd" dependencies = [ "androscalpel_serializer", "flate2", diff --git a/patcher/Cargo.toml b/patcher/Cargo.toml index 246454e..299c8e6 100644 --- a/patcher/Cargo.toml +++ b/patcher/Cargo.toml @@ -6,8 +6,10 @@ edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "c0152e7", features = ["code-analysis"] } -apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "c0152e7"} +androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "615f7a8", features = ["code-analysis"] } +apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "615f7a8"} +#androscalpel = { path = "../../androscalpel/androscalpel", features = ["code-analysis"] } +#apk_frauder = { path = "../../androscalpel/apk_frauder"} anyhow = { version = "1.0.95", features = ["backtrace"] } clap = { version = "4.5.27", features = ["derive"] } env_logger = "0.11.6" @@ -15,3 +17,9 @@ reqwest = { version = "0.12.12", default-features = false, features = ["blocking serde = "1.0.217" serde_json = "1.0.138" log = "0.4.25" + +[profile.minsizerelease] +inherits = "release" +strip = true # Automatically strip symbols from the binary. +opt-level = "z" # Optimize for size +lto = true diff --git a/patcher/src/bin/patcher.rs b/patcher/src/bin/patcher.rs index 149a226..7932b89 100644 --- a/patcher/src/bin/patcher.rs +++ b/patcher/src/bin/patcher.rs @@ -21,6 +21,8 @@ struct Cli { out: PathBuf, #[arg(short, long)] keystore: PathBuf, + #[arg(long)] + keypassword: Option, #[arg(short, long)] zipalign: Option, #[arg(short, long)] @@ -84,6 +86,9 @@ fn main() { i += 1; } // TODO: aapt would be a lot more stable? + println!("\n\n\n\n\n\n\n"); + println!("### /!\\ {:?}", cli.keypassword.as_deref()); + println!("\n\n\n\n\n\n\n"); apk_frauder::replace_dex( cli.path, cli.out, @@ -91,6 +96,7 @@ fn main() { cli.keystore, cli.zipalign, cli.apksigner, + cli.keypassword.as_deref(), None::>>>, ); } diff --git a/patcher/tst.sh b/patcher/tst.sh deleted file mode 100644 index dcc9b15..0000000 --- a/patcher/tst.sh +++ /dev/null @@ -1 +0,0 @@ -cargo run --bin patcher -- --code-loading-patch-strategy model-class-loaders --runtime-data ./tst/runtime.json --path ../test_apks/dynloading/build/test_dynloading.apk --out /tmp/patched_dynloading.apk -k ../test_apks/dynloading/ToyKey.keystore -z $(which zipalign) -a $(which apksigner) diff --git a/patcher/tst/dex/PathClassLoader_00a972ce_09d17bb5de42d5d9.bytecode b/patcher/tst/dex/PathClassLoader_00a972ce_09d17bb5de42d5d9.bytecode deleted file mode 100644 index 58770fc..0000000 Binary files a/patcher/tst/dex/PathClassLoader_00a972ce_09d17bb5de42d5d9.bytecode and /dev/null differ diff --git a/patcher/tst/dex/PathClassLoader_012faa7a_09d17bb5de42d5d9.bytecode b/patcher/tst/dex/PathClassLoader_012faa7a_09d17bb5de42d5d9.bytecode deleted file mode 100644 index 58770fc..0000000 Binary files a/patcher/tst/dex/PathClassLoader_012faa7a_09d17bb5de42d5d9.bytecode and /dev/null differ diff --git a/patcher/tst/dex/PathClassLoader_0354b7e2_09d17bb5de42d5d9.bytecode b/patcher/tst/dex/PathClassLoader_0354b7e2_09d17bb5de42d5d9.bytecode deleted file mode 100644 index 58770fc..0000000 Binary files a/patcher/tst/dex/PathClassLoader_0354b7e2_09d17bb5de42d5d9.bytecode and /dev/null differ diff --git a/patcher/tst/dex/PathClassLoader_07069310_09d17bb5de42d5d9.bytecode b/patcher/tst/dex/PathClassLoader_07069310_09d17bb5de42d5d9.bytecode deleted file mode 100644 index 58770fc..0000000 Binary files a/patcher/tst/dex/PathClassLoader_07069310_09d17bb5de42d5d9.bytecode and /dev/null differ diff --git a/patcher/tst/runtime.json b/patcher/tst/runtime.json deleted file mode 100644 index cd44ccf..0000000 --- a/patcher/tst/runtime.json +++ /dev/null @@ -1,168 +0,0 @@ -{ - "invoke_data": [ - { - "method": "Lcom/example/theseus/dynloading/Collider;->getColliderId()Ljava/lang/String;", - "method_cl_id": "0620d2cb", - "renamed_method": null, - "caller_method": "Lcom/example/theseus/dynloading/MainActivity;->directWithParent()V", - "caller_cl_id": "0620d2cb", - "renamed_caller_method": null, - "addr": 39, - "is_static": true - }, - { - "method": "Lcom/example/theseus/dynloading/AMain;->getColliderId()Ljava/lang/String;", - "method_cl_id": "012faa7a", - "renamed_method": null, - "caller_method": "Lcom/example/theseus/dynloading/MainActivity;->indirectWithoutParent()V", - "caller_cl_id": "0620d2cb", - "renamed_caller_method": null, - "addr": 33, - "is_static": true - }, - { - "method": "Lcom/example/theseus/dynloading/AMain;->getColliderId()Ljava/lang/String;", - "method_cl_id": "00a972ce", - "renamed_method": null, - "caller_method": "Lcom/example/theseus/dynloading/MainActivity;->indirectWithParent()V", - "caller_cl_id": "0620d2cb", - "renamed_caller_method": null, - "addr": 39, - "is_static": true - }, - { - "method": "Lcom/example/theseus/dynloading/Collider;->getColliderId()Ljava/lang/String;", - "method_cl_id": "0354b7e2", - "renamed_method": null, - "caller_method": "Lcom/example/theseus/dynloading/MainActivity;->directWithoutParent()V", - "caller_cl_id": "0620d2cb", - "renamed_caller_method": null, - "addr": 33, - "is_static": true - } - ], - "class_new_inst_data": [ - { - "constructor": "Landroid/app/Application;->()V", - "constructor_cl_id": "00aaeddc", - "renamed_constructor": null, - "caller_method": "Landroid/app/AppComponentFactory;->instantiateApplication(Ljava/lang/ClassLoader;Ljava/lang/String;)Landroid/app/Application;", - "caller_cl_id": "00aaeddc", - "renamed_caller_method": null, - "addr": 4 - }, - { - "constructor": "Lcom/example/theseus/dynloading/MainActivity;->()V", - "constructor_cl_id": "0620d2cb", - "renamed_constructor": null, - "caller_method": "Landroid/app/AppComponentFactory;->instantiateActivity(Ljava/lang/ClassLoader;Ljava/lang/String;Landroid/content/Intent;)Landroid/app/Activity;", - "caller_cl_id": "00aaeddc", - "renamed_caller_method": null, - "addr": 4 - } - ], - "cnstr_new_inst_data": [], - "dyn_code_load": [ - { - "classloader_class": "Ldalvik/system/PathClassLoader;", - "classloader": "07069310", - "files": [ - "./tst/dex/PathClassLoader_07069310_09d17bb5de42d5d9.bytecode" - ], - "classloader_parent": "0620d2cb" - }, - { - "classloader_class": "Ldalvik/system/PathClassLoader;", - "classloader": "012faa7a", - "files": [ - "./tst/dex/PathClassLoader_012faa7a_09d17bb5de42d5d9.bytecode" - ], - "classloader_parent": null - }, - { - "classloader_class": "Ldalvik/system/PathClassLoader;", - "classloader": "00a972ce", - "files": [ - "./tst/dex/PathClassLoader_00a972ce_09d17bb5de42d5d9.bytecode" - ], - "classloader_parent": "0620d2cb" - }, - { - "classloader_class": "Ldalvik/system/PathClassLoader;", - "classloader": "0354b7e2", - "files": [ - "./tst/dex/PathClassLoader_0354b7e2_09d17bb5de42d5d9.bytecode" - ], - "classloader_parent": null - } - ], - "classloaders": [ - { - "id": "0096a9c1", - "parent_id": "00aaeddc", - "str": "dalvik.system.PathClassLoader[DexPathList[[directory \".\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64, /system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - }, - { - "id": "00aaeddc", - "parent_id": null, - "str": "java.lang.BootClassLoader@aaeddc", - "cname": "java.lang.BootClassLoader" - }, - { - "id": "0035caa8", - "parent_id": null, - "str": "dalvik.system.InMemoryDexClassLoader[DexPathList[[dex file \"InMemoryDexFile[cookie=[0, 128037698188144]]\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.InMemoryDexClassLoader" - }, - { - "id": "0096a9c1", - "parent_id": "00aaeddc", - "str": "dalvik.system.PathClassLoader[DexPathList[[directory \".\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64, /system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - }, - { - "id": "00aaeddc", - "parent_id": null, - "str": "java.lang.BootClassLoader@aaeddc", - "cname": "java.lang.BootClassLoader" - }, - { - "id": "0035caa8", - "parent_id": null, - "str": "dalvik.system.InMemoryDexClassLoader[DexPathList[[dex file \"InMemoryDexFile[cookie=[0, 128037698188144]]\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.InMemoryDexClassLoader" - }, - { - "id": "0620d2cb", - "parent_id": "00aaeddc", - "str": "dalvik.system.PathClassLoader[DexPathList[[zip file \"/data/app/~~G73yvcDB8EWWZQoHd7RyMQ==/com.example.theseus.dynloading-9TbLe3e6jrCqYe-MsGwAPA==/base.apk\"],nativeLibraryDirectories=[/data/app/~~G73yvcDB8EWWZQoHd7RyMQ==/com.example.theseus.dynloading-9TbLe3e6jrCqYe-MsGwAPA==/lib/x86_64, /system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - }, - { - "id": "07069310", - "parent_id": "0620d2cb", - "str": "dalvik.system.PathClassLoader[DexPathList[[dex file \"/data/user/0/com.example.theseus.dynloading/cache/a.dex\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - }, - { - "id": "012faa7a", - "parent_id": null, - "str": "dalvik.system.PathClassLoader[DexPathList[[dex file \"/data/user/0/com.example.theseus.dynloading/cache/a.dex\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - }, - { - "id": "00a972ce", - "parent_id": "0620d2cb", - "str": "dalvik.system.PathClassLoader[DexPathList[[dex file \"/data/user/0/com.example.theseus.dynloading/cache/a.dex\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - }, - { - "id": "0354b7e2", - "parent_id": null, - "str": "dalvik.system.PathClassLoader[DexPathList[[dex file \"/data/user/0/com.example.theseus.dynloading/cache/a.dex\"],nativeLibraryDirectories=[/system/lib64, /system_ext/lib64]]]", - "cname": "dalvik.system.PathClassLoader" - } - ], - "apk_cl_id": "0035caa8" -} diff --git a/theseus_autopatcher/build.sh b/theseus_autopatcher/build.sh index 8e11b3a..60bc190 100644 --- a/theseus_autopatcher/build.sh +++ b/theseus_autopatcher/build.sh @@ -5,7 +5,7 @@ FOLDER=$(dirname "$(realpath $0)") -env --chdir "${FOLDER}/../patcher" cargo build --release --target=x86_64-unknown-linux-musl -cp "${FOLDER}/../patcher/target/x86_64-unknown-linux-musl/release/patcher" "${FOLDER}/src/theseus_autopatcher/patcher_86_64_musl" +env --chdir "${FOLDER}/../patcher" cargo build --profile minsizerelease --target=x86_64-unknown-linux-musl +cp "${FOLDER}/../patcher/target/x86_64-unknown-linux-musl/minsizerelease/patcher" "${FOLDER}/src/theseus_autopatcher/patcher_86_64_musl" env --chdir "${FOLDER}" poetry build diff --git a/theseus_autopatcher/src/theseus_autopatcher/__init__.py b/theseus_autopatcher/src/theseus_autopatcher/__init__.py index 20a28dd..0f52813 100644 --- a/theseus_autopatcher/src/theseus_autopatcher/__init__.py +++ b/theseus_autopatcher/src/theseus_autopatcher/__init__.py @@ -19,7 +19,12 @@ def patch_apk( zipalign: Path, apksigner: Path, keystore: Path, + keypass: None | str = None, ): + optional_args = [] + if keypass is not None: + optional_args.append("--keypassword") + optional_args.append(keypass) subprocess.run( [ str(PATCHER_BIN_PATH.absolute()), @@ -37,6 +42,7 @@ def patch_apk( str(apksigner.absolute()), "--code-loading-patch-strategy", "model-class-loaders", + *optional_args, ] ) @@ -80,6 +86,13 @@ def main(): type=Path, default=Path(".") / "TheseusKey.keystore", ) + parser.add_argument( + "-kp", + "--keypass", + required=False, + help="Password for the key in the keystore", + type=str, + ) parser.add_argument( "--keytool", required=False, @@ -90,7 +103,7 @@ def main(): "--patch", required=False, help="Path to the patcher executable to use. By default, use the one embeded with \ - the package. (static x86_64 linux build with musl)", + the package. (static x86_64 linux build with musl optimized for binary size instead of speed)", type=Path, ) args = parser.parse_args() @@ -131,7 +144,9 @@ def main(): exit(1) if not args.keystore.exists(): - gen_keystore(keytool, args.keystore) + if args.keypass is None: + args.keypass = "P@ssw0rd!" + gen_keystore(keytool, args.keystore, args.keypass) with tempfile.TemporaryDirectory() as tmpdname: tmpd = Path(tmpdname) @@ -151,4 +166,5 @@ def main(): zipalign=zipalign, apksigner=apksigner, keystore=args.keystore, + keypass=args.keypass, ) diff --git a/theseus_autopatcher/src/theseus_autopatcher/utils.py b/theseus_autopatcher/src/theseus_autopatcher/utils.py index ead0cd2..ebaf437 100644 --- a/theseus_autopatcher/src/theseus_autopatcher/utils.py +++ b/theseus_autopatcher/src/theseus_autopatcher/utils.py @@ -66,7 +66,7 @@ def get_keytool_path() -> Path | None: return None -def gen_keystore(keytool: Path, storepath: Path): +def gen_keystore(keytool: Path, storepath: Path, keypass: str): print(f"{str(storepath)} does not exist, creating it.") subprocess.run( [ @@ -78,6 +78,10 @@ def gen_keystore(keytool: Path, storepath: Path): "CN=SomeKey,O=SomeOne,C=FR", "-keystore", str(storepath), + "-storepass", + keypass, + "-keypass", + keypass, "-alias", "SignKey", "-keyalg", diff --git a/theseus_autopatcher/test.sh b/theseus_autopatcher/test.sh index 4c4f7c4..a05b3f2 100644 --- a/theseus_autopatcher/test.sh +++ b/theseus_autopatcher/test.sh @@ -20,6 +20,7 @@ pip install "${FOLDER}/dist/theseus_autopatcher-0.1.0-py3-none-any.whl[grodd]" adb wait-for-device -theseus-autopatch -a "${FOLDER}/../test_apks/dynloading/build/test_dynloading.apk" -o /tmp/patched_dynloading.apk -k "${FOLDER}/../test_apks/dynloading/ToyKey.keystore" +#theseus-autopatch -a "${FOLDER}/../test_apks/dynloading/build/test_dynloading.apk" -o /tmp/patched_dynloading.apk -k "${FOLDER}/../test_apks/dynloading/ToyKey.keystore" +theseus-autopatch -a "${FOLDER}/../test_apks/dynloading/build/test_dynloading.apk" -o /tmp/patched_dynloading.apk -k /tmp/kstore.keystore -kp 'P@ssw0rd!' rm -rf "${TMP}"