This commit is contained in:
Jean-Marie Mineau 2023-08-31 14:02:04 +02:00
parent bda74f55ac
commit 559ae665cf
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
5 changed files with 92 additions and 12 deletions

View file

@ -2,7 +2,7 @@
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::{Class, Result}; use crate::{Class, Result};
use androscalpel_serializer::DexFileReader; use androscalpel_serializer::{ClassDefItem, DexFileReader};
/// Represent an apk. /// Represent an apk.
#[pyclass] #[pyclass]
@ -16,8 +16,16 @@ impl Apk {
/// Add the content of a dex file to the apk. /// Add the content of a dex file to the apk.
pub fn add_dex_file(&mut self, data: &[u8]) -> Result<()> { pub fn add_dex_file(&mut self, data: &[u8]) -> Result<()> {
let dex = DexFileReader::new(data)?; let dex = DexFileReader::new(data)?;
for class in dex.get_class_defs() {
self.add_class_from_dex_file(class, &dex)?;
}
Ok(()) Ok(())
} }
/// Add a class from a dex file reader.
fn add_class_from_dex_file(&mut self, class: &ClassDefItem, dex: &DexFileReader) -> Result<()> {
todo!()
}
} }
#[pymethods] #[pymethods]

View file

@ -2,28 +2,47 @@
use pyo3::prelude::*; use pyo3::prelude::*;
use crate::DexString;
/// Represent an apk /// Represent an apk
#[pyclass] #[pyclass]
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Class { pub struct Class {
#[pyo3(get, set)] #[pyo3(get, set)]
pub name: String, pub name: DexString,
#[pyo3(get, set)]
pub ty: DexString,
// pub access_flags: // TODO
#[pyo3(get, set)]
pub superclass: Option<DexString>,
#[pyo3(get, set)]
pub interfaces: Vec<DexString>,
#[pyo3(get, set)]
pub source_file: Option<DexString>,
// pub annotations: Option<()> // TODO
// pub data: Option<()> // TODO
// pub static_values: Option<()> // TODO
// TODO: mix annotation data and static values to make it more practical
} }
#[pymethods] #[pymethods]
impl Class { impl Class {
#[new] #[new]
pub fn new() -> Self { pub fn new(name: DexString, ty: DexString) -> Self {
Self { Self {
name: "plop".into(), name,
ty,
superclass: None,
interfaces: vec![],
source_file: None,
} }
} }
pub fn __str__(&self) -> String { pub fn __str__(&self) -> DexString {
self.name.clone() self.name.clone()
} }
pub fn __repr__(&self) -> String { pub fn __repr__(&self) -> DexString {
self.name.clone() self.name.clone()
} }
} }

View file

@ -52,21 +52,38 @@ impl std::error::Error for Error {}
impl From<Error> for PyErr { impl From<Error> for PyErr {
fn from(error: Error) -> Self { fn from(error: Error) -> Self {
match error { match error {
Error::InputTooSmall(err) => PyValueError::new_err(format!("{err}")), Error::InputTooSmall(err) => PyValueError::new_err(err.to_string()),
Error::SerializationError(err) => PyValueError::new_err(format!("{err}")), Error::SerializationError(err) => PyValueError::new_err(err.to_string()),
Error::DeserializationError(err) => PyValueError::new_err(format!("{err}")), Error::DeserializationError(err) => PyValueError::new_err(err.to_string()),
Error::InvalidStringEncoding(err) => PyValueError::new_err(format!("{err}")), Error::InvalidStringEncoding(err) => PyValueError::new_err(err.to_string()),
Error::InconsistantStruct(err) => PyValueError::new_err(format!("{err}")), Error::InconsistantStruct(err) => PyValueError::new_err(err.to_string()),
} }
} }
} }
pub type Result<T> = core::result::Result<T, Error>; pub type Result<T> = core::result::Result<T, Error>;
#[pyclass]
#[derive(Clone, PartialEq, Eq, Debug)]
pub struct DexString(androscalpel_serializer::StringDataItem);
impl From<DexString> for androscalpel_serializer::StringDataItem {
fn from(DexString(string): DexString) -> Self {
string
}
}
impl From<androscalpel_serializer::StringDataItem> for DexString {
fn from(string: androscalpel_serializer::StringDataItem) -> Self {
Self(string)
}
}
/// Androscalpel. /// Androscalpel.
#[pymodule] #[pymodule]
fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> { fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
m.add_class::<Class>()?; m.add_class::<Class>()?;
m.add_class::<Apk>()?; m.add_class::<Apk>()?;
m.add_class::<DexString>()?;
Ok(()) Ok(())
} }

View file

@ -17,7 +17,7 @@ use crate::core::*;
pub use androscalpel_serializer_derive::*; pub use androscalpel_serializer_derive::*;
/// <https://source.android.com/docs/core/runtime/dex-format#string-data-item> /// <https://source.android.com/docs/core/runtime/dex-format#string-data-item>
#[derive(Serializable, PartialEq, Eq, Debug)] #[derive(Serializable, Clone, PartialEq, Eq, Debug)]
pub struct StringDataItem { pub struct StringDataItem {
pub utf16_size: Uleb128, pub utf16_size: Uleb128,
#[until(u8, u8, 0x00u8)] #[until(u8, u8, 0x00u8)]

View file

@ -90,6 +90,42 @@ impl<'a> DexFileReader<'a> {
pub fn get_header(&self) -> &HeaderItem { pub fn get_header(&self) -> &HeaderItem {
&self.header &self.header
} }
/// Retunr the file [`StringIdItem`] list.
pub fn get_string_ids(&self) -> &[StringIdItem] {
&self.string_ids
}
/// Retunr the file [`TypeIdItem`] list.
pub fn get_type_ids(&self) -> &[TypeIdItem] {
&self.type_ids
}
/// Retunr the file [`ProtoIdItem`] list.
pub fn get_proto_ids(&self) -> &[ProtoIdItem] {
&self.proto_ids
}
/// Retunr the file [`FieldIdItem`] list.
pub fn get_field_ids(&self) -> &[FieldIdItem] {
&self.field_ids
}
/// Retunr the file [`MethodIdItem`] list.
pub fn get_method_ids(&self) -> &[MethodIdItem] {
&self.method_ids
}
/// Retunr the file [`ClassDefItem`] list.
pub fn get_class_defs(&self) -> &[ClassDefItem] {
&self.class_defs
}
/// Retunr the file [`CallSiteIdItem`] list.
pub fn get_call_site_ids(&self) -> &[CallSiteIdItem] {
&self.call_site_ids
}
/// Retunr the file [`MethodHandleItem`] list.
pub fn get_method_handles(&self) -> &[MethodHandleItem] {
&self.method_handles
}
/// Retunr the file [`MapList`].
pub fn get_map_list(&self) -> &MapList {
&self.map_list
}
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] {