diff --git a/patcher/.cargo/config b/patcher/.cargo/config.toml similarity index 100% rename from patcher/.cargo/config rename to patcher/.cargo/config.toml diff --git a/patcher/Cargo.lock b/patcher/Cargo.lock index 7ae4345..d4c23d0 100644 --- a/patcher/Cargo.lock +++ b/patcher/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -35,12 +35,12 @@ dependencies = [ [[package]] name = "androscalpel" version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git#4b4ef6032dd3a9a756607b327b4224f18d2ce94f" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=095ce2ce9340a7050aceb11ba626a1a9a966436a#095ce2ce9340a7050aceb11ba626a1a9a966436a" dependencies = [ "adler", - "androscalpel_serializer 0.1.0 (git+ssh://git@git.mineau.eu/histausse/androscalpel.git)", + "androscalpel_serializer", "anyhow", - "apk_frauder 0.1.0 (git+ssh://git@git.mineau.eu/histausse/androscalpel.git)", + "apk_frauder", "log", "rayon", "serde", @@ -51,33 +51,16 @@ dependencies = [ [[package]] name = "androscalpel_serializer" version = "0.1.0" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=095ce2ce9340a7050aceb11ba626a1a9a966436a#095ce2ce9340a7050aceb11ba626a1a9a966436a" dependencies = [ - "androscalpel_serializer_derive 0.1.0", - "log", -] - -[[package]] -name = "androscalpel_serializer" -version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git#4b4ef6032dd3a9a756607b327b4224f18d2ce94f" -dependencies = [ - "androscalpel_serializer_derive 0.1.0 (git+ssh://git@git.mineau.eu/histausse/androscalpel.git)", + "androscalpel_serializer_derive", "log", ] [[package]] name = "androscalpel_serializer_derive" version = "0.1.0" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "androscalpel_serializer_derive" -version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git#4b4ef6032dd3a9a756607b327b4224f18d2ce94f" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=095ce2ce9340a7050aceb11ba626a1a9a966436a#095ce2ce9340a7050aceb11ba626a1a9a966436a" dependencies = [ "proc-macro2", "quote", @@ -146,19 +129,9 @@ dependencies = [ [[package]] name = "apk_frauder" version = "0.1.0" +source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git?rev=095ce2ce9340a7050aceb11ba626a1a9a966436a#095ce2ce9340a7050aceb11ba626a1a9a966436a" dependencies = [ - "androscalpel_serializer 0.1.0", - "flate2", - "log", - "rand", -] - -[[package]] -name = "apk_frauder" -version = "0.1.0" -source = "git+ssh://git@git.mineau.eu/histausse/androscalpel.git#4b4ef6032dd3a9a756607b327b4224f18d2ce94f" -dependencies = [ - "androscalpel_serializer 0.1.0 (git+ssh://git@git.mineau.eu/histausse/androscalpel.git)", + "androscalpel_serializer", "flate2", "log", "rand", @@ -838,7 +811,7 @@ version = "0.1.0" dependencies = [ "androscalpel", "anyhow", - "apk_frauder 0.1.0", + "apk_frauder", "clap", "env_logger", "reqwest", diff --git a/patcher/Cargo.toml b/patcher/Cargo.toml index f10c366..2c384ba 100644 --- a/patcher/Cargo.toml +++ b/patcher/Cargo.toml @@ -6,9 +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" } -#apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git" } -apk_frauder = { path = "/home/histausse/workspace/dev/Project/androscalpel/apk_frauder" } +androscalpel = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "095ce2ce9340a7050aceb11ba626a1a9a966436a" } +apk_frauder = { git = "ssh://git@git.mineau.eu/histausse/androscalpel.git", rev = "095ce2ce9340a7050aceb11ba626a1a9a966436a"} anyhow = "1.0.95" clap = { version = "4.5.27", features = ["derive"] } env_logger = "0.11.6" diff --git a/patcher/src/get_apk.rs b/patcher/src/get_apk.rs index 3c7fc32..25ba690 100644 --- a/patcher/src/get_apk.rs +++ b/patcher/src/get_apk.rs @@ -1,6 +1,6 @@ use androscalpel::Apk; use clap::Args; -use std::fs::read_to_string; +use std::fs::{read_to_string, File}; use std::path::PathBuf; use std::time::Duration; @@ -83,7 +83,7 @@ pub fn get_apk(location: &ApkLocation) -> Apk { } ApkLocation { path: Some(path), .. - } => Apk::load_apk(path.into(), false, false).unwrap(), + } => Apk::load_apk(File::open(path).unwrap(), |_, _, _| None, false).unwrap(), _ => panic!("Don't know what to do with:\n{:#?}", location), } } diff --git a/patcher/src/lib.rs b/patcher/src/lib.rs index 263e9cf..6eab25a 100644 --- a/patcher/src/lib.rs +++ b/patcher/src/lib.rs @@ -1,4 +1,4 @@ -use androscalpel::{IdMethod, IdType, Instruction, Method}; +use androscalpel::{IdMethod, Instruction, Method}; use anyhow::{bail, Context, Result}; use std::sync::LazyLock; @@ -83,19 +83,34 @@ pub fn transform_method(meth: &mut Method, ref_data: &ReflectionData) -> Result< nb_arg_reg: 0, }; let mut new_insns = vec![]; - for ins in &code.insns { + let mut iter = code.insns.iter().peekable(); + while let Some(ins) = iter.next() { match ins { Instruction::InvokeVirtual { method, args } if method == &*MTH_INVOKE => { - // TODO move ret ? + let move_ret = match iter.peek() { + Some(Instruction::MoveResult { .. }) + | Some(Instruction::MoveResultWide { .. }) + | Some(Instruction::MoveResultObject { .. }) => iter.next().cloned(), + _ => None, + }; // TODO: rever from get_invoke_block failure let label: String = "TODO_NAME_THIS".into(); - for ins in get_invoke_block(ref_data, args.as_slice(), &mut register_info, &label)? - .into_iter() + for ins in get_invoke_block( + ref_data, + args.as_slice(), + &mut register_info, + &label, + move_ret.clone(), + )? + .into_iter() { println!(" \x1b[92m{}\x1b[0m", ins.__str__()); new_insns.push(ins); } new_insns.push(ins.clone()); + if let Some(move_ret) = move_ret { + new_insns.push(move_ret); + } println!(" \x1b[91m{}\x1b[0m", ins.__str__()); let lab = Instruction::Label { name: format!("{label}_END"), @@ -134,6 +149,7 @@ fn get_invoke_block( invoke_arg: &[u16], reg_inf: &mut RegistersInfo, label: &str, + move_result: Option, ) -> Result> { let (method_obj, obj_inst, arg_arr) = if let &[a, b, c] = invoke_arg { (a, b, c) @@ -216,9 +232,22 @@ fn get_invoke_block( method: MTH_GET_PARAMS_TY.clone(), args: vec![method_obj], }); - insns.push(Instruction::MoveResultObject { - to: reg_inf.array, // wrong name, but available for tmp val + insns.push(Instruction::MoveResultObject { to: reg_inf.array }); + // First check the number of args + insns.push(Instruction::ArrayLength { + dest: reg_inf.array_index, + arr: reg_inf.array, }); + insns.push(Instruction::Const { + reg: reg_inf.array_val, + lit: ref_data.method.proto.get_parameters().len() as i32, + }); + insns.push(Instruction::IfNe { + a: reg_inf.array_index, + b: reg_inf.array_val, + label: format!("{label}_END_OF_CALL_1"), // TODO: rename 1 + }); + // then the type of each arg for (i, param) in ref_data .method .proto @@ -274,6 +303,9 @@ fn get_invoke_block( method: ref_data.method.clone(), args: (reg_inf.first_arg..reg_inf.first_arg + 1 + nb_args as u16).collect(), }); + if let Some(move_result) = move_result { + insns.push(move_result); + } insns.push(Instruction::Goto { label: format!("{label}_END"), }); diff --git a/test_apks/tests/java/classes/com/example/theseus/tests/MainActivity.java b/test_apks/tests/java/classes/com/example/theseus/tests/MainActivity.java index 2d3573f..917caca 100644 --- a/test_apks/tests/java/classes/com/example/theseus/tests/MainActivity.java +++ b/test_apks/tests/java/classes/com/example/theseus/tests/MainActivity.java @@ -50,6 +50,7 @@ public class MainActivity extends Activity { ClassLoader cl = MainActivity.class.getClassLoader(); Class clz = cl.loadClass("com.example.theseus.tests.Reflectee"); Method mth = clz.getMethod("transfer", String.class); + /* String name = mth.getName(); Class[] params = mth.getParameterTypes(); Class ret = mth.getReturnType(); @@ -60,7 +61,14 @@ public class MainActivity extends Activity { Log.e("[TEST]", ret.toString()); Log.e("[TEST]", dec.toString()); Log.e("[TEST]", "---------------------------------"); - if (name.equals("transfer") && Arrays.equals(params, new Class[] {String.class}) && ret == String.class && dec == Reflectee.class) { + */ + Class[] params = mth.getParameterTypes(); + if ( + mth.getName().equals("transfer") && + ret == String.class && + dec == Reflectee.class && + params.length == 1 && + params[0] == String.class { Log.e("[TEST]", "OK"); } String newData = (String) mth.invoke(r, data);