patch static invocation
This commit is contained in:
parent
91fd0137d8
commit
b33807edde
1 changed files with 36 additions and 30 deletions
|
|
@ -114,7 +114,8 @@ pub struct ReflectionInvokeData {
|
||||||
pub caller_method: IdMethod,
|
pub caller_method: IdMethod,
|
||||||
/// Address where the call to `java.lang.reflect.Method.invoke()` was made in `caller_method`.
|
/// Address where the call to `java.lang.reflect.Method.invoke()` was made in `caller_method`.
|
||||||
pub addr: usize,
|
pub addr: usize,
|
||||||
// TODO: variable number of args?
|
/// If the method is static (static method don't take 'this' as argument)
|
||||||
|
pub is_static: bool,
|
||||||
// TODO: type of invoke?
|
// TODO: type of invoke?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -924,14 +925,10 @@ fn get_invoke_block(
|
||||||
(a, b, c)
|
(a, b, c)
|
||||||
} else {
|
} else {
|
||||||
bail!(
|
bail!(
|
||||||
"Method;->invoke arg should have exactrly 3 arguments, found {}",
|
"Method;->invoke arg should have exactly 3 arguments, found {}",
|
||||||
invoke_arg.len()
|
invoke_arg.len()
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
if arg_arr > u8::MAX as u16 {
|
|
||||||
// TODO
|
|
||||||
bail!("Cannot transform invoke calls to a method using 16 bits register for its argument");
|
|
||||||
}
|
|
||||||
let nb_args: usize = ref_data
|
let nb_args: usize = ref_data
|
||||||
.method
|
.method
|
||||||
.proto
|
.proto
|
||||||
|
|
@ -939,14 +936,14 @@ fn get_invoke_block(
|
||||||
.iter()
|
.iter()
|
||||||
.map(|ty| if ty.is_double() || ty.is_long() { 2 } else { 1 })
|
.map(|ty| if ty.is_double() || ty.is_long() { 2 } else { 1 })
|
||||||
.sum();
|
.sum();
|
||||||
if reg_inf.nb_arg_reg < nb_args as u16 + 1 {
|
if reg_inf.nb_arg_reg < nb_args as u16 + if ref_data.is_static { 0 } else { 1 } {
|
||||||
reg_inf.nb_arg_reg = nb_args as u16 + 1;
|
reg_inf.nb_arg_reg = nb_args as u16 + if ref_data.is_static { 0 } else { 1 };
|
||||||
}
|
}
|
||||||
|
|
||||||
let abort_label = format!(
|
let abort_label = format!(
|
||||||
"end_static_call_to_{}_at_{}",
|
"end_static_call_to_{}_at_{:08X}",
|
||||||
ref_data.method.try_to_smali()?,
|
ref_data.method.try_to_smali()?,
|
||||||
"TODO_ADDR"
|
ref_data.addr
|
||||||
);
|
);
|
||||||
let mut insns = test_method(
|
let mut insns = test_method(
|
||||||
method_obj,
|
method_obj,
|
||||||
|
|
@ -955,31 +952,40 @@ fn get_invoke_block(
|
||||||
reg_inf,
|
reg_inf,
|
||||||
);
|
);
|
||||||
|
|
||||||
// Move 'this' to fist arg
|
if !ref_data.is_static {
|
||||||
// We do a small detour to `reg_inf.array_val` because we need a u8 reg to down cast the
|
// Move 'this' to fist arg
|
||||||
// Object reference to the right Class
|
// We do a small detour to `reg_inf.array_val` because we need a u8 reg to down cast the
|
||||||
insns.push(Instruction::MoveObject {
|
// Object reference to the right Class
|
||||||
from: obj_inst,
|
insns.push(Instruction::MoveObject {
|
||||||
to: reg_inf.array_val as u16,
|
from: obj_inst,
|
||||||
});
|
to: reg_inf.array_val as u16,
|
||||||
insns.push(Instruction::CheckCast {
|
});
|
||||||
reg: reg_inf.array_val,
|
insns.push(Instruction::CheckCast {
|
||||||
lit: ref_data.method.class_.clone(),
|
reg: reg_inf.array_val,
|
||||||
});
|
lit: ref_data.method.class_.clone(),
|
||||||
insns.push(Instruction::MoveObject {
|
});
|
||||||
from: reg_inf.array_val as u16,
|
insns.push(Instruction::MoveObject {
|
||||||
to: reg_inf.first_arg,
|
from: reg_inf.array_val as u16,
|
||||||
});
|
to: reg_inf.first_arg,
|
||||||
|
});
|
||||||
|
}
|
||||||
insns.append(&mut get_args_from_obj_arr(
|
insns.append(&mut get_args_from_obj_arr(
|
||||||
&ref_data.method.proto.get_parameters(),
|
&ref_data.method.proto.get_parameters(),
|
||||||
arg_arr,
|
arg_arr,
|
||||||
reg_inf.first_arg + 1,
|
reg_inf.first_arg + if ref_data.is_static { 0 } else { 1 },
|
||||||
reg_inf,
|
reg_inf,
|
||||||
));
|
));
|
||||||
insns.push(Instruction::InvokeVirtual {
|
if ref_data.is_static {
|
||||||
method: ref_data.method.clone(),
|
insns.push(Instruction::InvokeStatic {
|
||||||
args: (reg_inf.first_arg..reg_inf.first_arg + 1 + nb_args as u16).collect(),
|
method: ref_data.method.clone(),
|
||||||
});
|
args: (reg_inf.first_arg..reg_inf.first_arg + nb_args as u16).collect(),
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
insns.push(Instruction::InvokeVirtual {
|
||||||
|
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 {
|
if let Some(move_result) = move_result {
|
||||||
let ret_ty = ref_data.method.proto.get_return_type();
|
let ret_ty = ref_data.method.proto.get_return_type();
|
||||||
let res_reg = if let Instruction::MoveResultObject { to } = &move_result {
|
let res_reg = if let Instruction::MoveResultObject { to } = &move_result {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue