Merge branch 'main' of git.mineau.eu:histausse/androscalpel
This commit is contained in:
commit
4c4940e6b1
5 changed files with 58 additions and 30 deletions
|
|
@ -2769,8 +2769,6 @@ impl Apk {
|
|||
}
|
||||
Ok(Code {
|
||||
registers_size: code_item.registers_size,
|
||||
ins_size: code_item.ins_size,
|
||||
outs_size: code_item.outs_size,
|
||||
parameter_names,
|
||||
insns,
|
||||
})
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ use std::collections::{HashMap, HashSet};
|
|||
use pyo3::prelude::*;
|
||||
|
||||
use crate::{
|
||||
ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle, Result,
|
||||
Visitable, VisitableMut, Visitor, VisitorMut,
|
||||
ins::Instruction, DexString, IdField, IdMethod, IdMethodType, IdType, Method, MethodHandle,
|
||||
Result, Visitable, VisitableMut, Visitor, VisitorMut,
|
||||
};
|
||||
|
||||
// TODO: make this easy to edit/manipulate, maybe move to Method
|
||||
|
|
@ -25,14 +25,6 @@ pub struct Code {
|
|||
/// The number of registers used by the code
|
||||
#[cfg_attr(feature = "python", pyo3(get))]
|
||||
pub registers_size: u16,
|
||||
// TODO: what does it means? is it computable?
|
||||
/// The number of words of incoming arguments to the method
|
||||
#[cfg_attr(feature = "python", pyo3(get))]
|
||||
pub ins_size: u16,
|
||||
// TODO: what does it means? is it computable?
|
||||
/// The number of words of outgoing argument space
|
||||
#[cfg_attr(feature = "python", pyo3(get))]
|
||||
pub outs_size: u16,
|
||||
/// The names of the parameters if given
|
||||
#[cfg_attr(feature = "python", pyo3(get))]
|
||||
pub parameter_names: Option<Vec<Option<DexString>>>,
|
||||
|
|
@ -47,8 +39,6 @@ impl PartialEq for Code {
|
|||
let comparable_self = self.semantic_comparable().unwrap();
|
||||
let comparable_other = other.semantic_comparable().unwrap();
|
||||
(comparable_self.registers_size == comparable_other.registers_size)
|
||||
&& (comparable_self.ins_size == comparable_other.ins_size)
|
||||
&& (comparable_self.outs_size == comparable_other.outs_size)
|
||||
&& (comparable_self.insns == comparable_other.insns)
|
||||
}
|
||||
}
|
||||
|
|
@ -68,20 +58,46 @@ impl Code {
|
|||
#[cfg_attr(feature = "python", pyo3(signature = (registers_size, ins_size, outs_size, insns, parameter_names=None)))]
|
||||
pub fn new(
|
||||
registers_size: u16,
|
||||
ins_size: u16,
|
||||
outs_size: u16,
|
||||
insns: Vec<Instruction>,
|
||||
parameter_names: Option<Vec<Option<DexString>>>,
|
||||
) -> Self {
|
||||
Self {
|
||||
registers_size,
|
||||
ins_size,
|
||||
outs_size,
|
||||
insns,
|
||||
parameter_names,
|
||||
}
|
||||
}
|
||||
|
||||
/// Compute the `ins_size` field. This is the number of register parameters, including the
|
||||
/// `this` parameter for non-static methods.
|
||||
/// This information is stored in the code item in dex files, but is not computable from the code
|
||||
/// (as opposed to `outs_size`). The [`Method`] struct is needed to compute it.
|
||||
pub fn ins_size(&self, method: &Method) -> u16 {
|
||||
method.ins_size()
|
||||
}
|
||||
/// Compute the `outs_size` field. This is the number of registers needed to call other
|
||||
/// function.
|
||||
pub fn outs_size(&self) -> u16 {
|
||||
let mut outs = 0;
|
||||
for ins in &self.insns {
|
||||
match ins {
|
||||
Instruction::InvokeVirtual { args, .. }
|
||||
| Instruction::InvokeSuper { args, .. }
|
||||
| Instruction::InvokeDirect { args, .. }
|
||||
| Instruction::InvokeStatic { args, .. }
|
||||
| Instruction::InvokeInterface { args, .. }
|
||||
| Instruction::InvokePolymorphic { args, .. }
|
||||
| Instruction::InvokeCustom { args, .. } => {
|
||||
if args.len() > outs {
|
||||
outs = args.len();
|
||||
}
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
outs as u16
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ impl MethodCFG<'_> {
|
|||
return HashMap::new();
|
||||
}
|
||||
// Initialize the entry block from function signature:
|
||||
let mut i = (code.registers_size - code.ins_size) as usize;
|
||||
let mut i = (code.registers_size - code.ins_size(&self.method)) as usize;
|
||||
if !self.method.is_static {
|
||||
end_block_reg_tys[0][i] = RegType::Object; // 'this'
|
||||
i += 1;
|
||||
|
|
|
|||
|
|
@ -406,7 +406,7 @@ impl DexWriter {
|
|||
///
|
||||
/// This is currently a stub that probably serialize invalid references to data.
|
||||
fn insert_code_item(&mut self, method_id: IdMethod, direct_methods: bool) -> Result<()> {
|
||||
let code = if direct_methods {
|
||||
let method = if direct_methods {
|
||||
self.class_defs
|
||||
.get(&method_id.class_)
|
||||
.unwrap()
|
||||
|
|
@ -414,10 +414,6 @@ impl DexWriter {
|
|||
.direct_methods
|
||||
.get(&method_id)
|
||||
.unwrap()
|
||||
.code
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
} else {
|
||||
self.class_defs
|
||||
.get(&method_id.class_)
|
||||
|
|
@ -426,11 +422,10 @@ impl DexWriter {
|
|||
.virtual_methods
|
||||
.get(&method_id)
|
||||
.unwrap()
|
||||
.code
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.clone()
|
||||
};
|
||||
let code = method.code.as_ref().unwrap().clone();
|
||||
let ins_size = code.ins_size(&method);
|
||||
let outs_size = code.outs_size();
|
||||
// Estimate instructions addresses
|
||||
let mut min_addr = 0;
|
||||
let mut max_addr = 0;
|
||||
|
|
@ -864,9 +859,9 @@ impl DexWriter {
|
|||
};
|
||||
let item = CodeItem {
|
||||
registers_size: code.registers_size,
|
||||
ins_size: code.ins_size,
|
||||
outs_size: code.outs_size,
|
||||
debug_info_off, // linked in link_debug_info()
|
||||
ins_size,
|
||||
outs_size,
|
||||
insns,
|
||||
tries,
|
||||
handlers,
|
||||
|
|
|
|||
|
|
@ -294,6 +294,25 @@ impl Method {
|
|||
.iter()
|
||||
.any(|list| !list.is_empty())
|
||||
}
|
||||
|
||||
/// Compute the `ins_size` field. This is the number of register parameters, including the
|
||||
/// `this` parameter for non-static methods.
|
||||
/// This information is stored in the code item in dex files, but is not computable from the code
|
||||
/// (as opposed to `outs_size`). The [`Method`] struct is needed to compute it.
|
||||
pub fn ins_size(&self) -> u16 {
|
||||
let mut ins = 0;
|
||||
if !self.is_static {
|
||||
ins += 1; // this
|
||||
}
|
||||
for param in &self.descriptor.proto.parameters {
|
||||
if param.is_long() || param.is_double() {
|
||||
ins += 2;
|
||||
} else {
|
||||
ins += 1;
|
||||
}
|
||||
}
|
||||
ins
|
||||
}
|
||||
}
|
||||
|
||||
impl<V: Visitor> Visitable<V> for Method {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue