From d69036d3b51124b3e486c5be2f50e990bd359059 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Tue, 3 Oct 2023 16:44:45 +0200 Subject: [PATCH] add array support to dex values --- TODO.md | 4 ++++ androscalpel/src/apk.rs | 7 ++++++- androscalpel/src/method_handle.rs | 17 +++++++++++++++++ androscalpel/src/scalar.rs | 24 ++++++++++++++++-------- androscalpel/src/value.rs | 26 ++++++++++++++++++++++++++ 5 files changed, 69 insertions(+), 9 deletions(-) diff --git a/TODO.md b/TODO.md index de5e1ab..2968a7f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,8 @@ +- enum +- method +- code - edditable format - sanity checks - tests +- DexValues will become a problem ? (eg need to clone the vector for the array) - https://source.android.com/docs/core/runtime/dex-format#system-annotation diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index a5635a0..44fee62 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -269,7 +269,12 @@ impl Apk { dex, )?)), EncodedValue::Enum(val) => Ok(DexValue::Enum(IdEnum(*val))), - EncodedValue::Array(_val) => todo!(), //Ok(DexValue::Array(DexArray(*val))), + EncodedValue::Array(arr) => Ok(DexValue::Array(DexArray( + arr.values + .iter() + .map(|val| Self::encoded_value_to_dex_value(val, dex)) + .collect::>()?, + ))), EncodedValue::Annotation(_val) => todo!(), //Ok(DexValue::Annotation(DexAnnotation(*val))), EncodedValue::Null => Ok(DexValue::Null(DexNull)), EncodedValue::Boolean(val) => Ok(DexValue::Boolean(DexBoolean(*val))), diff --git a/androscalpel/src/method_handle.rs b/androscalpel/src/method_handle.rs index e1aaa9f..cfc3a2c 100644 --- a/androscalpel/src/method_handle.rs +++ b/androscalpel/src/method_handle.rs @@ -276,3 +276,20 @@ impl IntoPy for MethodHandle { } } } + +impl MethodHandle { + // Not exposed to python, but meh, let's keep it coherent + pub fn __str__(&self) -> String { + match self { + Self::StaticPut(val) => val.__str__(), + Self::StaticGet(val) => val.__str__(), + Self::InstancePut(val) => val.__str__(), + Self::InstanceGet(val) => val.__str__(), + Self::InvokeStatic(val) => val.__str__(), + Self::InvokeInstance(val) => val.__str__(), + Self::InvokeConstructor(val) => val.__str__(), + Self::InvokeDirect(val) => val.__str__(), + Self::InvokeInterface(val) => val.__str__(), + } + } +} diff --git a/androscalpel/src/scalar.rs b/androscalpel/src/scalar.rs index 35a7837..ac602a2 100644 --- a/androscalpel/src/scalar.rs +++ b/androscalpel/src/scalar.rs @@ -1,5 +1,6 @@ //! The class identifying dex structure. +use crate::DexValue; use pyo3::prelude::*; // TODO: move DexString here @@ -233,24 +234,31 @@ impl DexBoolean { } #[pyclass] -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub struct DexArray; +#[derive(Debug, Clone)] +pub struct DexArray(pub Vec); #[pymethods] impl DexArray { #[new] - pub fn _new() -> Self { - Self + pub fn _new(arr: Vec) -> Self { + Self(arr) } - pub fn get_value(&self) { - todo!() + pub fn get_value(&self) -> Vec { + self.0.clone() // TODO: this will becom a problem... } pub fn __str__(&self) -> String { - self.__repr__() + format!( + "[{}]", + self.0 + .iter() + .map(|val| val.__str__()) + .collect::>() + .join(", ") + ) } pub fn __repr__(&self) -> String { - "DexArray".into() + "DexArray()".into() } } diff --git a/androscalpel/src/value.rs b/androscalpel/src/value.rs index a29ea04..f905d0b 100644 --- a/androscalpel/src/value.rs +++ b/androscalpel/src/value.rs @@ -74,6 +74,32 @@ impl<'source> FromPyObject<'source> for DexValue { } } +impl DexValue { + // Not exposed to python, but meh, let's keep it coherent + pub fn __str__(&self) -> String { + match self { + DexValue::Byte(val) => val.__str__(), + DexValue::Short(val) => val.__str__(), + DexValue::Char(val) => val.__str__(), + DexValue::Int(val) => val.__str__(), + DexValue::Long(val) => val.__str__(), + DexValue::Float(val) => val.__str__(), + DexValue::Double(val) => val.__str__(), + DexValue::MethodType(val) => val.__str__(), + DexValue::MethodHandle(val) => val.__str__(), + DexValue::String(val) => val.__str__(), + DexValue::Type(val) => val.__str__(), + DexValue::Field(val) => val.__str__(), + DexValue::Method(val) => val.__str__(), + DexValue::Enum(val) => val.__str__(), + DexValue::Array(val) => val.__str__(), + DexValue::Annotation(val) => val.__str__(), + DexValue::Null(val) => val.__str__(), + DexValue::Boolean(val) => val.__str__(), + } + } +} + impl IntoPy for DexValue { fn into_py(self, py: Python<'_>) -> PyObject { match self {