WIP
This commit is contained in:
parent
bda74f55ac
commit
559ae665cf
5 changed files with 92 additions and 12 deletions
|
|
@ -2,7 +2,7 @@
|
|||
use pyo3::prelude::*;
|
||||
|
||||
use crate::{Class, Result};
|
||||
use androscalpel_serializer::DexFileReader;
|
||||
use androscalpel_serializer::{ClassDefItem, DexFileReader};
|
||||
|
||||
/// Represent an apk.
|
||||
#[pyclass]
|
||||
|
|
@ -16,8 +16,16 @@ impl Apk {
|
|||
/// Add the content of a dex file to the apk.
|
||||
pub fn add_dex_file(&mut self, data: &[u8]) -> Result<()> {
|
||||
let dex = DexFileReader::new(data)?;
|
||||
for class in dex.get_class_defs() {
|
||||
self.add_class_from_dex_file(class, &dex)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Add a class from a dex file reader.
|
||||
fn add_class_from_dex_file(&mut self, class: &ClassDefItem, dex: &DexFileReader) -> Result<()> {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
|
|
|
|||
|
|
@ -2,28 +2,47 @@
|
|||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use crate::DexString;
|
||||
|
||||
/// Represent an apk
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Class {
|
||||
#[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]
|
||||
impl Class {
|
||||
#[new]
|
||||
pub fn new() -> Self {
|
||||
pub fn new(name: DexString, ty: DexString) -> 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()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
pub fn __repr__(&self) -> DexString {
|
||||
self.name.clone()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -52,21 +52,38 @@ impl std::error::Error for Error {}
|
|||
impl From<Error> for PyErr {
|
||||
fn from(error: Error) -> Self {
|
||||
match error {
|
||||
Error::InputTooSmall(err) => PyValueError::new_err(format!("{err}")),
|
||||
Error::SerializationError(err) => PyValueError::new_err(format!("{err}")),
|
||||
Error::DeserializationError(err) => PyValueError::new_err(format!("{err}")),
|
||||
Error::InvalidStringEncoding(err) => PyValueError::new_err(format!("{err}")),
|
||||
Error::InconsistantStruct(err) => PyValueError::new_err(format!("{err}")),
|
||||
Error::InputTooSmall(err) => PyValueError::new_err(err.to_string()),
|
||||
Error::SerializationError(err) => PyValueError::new_err(err.to_string()),
|
||||
Error::DeserializationError(err) => PyValueError::new_err(err.to_string()),
|
||||
Error::InvalidStringEncoding(err) => PyValueError::new_err(err.to_string()),
|
||||
Error::InconsistantStruct(err) => PyValueError::new_err(err.to_string()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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.
|
||||
#[pymodule]
|
||||
fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
m.add_class::<Class>()?;
|
||||
m.add_class::<Apk>()?;
|
||||
m.add_class::<DexString>()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ use crate::core::*;
|
|||
pub use androscalpel_serializer_derive::*;
|
||||
|
||||
/// <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 utf16_size: Uleb128,
|
||||
#[until(u8, u8, 0x00u8)]
|
||||
|
|
|
|||
|
|
@ -90,6 +90,42 @@ impl<'a> DexFileReader<'a> {
|
|||
pub fn get_header(&self) -> &HeaderItem {
|
||||
&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<()> {
|
||||
if self.header.magic.version != [0x30, 0x33, 0x39] {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue