fix void function return handling

This commit is contained in:
Jean-Marie Mineau 2025-06-18 17:32:39 +02:00
parent 606c635a91
commit bdea6c0300
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
4 changed files with 24 additions and 25 deletions

1
patcher/.gitignore vendored
View file

@ -1 +1,2 @@
target target
tests

View file

@ -6,8 +6,8 @@ edition = "2024"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
#androscalpel = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "110f0c0", features = ["code-analysis", "platform-list"] } #androscalpel = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "3a0b9bb", features = ["code-analysis", "platform-list"] }
#apk_frauder = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "110f0c0"} #apk_frauder = { git = "ssh://git@gitlab.inria.fr/androidoftheseus/androscalpel.git", rev = "3a0b9bb"}
androscalpel = { path = "../../androscalpel/androscalpel", features = ["code-analysis", "platform-list"] } androscalpel = { path = "../../androscalpel/androscalpel", features = ["code-analysis", "platform-list"] }
apk_frauder = { path = "../../androscalpel/apk_frauder"} apk_frauder = { path = "../../androscalpel/apk_frauder"}
anyhow = { version = "1.0.95", features = ["backtrace"] } anyhow = { version = "1.0.95", features = ["backtrace"] }

View file

@ -43,6 +43,7 @@ fn main() {
env_logger::init(); env_logger::init();
let cli = Cli::parse(); let cli = Cli::parse();
let mut apk = Apk::load_apk(File::open(&cli.path).unwrap(), labeling, false).unwrap(); let mut apk = Apk::load_apk(File::open(&cli.path).unwrap(), labeling, false).unwrap();
//println!("{:#?}", apk.list_classes()); //println!("{:#?}", apk.list_classes());
let mut json = String::new(); let mut json = String::new();
File::open(&cli.runtime_data) File::open(&cli.runtime_data)
@ -107,19 +108,9 @@ fn main() {
.into_values() .into_values()
.map(|v| (v.descriptor.clone(), v)) .map(|v| (v.descriptor.clone(), v))
.collect(); .collect();
// Add the new testing class in a separateed dex file to avoid breaking apk.add_class("classes.dex", class).unwrap();
// the dex method limit. apk.redistribute_classes();
// TODO: check the number of methods in the existing dex files to avoid generated
// a new one each time.
let mut i = 2;
let new_dex_name = loop {
let name = format!("classes{}.dex", i);
if !apk.dex_files.contains_key(&name) {
break name;
};
i += 1;
};
apk.add_class(&new_dex_name, class).unwrap();
let mut dex_files = vec![]; let mut dex_files = vec![];
let mut files = apk.gen_raw_dex().unwrap(); let mut files = apk.gen_raw_dex().unwrap();
let mut i = 0; let mut i = 0;

View file

@ -1346,7 +1346,7 @@ fn get_invoke_block(
arg_arr, arg_arr,
reg_inf.first_arg + if ref_data.is_static { 0 } else { 1 }, reg_inf.first_arg + if ref_data.is_static { 0 } else { 1 },
reg_inf, reg_inf,
)); )?);
if ref_data.is_static { if ref_data.is_static {
insns.push(Instruction::InvokeStatic { insns.push(Instruction::InvokeStatic {
method: ref_data.get_static_callee(), method: ref_data.get_static_callee(),
@ -1375,7 +1375,7 @@ fn get_invoke_block(
to: reg_inf.array_val, to: reg_inf.array_val,
}); });
insns.push(Instruction::InvokeStatic { insns.push(Instruction::InvokeStatic {
method: get_scalar_to_obj_method(&ret_ty).unwrap(), method: get_scalar_to_obj_method(&ret_ty)?,
args: vec![reg_inf.array_val as u16, (reg_inf.array_val + 1) as u16], args: vec![reg_inf.array_val as u16, (reg_inf.array_val + 1) as u16],
}); });
insns.push(move_result); insns.push(move_result);
@ -1383,12 +1383,19 @@ fn get_invoke_block(
reg: res_reg, reg: res_reg,
lit: OBJECT_TY.clone(), lit: OBJECT_TY.clone(),
}); });
} else if ret_ty.is_void() {
// Void is represented by a null object
insns.push(Instruction::Const {
reg: res_reg,
lit: 0,
});
insns.push(move_result);
} else { } else {
insns.push(Instruction::MoveResult { insns.push(Instruction::MoveResult {
to: reg_inf.array_val, to: reg_inf.array_val,
}); });
insns.push(Instruction::InvokeStatic { insns.push(Instruction::InvokeStatic {
method: get_scalar_to_obj_method(&ret_ty).unwrap(), method: get_scalar_to_obj_method(&ret_ty)?,
args: vec![reg_inf.array_val as u16], args: vec![reg_inf.array_val as u16],
}); });
insns.push(move_result); insns.push(move_result);
@ -1415,7 +1422,7 @@ fn get_args_from_obj_arr(
array_reg: u16, array_reg: u16,
first_arg_reg: u16, first_arg_reg: u16,
reg_inf: &mut RegistersInfo, reg_inf: &mut RegistersInfo,
) -> Vec<Instruction> { ) -> Result<Vec<Instruction>> {
let mut insns = vec![]; let mut insns = vec![];
let mut restore_array = vec![]; let mut restore_array = vec![];
let mut reg_count = 0; let mut reg_count = 0;
@ -1455,10 +1462,10 @@ fn get_args_from_obj_arr(
} else if param.is_double() || param.is_long() { } else if param.is_double() || param.is_long() {
insns.push(Instruction::CheckCast { insns.push(Instruction::CheckCast {
reg: reg_inf.array_val, reg: reg_inf.array_val,
lit: get_obj_of_scalar(param).unwrap(), lit: get_obj_of_scalar(param)?,
}); });
insns.push(Instruction::InvokeVirtual { insns.push(Instruction::InvokeVirtual {
method: get_obj_to_scalar_method(param).unwrap(), method: get_obj_to_scalar_method(param)?,
args: vec![reg_inf.array_val as u16], args: vec![reg_inf.array_val as u16],
}); });
insns.push(Instruction::MoveResultWide { insns.push(Instruction::MoveResultWide {
@ -1472,10 +1479,10 @@ fn get_args_from_obj_arr(
} else { } else {
insns.push(Instruction::CheckCast { insns.push(Instruction::CheckCast {
reg: reg_inf.array_val, reg: reg_inf.array_val,
lit: get_obj_of_scalar(param).unwrap(), lit: get_obj_of_scalar(param)?,
}); });
insns.push(Instruction::InvokeVirtual { insns.push(Instruction::InvokeVirtual {
method: get_obj_to_scalar_method(param).unwrap(), method: get_obj_to_scalar_method(param)?,
args: vec![reg_inf.array_val as u16], args: vec![reg_inf.array_val as u16],
}); });
insns.push(Instruction::MoveResult { insns.push(Instruction::MoveResult {
@ -1489,7 +1496,7 @@ fn get_args_from_obj_arr(
} }
} }
insns.append(&mut restore_array); insns.append(&mut restore_array);
insns Ok(insns)
} }
pub(crate) static ABORD_LABELS: std::sync::LazyLock< pub(crate) static ABORD_LABELS: std::sync::LazyLock<
@ -1557,7 +1564,7 @@ fn get_cnstr_new_inst_block(
arg_arr, arg_arr,
reg_inf.first_arg + 1, reg_inf.first_arg + 1,
reg_inf, reg_inf,
)); )?);
if reg_inf.first_arg < u8::MAX as u16 { if reg_inf.first_arg < u8::MAX as u16 {
insns.push(Instruction::NewInstance { insns.push(Instruction::NewInstance {
reg: reg_inf.first_arg as u8, reg: reg_inf.first_arg as u8,