diff --git a/frida/pyproject.toml b/frida/pyproject.toml index f38ef4e..ed85dbe 100644 --- a/frida/pyproject.toml +++ b/frida/pyproject.toml @@ -19,7 +19,7 @@ requires = ["poetry-core>=2.0.0,<3.0.0"] build-backend = "poetry.core.masonry.api" [tool.poetry.scripts] -collect-reflection-data = 'theseus_frida.__init__:main' +collect-runtime-data = 'theseus_frida.__init__:main' [tool.poetry] include = [ diff --git a/frida/theseus_frida/__init__.py b/frida/theseus_frida/__init__.py index 8e55fb5..9e54332 100644 --- a/frida/theseus_frida/__init__.py +++ b/frida/theseus_frida/__init__.py @@ -141,7 +141,10 @@ def handle_cnstr_new_inst_data(data, data_storage: dict): def handle_load_dex(data, data_storage: dict, file_storage: Path): dex = data["dex"] classloader_class = data["classloader_class"] - classloader = data["classloader"].hex() + classloader = data["classloader"] + if classloader < 0: + classloader += 2 << (HASH_NB_BYTES * 8 - 1) + classloader = classloader.to_bytes(HASH_NB_BYTES).hex() short_class = classloader_class.split("/")[-1].removesuffix(";") files = [] print("DEX file loaded:") diff --git a/patcher/Cargo.lock b/patcher/Cargo.lock index 63e65d5..26f5029 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=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" 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=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" 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=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" 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=610347554d7e46a9213f45b09b76ba7e2bce201b#610347554d7e46a9213f45b09b76ba7e2bce201b" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=4c4940e6b1e1760617d2cb86f83a27a7a8e187da#4c4940e6b1e1760617d2cb86f83a27a7a8e187da" dependencies = [ "androscalpel_serializer", "flate2", diff --git a/patcher/Cargo.toml b/patcher/Cargo.toml index 6a12040..04c6d2e 100644 --- a/patcher/Cargo.toml +++ b/patcher/Cargo.toml @@ -6,8 +6,8 @@ edition = "2021" # 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 = "610347554d7e46a9213f45b09b76ba7e2bce201b", features = ["code-analysis"] } -apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "610347554d7e46a9213f45b09b76ba7e2bce201b"} +androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "4c4940e6b1e1760617d2cb86f83a27a7a8e187da", features = ["code-analysis"] } +apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "4c4940e6b1e1760617d2cb86f83a27a7a8e187da"} anyhow = { version = "1.0.95", features = ["backtrace"] } clap = { version = "4.5.27", features = ["derive"] } env_logger = "0.11.6" diff --git a/patcher/src/bin/patcher.rs b/patcher/src/bin/patcher.rs index afa437e..2e7295d 100644 --- a/patcher/src/bin/patcher.rs +++ b/patcher/src/bin/patcher.rs @@ -6,6 +6,7 @@ use std::path::PathBuf; use androscalpel::Apk; use patcher::{ + code_loading_patcher::insert_code, labeling, reflection_patcher::transform_method, runtime_data::RuntimeData, // ReflectionInvokeData, ReflectionClassNewInstData, ReflectionCnstrNewInstData, @@ -27,7 +28,7 @@ struct Cli { #[arg(short, long)] path: PathBuf, #[arg(short, long)] - reflection_data: PathBuf, + runtime_data: PathBuf, } fn main() { @@ -36,13 +37,13 @@ fn main() { let mut apk = Apk::load_apk(File::open(&cli.path).unwrap(), labeling, false).unwrap(); //println!("{:#?}", apk.list_classes()); let mut json = String::new(); - File::open(&cli.reflection_data) + File::open(&cli.runtime_data) .unwrap() .read_to_string(&mut json) .unwrap(); - let reflection_data: RuntimeData = serde_json::from_str(&json).unwrap(); + let rt_data: RuntimeData = serde_json::from_str(&json).unwrap(); /* - let reflection_data = RuntimeData { + let rt_data = RuntimeData { invoke_data: vec![ ReflectionInvokeData { method: IdMethod::from_smali( @@ -112,14 +113,15 @@ fn main() { addr: 0x22, }], }; - println!("{}", serde_json::to_string(&reflection_data).unwrap()); + println!("{}", serde_json::to_string(&rt_data).unwrap()); */ - for method in reflection_data.get_method_referenced().iter() { + insert_code(&mut apk, &rt_data).unwrap(); + for method in rt_data.get_method_referenced().iter() { if let Some(class) = apk.get_class_mut(&method.class_) { //println!("{:#?}", class.direct_methods.keys()); //println!("{:#?}", class.virtual_methods.keys()); let method = class.virtual_methods.get_mut(method).unwrap(); - transform_method(method, &reflection_data).unwrap(); + transform_method(method, &rt_data).unwrap(); } } let mut dex_files = vec![]; @@ -138,7 +140,7 @@ fn main() { } i += 1; } - // TODO: aapt would be a lot more stable + // TODO: aapt would be a lot more stable? apk_frauder::replace_dex( cli.path, cli.out, diff --git a/patcher/src/code_loading_patcher.rs b/patcher/src/code_loading_patcher.rs new file mode 100644 index 0000000..e03f449 --- /dev/null +++ b/patcher/src/code_loading_patcher.rs @@ -0,0 +1,18 @@ +use std::fs::File; + +use androscalpel::Apk; +use anyhow::Result; + +use crate::runtime_data::RuntimeData; + +/// Insert statically bytecode that was loaded from other source at runtime. +/// For now, we ignore class collision. +pub fn insert_code(apk: &mut Apk, data: &RuntimeData) -> Result<()> { + for dyn_data in &data.dyn_code_load { + for file in &dyn_data.files { + let file = File::open(file)?; + apk.add_code(file, crate::labeling, false)?; + } + } + Ok(()) +} diff --git a/patcher/src/lib.rs b/patcher/src/lib.rs index 80ac18e..3bc00ef 100644 --- a/patcher/src/lib.rs +++ b/patcher/src/lib.rs @@ -1,5 +1,6 @@ use androscalpel::{IdMethod, Instruction}; +pub mod code_loading_patcher; pub mod dex_types; pub mod reflection_patcher; pub mod register_manipulation;