From 23c51812696f626317f09c93bca40c72f1e3bb95 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Mon, 4 Sep 2023 16:58:36 +0200 Subject: [PATCH] more work on DexField and DexType --- androscalpel/src/apk.rs | 30 +++++++++++++++---- androscalpel/src/field.rs | 63 +++++++++++++++++++++++---------------- 2 files changed, 63 insertions(+), 30 deletions(-) diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index 7b96a25..24fea4a 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -174,13 +174,30 @@ impl Apk { parameters, })) } + // TODO: need method to be implemented first EncodedValue::MethodHandle(_val) => todo!(), //Ok(DexValue::MethodHandle(DexMethodHandle(*val))), EncodedValue::String(val) => Ok(DexValue::String(dex.get_string(*val)?.into())), EncodedValue::Type(val) => Ok(DexValue::Type(DexType( dex.get_string(dex.get_type_id(*val as usize)?.descriptor_idx)? .into(), ))), - EncodedValue::Field(val) => Ok(DexValue::Field(DexField(*val))), + EncodedValue::Field(val) => { + let field = dex.get_field_id(*val as usize)?; + let name = dex.get_string(field.name_idx)?.into(); + let type_ = DexType( + dex.get_string(dex.get_type_id(field.type_idx as usize)?.descriptor_idx)? + .into(), + ); + let class_ = DexType( + dex.get_string(dex.get_type_id(field.class_idx as usize)?.descriptor_idx)? + .into(), + ); + Ok(DexValue::Field(DexField { + name, + type_, + class_, + })) + } EncodedValue::Method(val) => Ok(DexValue::Method(DexMethod(*val))), EncodedValue::Enum(val) => Ok(DexValue::Enum(DexEnum(*val))), EncodedValue::Array(_val) => todo!(), //Ok(DexValue::Array(DexArray(*val))), @@ -200,10 +217,8 @@ impl Apk { idx += field.field_idx_diff.0; let id_item = dex.get_field_id(idx as usize)?; - // Check class_idx == class? ¯\_(ツ)/¯ at least it usefull for debug let class_ty = dex.get_type_id(id_item.class_idx as usize)?; let class: DexString = dex.get_string(class_ty.descriptor_idx)?.into(); - let class: String = class.into(); let ty = dex.get_type_id(id_item.type_idx as usize)?; let ty = dex.get_string(ty.descriptor_idx)?.into(); let name: DexString = dex.get_string(id_item.name_idx)?.into(); @@ -223,6 +238,7 @@ impl Apk { (false, false, true) => FieldVisibility::Protected, (false, false, false) => FieldVisibility::None_, (pbl, prv, prt) => { + let class: String = class.into(); let name: String = name.into(); return Err(Error::InconsistantStruct(format!( "Inconsistant visiblity found in {class}.{name}: \ @@ -230,9 +246,13 @@ impl Apk { ))); } }; - fields.push(Field { + let descriptor = DexField { name, - type_: ty, + type_: DexType(ty), + class_: DexType(class), + }; + fields.push(Field { + descriptor, visibility, is_static, is_final, diff --git a/androscalpel/src/field.rs b/androscalpel/src/field.rs index 251757d..b2750ff 100644 --- a/androscalpel/src/field.rs +++ b/androscalpel/src/field.rs @@ -9,13 +9,9 @@ use crate::DexString; #[pyclass] #[derive(Debug, Clone)] pub struct Field { - /// The name of the field, format described at - /// + /// The structure used to reference this field. #[pyo3(get, set)] - pub name: DexString, - /// The type of the field, format described at <> - #[pyo3(get, set)] - pub type_: DexString, + pub descriptor: DexField, /// The field visibility #[pyo3(get, set)] pub visibility: FieldVisibility, @@ -54,10 +50,9 @@ pub enum FieldVisibility { #[pymethods] impl Field { #[new] - pub fn new(name: DexString, type_: DexString) -> Self { + pub fn new(descriptor: DexField) -> Self { Self { - name, - type_, + descriptor, visibility: FieldVisibility::Public, is_static: false, is_final: false, @@ -101,8 +96,8 @@ impl Field { } pub fn __repr__(&self) -> String { - let name: String = (&self.name).into(); - let ty: String = (&self.type_).into(); + let name: String = (&self.descriptor.name).into(); + let ty: String = (&self.descriptor.type_.0).into(); format!("Field({name}, {ty})") } @@ -316,6 +311,8 @@ impl DexMethodType { } impl DexMethodType { + /// Compute the format for the shorty as described in + /// pub fn get_shorty(return_type: &DexType, parameters: &[DexType]) -> DexString { todo!() } @@ -386,39 +383,55 @@ impl DexType { } pub fn get_name(&self) -> DexString { - self.0 + self.0.clone() } pub fn __str__(&self) -> String { - self.0.into() + (&self.0).into() } pub fn __repr__(&self) -> String { - let name: String = self.0.into(); + let name: String = (&self.0).into(); format!("DexType({name})") } } #[pyclass] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct DexField(pub u32); +#[derive(Debug, Clone, PartialEq, Eq)] +pub struct DexField { + /// The name of the field, format described at + /// + #[pyo3(get, set)] + pub name: DexString, + /// The type of the field. + #[pyo3(get, set)] + pub type_: DexType, + /// The class that own the field. + #[pyo3(get, set)] + pub class_: DexType, +} + #[pymethods] impl DexField { #[new] - pub fn new(val: u32) -> Self { - Self(val) - } - - pub fn get_value(&self) -> u32 { - self.0 + pub fn new(name: DexString, type_: DexType, class_: DexType) -> Self { + Self { + name, + type_, + class_, + } } pub fn __str__(&self) -> String { - self.__repr__() + let class: String = self.class_.get_name().into(); + let name: String = (&self.name).into(); + format!("{class}.{name}") } pub fn __repr__(&self) -> String { - format!("DexField({})", self.0) + let class: String = self.class_.get_name().into(); + let name: String = (&self.name).into(); + format!("DexField({class}.{name})") } } @@ -634,7 +647,7 @@ impl IntoPy for DexValue { DexValue::Long(val) => val.into_py(py), DexValue::Float(val) => val.into_py(py), DexValue::Double(val) => val.into_py(py), - //DexValue::MethodType(val) => val.into_py(py), + DexValue::MethodType(val) => val.into_py(py), //DexValue::MethodHandle(val) => val.into_py(py), DexValue::String(val) => val.into_py(py), DexValue::Type(val) => val.into_py(py),