convert instruction to an editable format WIP

This commit is contained in:
Jean-Marie Mineau 2023-12-16 02:09:52 +01:00
parent 2d164362a7
commit 29c43a68b2
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
5 changed files with 2631 additions and 45 deletions

File diff suppressed because it is too large Load diff

View file

@ -4,11 +4,11 @@ use std::collections::HashSet;
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::{DexString, IdField, IdMethod, IdMethodType, IdType, MethodHandle}; use crate::{DexString, IdField, IdMethod, IdMethodType, IdType, Instruction, MethodHandle};
// TODO: make this easy to edit/manipulate, maybe move to Method // TODO: make this easy to edit/manipulate, maybe move to Method
type TmpHandlerType = (Vec<(IdType, u32)>, Option<u32>); // type TmpHandlerType = (Vec<(IdType, u32)>, Option<u32>);
/// The code run by a method. /// The code run by a method.
#[pyclass] #[pyclass]
@ -33,12 +33,12 @@ pub struct Code {
// TODO: implement OPcode // TODO: implement OPcode
/// The instructions. /// The instructions.
#[pyo3(get, set)] #[pyo3(get, set)]
pub insns: Vec<u16>, pub insns: Vec<Instruction>,
// TODO: currently unusable, juste a mapping ty TryItem // TODO: currently unusable, juste a mapping ty TryItem
// TODO: maybe implement as custom OPcode to make me easy to modify? // TODO: maybe implement as custom OPcode to make me easy to modify?
/// Try blocks // /// Try blocks
#[pyo3(get, set)] // #[pyo3(get, set)]
pub tries: Vec<(u32, u16, TmpHandlerType)>, // pub tries: Vec<(u32, u16, TmpHandlerType)>,
// TODO: currently unusable, juste a mapping ty TryItem // TODO: currently unusable, juste a mapping ty TryItem
// TODO: maybe implement as custom OPcode to make me easy to modify? // TODO: maybe implement as custom OPcode to make me easy to modify?
} }
@ -62,6 +62,8 @@ impl Code {
/// Return all strings referenced in the codes. /// Return all strings referenced in the codes.
pub fn get_all_strings(&self) -> HashSet<DexString> { pub fn get_all_strings(&self) -> HashSet<DexString> {
todo!()
/*
let mut strings = HashSet::new(); let mut strings = HashSet::new();
for (_, _, (list, _)) in &self.tries { for (_, _, (list, _)) in &self.tries {
for (ty, _) in list { for (ty, _) in list {
@ -69,10 +71,13 @@ impl Code {
} }
} }
strings strings
*/
} }
/// Return all types referenced in the codes. /// Return all types referenced in the codes.
pub fn get_all_types(&self) -> HashSet<IdType> { pub fn get_all_types(&self) -> HashSet<IdType> {
todo!()
/*
let mut types = HashSet::new(); let mut types = HashSet::new();
for (_, _, (list, _)) in &self.tries { for (_, _, (list, _)) in &self.tries {
for (ty, _) in list { for (ty, _) in list {
@ -80,6 +85,7 @@ impl Code {
} }
} }
types types
*/
} }
/// Return all prototypes referenced in the codes. /// Return all prototypes referenced in the codes.

File diff suppressed because it is too large Load diff

View file

@ -24,7 +24,7 @@ pub use dex_id::*;
pub use dex_string::*; pub use dex_string::*;
pub use dex_writer::*; pub use dex_writer::*;
pub use field::*; pub use field::*;
//pub use instructions::*; pub use instructions::{CallSite, Instruction};
pub use method::*; pub use method::*;
pub use method_handle::*; pub use method_handle::*;
pub use scalar::*; pub use scalar::*;

View file

@ -194,6 +194,16 @@ impl<'a> DexFileReader<'a> {
))) )))
} }
/// Return a [`CallSiteIdItem`] reference from its idx.
pub fn get_call_site_id(&self, idx: usize) -> Result<&CallSiteIdItem> {
self.call_site_ids
.get(idx)
.ok_or(Error::InconsistantStruct(format!(
"call site {idx} is out of bound (|call_site_ids|={})",
self.call_site_ids.len()
)))
}
fn sanity_check(&self) -> Result<()> { fn sanity_check(&self) -> Result<()> {
if self.header.magic.version != [0x30, 0x33, 0x39] { if self.header.magic.version != [0x30, 0x33, 0x39] {
warn!( warn!(