more work on DexField and DexType

This commit is contained in:
Jean-Marie Mineau 2023-09-04 16:58:36 +02:00
parent 2ec3fe2c9d
commit 23c5181269
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 63 additions and 30 deletions

View file

@ -174,13 +174,30 @@ impl Apk {
parameters, parameters,
})) }))
} }
// TODO: need method to be implemented first
EncodedValue::MethodHandle(_val) => todo!(), //Ok(DexValue::MethodHandle(DexMethodHandle(*val))), EncodedValue::MethodHandle(_val) => todo!(), //Ok(DexValue::MethodHandle(DexMethodHandle(*val))),
EncodedValue::String(val) => Ok(DexValue::String(dex.get_string(*val)?.into())), EncodedValue::String(val) => Ok(DexValue::String(dex.get_string(*val)?.into())),
EncodedValue::Type(val) => Ok(DexValue::Type(DexType( EncodedValue::Type(val) => Ok(DexValue::Type(DexType(
dex.get_string(dex.get_type_id(*val as usize)?.descriptor_idx)? dex.get_string(dex.get_type_id(*val as usize)?.descriptor_idx)?
.into(), .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::Method(val) => Ok(DexValue::Method(DexMethod(*val))),
EncodedValue::Enum(val) => Ok(DexValue::Enum(DexEnum(*val))), EncodedValue::Enum(val) => Ok(DexValue::Enum(DexEnum(*val))),
EncodedValue::Array(_val) => todo!(), //Ok(DexValue::Array(DexArray(*val))), EncodedValue::Array(_val) => todo!(), //Ok(DexValue::Array(DexArray(*val))),
@ -200,10 +217,8 @@ impl Apk {
idx += field.field_idx_diff.0; idx += field.field_idx_diff.0;
let id_item = dex.get_field_id(idx as usize)?; 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_ty = dex.get_type_id(id_item.class_idx as usize)?;
let class: DexString = dex.get_string(class_ty.descriptor_idx)?.into(); 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_type_id(id_item.type_idx as usize)?;
let ty = dex.get_string(ty.descriptor_idx)?.into(); let ty = dex.get_string(ty.descriptor_idx)?.into();
let name: DexString = dex.get_string(id_item.name_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, true) => FieldVisibility::Protected,
(false, false, false) => FieldVisibility::None_, (false, false, false) => FieldVisibility::None_,
(pbl, prv, prt) => { (pbl, prv, prt) => {
let class: String = class.into();
let name: String = name.into(); let name: String = name.into();
return Err(Error::InconsistantStruct(format!( return Err(Error::InconsistantStruct(format!(
"Inconsistant visiblity found in {class}.{name}: \ "Inconsistant visiblity found in {class}.{name}: \
@ -230,9 +246,13 @@ impl Apk {
))); )));
} }
}; };
fields.push(Field { let descriptor = DexField {
name, name,
type_: ty, type_: DexType(ty),
class_: DexType(class),
};
fields.push(Field {
descriptor,
visibility, visibility,
is_static, is_static,
is_final, is_final,

View file

@ -9,13 +9,9 @@ use crate::DexString;
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Field { pub struct Field {
/// The name of the field, format described at /// The structure used to reference this field.
/// <https://source.android.com/docs/core/runtime/dex-format#membername>
#[pyo3(get, set)] #[pyo3(get, set)]
pub name: DexString, pub descriptor: DexField,
/// The type of the field, format described at <>
#[pyo3(get, set)]
pub type_: DexString,
/// The field visibility /// The field visibility
#[pyo3(get, set)] #[pyo3(get, set)]
pub visibility: FieldVisibility, pub visibility: FieldVisibility,
@ -54,10 +50,9 @@ pub enum FieldVisibility {
#[pymethods] #[pymethods]
impl Field { impl Field {
#[new] #[new]
pub fn new(name: DexString, type_: DexString) -> Self { pub fn new(descriptor: DexField) -> Self {
Self { Self {
name, descriptor,
type_,
visibility: FieldVisibility::Public, visibility: FieldVisibility::Public,
is_static: false, is_static: false,
is_final: false, is_final: false,
@ -101,8 +96,8 @@ impl Field {
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
let name: String = (&self.name).into(); let name: String = (&self.descriptor.name).into();
let ty: String = (&self.type_).into(); let ty: String = (&self.descriptor.type_.0).into();
format!("Field({name}, {ty})") format!("Field({name}, {ty})")
} }
@ -316,6 +311,8 @@ impl DexMethodType {
} }
impl DexMethodType { impl DexMethodType {
/// Compute the format for the shorty as described in
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
pub fn get_shorty(return_type: &DexType, parameters: &[DexType]) -> DexString { pub fn get_shorty(return_type: &DexType, parameters: &[DexType]) -> DexString {
todo!() todo!()
} }
@ -386,39 +383,55 @@ impl DexType {
} }
pub fn get_name(&self) -> DexString { pub fn get_name(&self) -> DexString {
self.0 self.0.clone()
} }
pub fn __str__(&self) -> String { pub fn __str__(&self) -> String {
self.0.into() (&self.0).into()
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> String {
let name: String = self.0.into(); let name: String = (&self.0).into();
format!("DexType({name})") format!("DexType({name})")
} }
} }
#[pyclass] #[pyclass]
#[derive(Debug, Clone, Copy, PartialEq, Eq)] #[derive(Debug, Clone, PartialEq, Eq)]
pub struct DexField(pub u32); pub struct DexField {
/// The name of the field, format described at
/// <https://source.android.com/docs/core/runtime/dex-format#membername>
#[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] #[pymethods]
impl DexField { impl DexField {
#[new] #[new]
pub fn new(val: u32) -> Self { pub fn new(name: DexString, type_: DexType, class_: DexType) -> Self {
Self(val) Self {
name,
type_,
class_,
} }
pub fn get_value(&self) -> u32 {
self.0
} }
pub fn __str__(&self) -> String { 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 { 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<PyObject> for DexValue {
DexValue::Long(val) => val.into_py(py), DexValue::Long(val) => val.into_py(py),
DexValue::Float(val) => val.into_py(py), DexValue::Float(val) => val.into_py(py),
DexValue::Double(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::MethodHandle(val) => val.into_py(py),
DexValue::String(val) => val.into_py(py), DexValue::String(val) => val.into_py(py),
DexValue::Type(val) => val.into_py(py), DexValue::Type(val) => val.into_py(py),