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,
}))
}
// 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,

View file

@ -9,13 +9,9 @@ use crate::DexString;
#[pyclass]
#[derive(Debug, Clone)]
pub struct Field {
/// The name of the field, format described at
/// <https://source.android.com/docs/core/runtime/dex-format#membername>
/// 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
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
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
/// <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]
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<PyObject> 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),