refactor values repr
This commit is contained in:
parent
1bf328d44e
commit
b2c4da413c
5 changed files with 740 additions and 720 deletions
371
androscalpel/src/dex_id.rs
Normal file
371
androscalpel/src/dex_id.rs
Normal file
|
|
@ -0,0 +1,371 @@
|
|||
//! The class identifying dex structure.
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use crate::DexString;
|
||||
use androscalpel_serializer::{StringDataItem, Uleb128};
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct IdMethodType {
|
||||
/// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||
pub(crate) shorty: DexString,
|
||||
pub(crate) return_type: IdType,
|
||||
pub(crate) parameters: Vec<IdType>,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
/// The type of a method. The shorty is formated as described in
|
||||
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||
impl IdMethodType {
|
||||
#[new]
|
||||
pub fn new(return_type: IdType, parameters: Vec<IdType>) -> Self {
|
||||
// TODO: check format
|
||||
Self {
|
||||
shorty: Self::get_shorty(&return_type, ¶meters),
|
||||
return_type,
|
||||
parameters,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
let repr: String = (&self.shorty).into();
|
||||
format!("DexMethodType({repr})")
|
||||
}
|
||||
}
|
||||
|
||||
impl IdMethodType {
|
||||
/// 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: &IdType, parameters: &[IdType]) -> DexString {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct IdMethodHandle(pub u32);
|
||||
#[pymethods]
|
||||
impl DexMethodHandle {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexMethodHandle({})", self.0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// A type.
|
||||
/// Type represented by [`DexString`] that follow the TypeDescriptor format
|
||||
/// as described here <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct IdType(pub(crate) DexString);
|
||||
#[pymethods]
|
||||
impl IdType {
|
||||
#[new]
|
||||
pub fn _new(ty: DexString) -> Self {
|
||||
// TODO: check format
|
||||
Self(ty)
|
||||
}
|
||||
|
||||
/// Return the void type (for return type)
|
||||
#[staticmethod]
|
||||
pub fn void() -> Self {
|
||||
Self("V".into())
|
||||
}
|
||||
|
||||
/// Return the boolean type
|
||||
#[staticmethod]
|
||||
pub fn boolean() -> Self {
|
||||
Self("Z".into())
|
||||
}
|
||||
/// Return the byte type
|
||||
#[staticmethod]
|
||||
pub fn byte() -> Self {
|
||||
Self("B".into())
|
||||
}
|
||||
|
||||
/// Return the short type
|
||||
#[staticmethod]
|
||||
pub fn short() -> Self {
|
||||
Self("S".into())
|
||||
}
|
||||
|
||||
/// Return the char type
|
||||
#[staticmethod]
|
||||
pub fn char() -> Self {
|
||||
Self("C".into())
|
||||
}
|
||||
|
||||
/// Return the int type
|
||||
#[staticmethod]
|
||||
pub fn int() -> Self {
|
||||
Self("I".into())
|
||||
}
|
||||
|
||||
/// Return the long type
|
||||
#[staticmethod]
|
||||
pub fn long() -> Self {
|
||||
Self("J".into())
|
||||
}
|
||||
|
||||
/// Return the float type
|
||||
#[staticmethod]
|
||||
pub fn float() -> Self {
|
||||
Self("F".into())
|
||||
}
|
||||
|
||||
/// Return the double type
|
||||
#[staticmethod]
|
||||
pub fn double() -> Self {
|
||||
Self("D".into())
|
||||
}
|
||||
|
||||
/// Return the type for the class of fully qualified name `name`
|
||||
#[staticmethod]
|
||||
pub fn class(name: &str) -> Self {
|
||||
Self(format!("L{name}").into())
|
||||
}
|
||||
|
||||
/// Return the type for an array of the specify `type_`
|
||||
#[staticmethod]
|
||||
pub fn array(type_: &IdType) -> Self {
|
||||
let mut ty = type_.clone();
|
||||
ty.0 .0.utf16_size.0 += 1;
|
||||
ty.0 .0.data.insert(0, 0x5b);
|
||||
ty
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> DexString {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
(&self.0).into()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
let name: String = (&self.0).into();
|
||||
format!("DexType({name})")
|
||||
}
|
||||
|
||||
/// Check if the type is void (return type)
|
||||
pub fn is_void(&self) -> bool {
|
||||
self == &Self::void()
|
||||
}
|
||||
|
||||
/// Check if the type is boolean
|
||||
pub fn is_boolean(&self) -> bool {
|
||||
self == &Self::boolean()
|
||||
}
|
||||
|
||||
/// Check if the type is byte
|
||||
pub fn is_byte(&self) -> bool {
|
||||
self == &Self::byte()
|
||||
}
|
||||
|
||||
/// Check if the type is short
|
||||
pub fn is_short(&self) -> bool {
|
||||
self == &Self::short()
|
||||
}
|
||||
|
||||
/// Check if the type is char
|
||||
pub fn is_char(&self) -> bool {
|
||||
self == &Self::char()
|
||||
}
|
||||
|
||||
/// Check if the type is int
|
||||
pub fn is_int(&self) -> bool {
|
||||
self == &Self::int()
|
||||
}
|
||||
|
||||
/// Check if the type is long
|
||||
pub fn is_long(&self) -> bool {
|
||||
self == &Self::long()
|
||||
}
|
||||
|
||||
/// Check if the type is float
|
||||
pub fn is_float(&self) -> bool {
|
||||
self == &Self::float()
|
||||
}
|
||||
|
||||
/// Check if the type is double
|
||||
pub fn is_double(&self) -> bool {
|
||||
self == &Self::double()
|
||||
}
|
||||
|
||||
/// Check if the type is a class
|
||||
pub fn is_class(&self) -> bool {
|
||||
self.0.get_utf16_size() == 0
|
||||
&& self.0.get_bytes().is_empty()
|
||||
&& self.0.get_bytes()[0] != 0x76
|
||||
// Check if first char is an L
|
||||
}
|
||||
|
||||
/// Check if the type is an array
|
||||
pub fn is_array(&self) -> bool {
|
||||
self.0.get_utf16_size() == 0
|
||||
&& self.0.get_bytes().is_empty()
|
||||
&& self.0.get_bytes()[0] != 0x5b
|
||||
// Check if first char is an [
|
||||
}
|
||||
|
||||
/// If the type is a class, return the name of the class,
|
||||
/// else None.
|
||||
pub fn get_class_name(&self) -> Option<DexString> {
|
||||
if self.is_class() {
|
||||
Some(
|
||||
StringDataItem {
|
||||
utf16_size: Uleb128(self.0.get_utf16_size() - 1),
|
||||
data: self.0.get_bytes()[1..].to_vec(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// If the type is a array, return the type of the elements,
|
||||
/// else None.
|
||||
pub fn get_element_type(&self) -> Option<Self> {
|
||||
if self.is_array() {
|
||||
Some(Self(
|
||||
StringDataItem {
|
||||
utf16_size: Uleb128(self.0.get_utf16_size() - 1),
|
||||
data: self.0.get_bytes()[1..].to_vec(),
|
||||
}
|
||||
.into(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: TESTS
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct IdField {
|
||||
/// 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_: IdType,
|
||||
/// The class that own the field.
|
||||
#[pyo3(get, set)]
|
||||
pub class_: IdType,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
impl IdField {
|
||||
#[new]
|
||||
pub fn new(name: DexString, type_: IdType, class_: IdType) -> Self {
|
||||
Self {
|
||||
name,
|
||||
type_,
|
||||
class_,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
let class: String = self.class_.get_name().into();
|
||||
let name: String = (&self.name).into();
|
||||
format!("{class}.{name}")
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
let class: String = self.class_.get_name().into();
|
||||
let name: String = (&self.name).into();
|
||||
format!("IdField({class}.{name})")
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct IdMethod(pub u32);
|
||||
#[pymethods]
|
||||
impl IdMethod {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexMethod({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct IdEnum(pub u32);
|
||||
#[pymethods]
|
||||
impl IdEnum {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexEnum({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct IdAnnotation;
|
||||
#[pymethods]
|
||||
impl IdAnnotation {
|
||||
#[new]
|
||||
pub fn _new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn get_value(&self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
"DexAnnotation".into()
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,8 @@
|
|||
//! Representation of the fields of a class.
|
||||
|
||||
use pyo3::exceptions::PyTypeError;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use crate::DexString;
|
||||
use androscalpel_serializer::{StringDataItem, Uleb128};
|
||||
use crate::{DexValue, IdField};
|
||||
|
||||
/// Represent a field.
|
||||
#[pyclass]
|
||||
|
|
@ -12,7 +10,7 @@ use androscalpel_serializer::{StringDataItem, Uleb128};
|
|||
pub struct Field {
|
||||
/// The structure used to reference this field.
|
||||
#[pyo3(get, set)]
|
||||
pub descriptor: DexField,
|
||||
pub descriptor: IdField,
|
||||
/// The field visibility
|
||||
#[pyo3(get, set)]
|
||||
pub visibility: FieldVisibility,
|
||||
|
|
@ -51,7 +49,7 @@ pub enum FieldVisibility {
|
|||
#[pymethods]
|
||||
impl Field {
|
||||
#[new]
|
||||
pub fn new(descriptor: DexField) -> Self {
|
||||
pub fn new(descriptor: IdField) -> Self {
|
||||
Self {
|
||||
descriptor,
|
||||
visibility: FieldVisibility::Public,
|
||||
|
|
@ -116,713 +114,3 @@ impl Field {
|
|||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexByte(pub i8);
|
||||
#[pymethods]
|
||||
impl DexByte {
|
||||
#[new]
|
||||
pub fn new(val: i8) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i8 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexByte({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexShort(pub i16);
|
||||
#[pymethods]
|
||||
impl DexShort {
|
||||
#[new]
|
||||
pub fn new(val: i16) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i16 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexShort({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexChar(pub u16);
|
||||
#[pymethods]
|
||||
impl DexChar {
|
||||
#[new]
|
||||
pub fn new(val: u16) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u16 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexChar({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexInt(pub i32);
|
||||
#[pymethods]
|
||||
impl DexInt {
|
||||
#[new]
|
||||
pub fn new(val: i32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexInt({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexLong(pub i64);
|
||||
#[pymethods]
|
||||
impl DexLong {
|
||||
#[new]
|
||||
pub fn new(val: i64) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexLong({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DexFloat(pub f32);
|
||||
#[pymethods]
|
||||
impl DexFloat {
|
||||
#[new]
|
||||
pub fn new(val: f32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> f32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexFloat({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DexDouble(pub f64);
|
||||
#[pymethods]
|
||||
impl DexDouble {
|
||||
#[new]
|
||||
pub fn new(val: f64) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> f64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexDouble({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DexMethodType {
|
||||
/// Type formated as described by <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||
pub(crate) shorty: DexString,
|
||||
pub(crate) return_type: DexType,
|
||||
pub(crate) parameters: Vec<DexType>,
|
||||
}
|
||||
|
||||
#[pymethods]
|
||||
/// The type of a method. The shorty is formated as described in
|
||||
/// <https://source.android.com/docs/core/runtime/dex-format#shortydescriptor>
|
||||
impl DexMethodType {
|
||||
#[new]
|
||||
pub fn new(return_type: DexType, parameters: Vec<DexType>) -> Self {
|
||||
// TODO: check format
|
||||
Self {
|
||||
shorty: Self::get_shorty(&return_type, ¶meters),
|
||||
return_type,
|
||||
parameters,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
let repr: String = (&self.shorty).into();
|
||||
format!("DexMethodType({repr})")
|
||||
}
|
||||
}
|
||||
|
||||
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!()
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexMethodHandle(pub u32);
|
||||
#[pymethods]
|
||||
impl DexMethodHandle {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexMethodHandle({})", self.0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexString(pub u32);
|
||||
#[pymethods]
|
||||
impl DexString {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexString({})", self.0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/// A type.
|
||||
/// Type a represented by [`DexString`] that follow the TypeDescriptor format
|
||||
/// as described here <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct DexType(pub(crate) DexString);
|
||||
#[pymethods]
|
||||
impl DexType {
|
||||
#[new]
|
||||
pub fn _new(ty: DexString) -> Self {
|
||||
// TODO: check format
|
||||
Self(ty)
|
||||
}
|
||||
|
||||
/// Return the void type (for return type)
|
||||
#[staticmethod]
|
||||
pub fn void() -> Self {
|
||||
Self("V".into())
|
||||
}
|
||||
|
||||
/// Return the boolean type
|
||||
#[staticmethod]
|
||||
pub fn boolean() -> Self {
|
||||
Self("Z".into())
|
||||
}
|
||||
/// Return the byte type
|
||||
#[staticmethod]
|
||||
pub fn byte() -> Self {
|
||||
Self("B".into())
|
||||
}
|
||||
|
||||
/// Return the short type
|
||||
#[staticmethod]
|
||||
pub fn short() -> Self {
|
||||
Self("S".into())
|
||||
}
|
||||
|
||||
/// Return the char type
|
||||
#[staticmethod]
|
||||
pub fn char() -> Self {
|
||||
Self("C".into())
|
||||
}
|
||||
|
||||
/// Return the int type
|
||||
#[staticmethod]
|
||||
pub fn int() -> Self {
|
||||
Self("I".into())
|
||||
}
|
||||
|
||||
/// Return the long type
|
||||
#[staticmethod]
|
||||
pub fn long() -> Self {
|
||||
Self("J".into())
|
||||
}
|
||||
|
||||
/// Return the float type
|
||||
#[staticmethod]
|
||||
pub fn float() -> Self {
|
||||
Self("F".into())
|
||||
}
|
||||
|
||||
/// Return the double type
|
||||
#[staticmethod]
|
||||
pub fn double() -> Self {
|
||||
Self("D".into())
|
||||
}
|
||||
|
||||
/// Return the type for the class of fully qualified name `name`
|
||||
#[staticmethod]
|
||||
pub fn class(name: &str) -> Self {
|
||||
Self(format!("L{name}").into())
|
||||
}
|
||||
|
||||
/// Return the type for an array of the specify `type_`
|
||||
#[staticmethod]
|
||||
pub fn array(type_: &DexType) -> Self {
|
||||
let mut ty = type_.clone();
|
||||
ty.0 .0.utf16_size.0 += 1;
|
||||
ty.0 .0.data.insert(0, 0x5b);
|
||||
ty
|
||||
}
|
||||
|
||||
pub fn get_name(&self) -> DexString {
|
||||
self.0.clone()
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
(&self.0).into()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
let name: String = (&self.0).into();
|
||||
format!("DexType({name})")
|
||||
}
|
||||
|
||||
/// Check if the type is void (return type)
|
||||
pub fn is_void(&self) -> bool {
|
||||
self == &Self::void()
|
||||
}
|
||||
|
||||
/// Check if the type is boolean
|
||||
pub fn is_boolean(&self) -> bool {
|
||||
self == &Self::boolean()
|
||||
}
|
||||
|
||||
/// Check if the type is byte
|
||||
pub fn is_byte(&self) -> bool {
|
||||
self == &Self::byte()
|
||||
}
|
||||
|
||||
/// Check if the type is short
|
||||
pub fn is_short(&self) -> bool {
|
||||
self == &Self::short()
|
||||
}
|
||||
|
||||
/// Check if the type is char
|
||||
pub fn is_char(&self) -> bool {
|
||||
self == &Self::char()
|
||||
}
|
||||
|
||||
/// Check if the type is int
|
||||
pub fn is_int(&self) -> bool {
|
||||
self == &Self::int()
|
||||
}
|
||||
|
||||
/// Check if the type is long
|
||||
pub fn is_long(&self) -> bool {
|
||||
self == &Self::long()
|
||||
}
|
||||
|
||||
/// Check if the type is float
|
||||
pub fn is_float(&self) -> bool {
|
||||
self == &Self::float()
|
||||
}
|
||||
|
||||
/// Check if the type is double
|
||||
pub fn is_double(&self) -> bool {
|
||||
self == &Self::double()
|
||||
}
|
||||
|
||||
/// Check if the type is a class
|
||||
pub fn is_class(&self) -> bool {
|
||||
self.0.get_utf16_size() == 0
|
||||
&& self.0.get_bytes().is_empty()
|
||||
&& self.0.get_bytes()[0] != 0x76
|
||||
// Check if first char is an L
|
||||
}
|
||||
|
||||
/// Check if the type is an array
|
||||
pub fn is_array(&self) -> bool {
|
||||
self.0.get_utf16_size() == 0
|
||||
&& self.0.get_bytes().is_empty()
|
||||
&& self.0.get_bytes()[0] != 0x5b
|
||||
// Check if first char is an [
|
||||
}
|
||||
|
||||
/// If the type is a class, return the name of the class,
|
||||
/// else None.
|
||||
pub fn get_class_name(&self) -> Option<DexString> {
|
||||
if self.is_class() {
|
||||
Some(
|
||||
StringDataItem {
|
||||
utf16_size: Uleb128(self.0.get_utf16_size() - 1),
|
||||
data: self.0.get_bytes()[1..].to_vec(),
|
||||
}
|
||||
.into(),
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
/// If the type is a array, return the type of the elements,
|
||||
/// else None.
|
||||
pub fn get_element_type(&self) -> Option<Self> {
|
||||
if self.is_array() {
|
||||
Some(Self(
|
||||
StringDataItem {
|
||||
utf16_size: Uleb128(self.0.get_utf16_size() - 1),
|
||||
data: self.0.get_bytes()[1..].to_vec(),
|
||||
}
|
||||
.into(),
|
||||
))
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: TESTS
|
||||
// TODO: move to another mod
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[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(name: DexString, type_: DexType, class_: DexType) -> Self {
|
||||
Self {
|
||||
name,
|
||||
type_,
|
||||
class_,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
let class: String = self.class_.get_name().into();
|
||||
let name: String = (&self.name).into();
|
||||
format!("{class}.{name}")
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
let class: String = self.class_.get_name().into();
|
||||
let name: String = (&self.name).into();
|
||||
format!("DexField({class}.{name})")
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexMethod(pub u32);
|
||||
#[pymethods]
|
||||
impl DexMethod {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexMethod({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexEnum(pub u32);
|
||||
#[pymethods]
|
||||
impl DexEnum {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexEnum({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexArray;
|
||||
#[pymethods]
|
||||
impl DexArray {
|
||||
#[new]
|
||||
pub fn _new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn get_value(&self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
"DexArray".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexAnnotation;
|
||||
#[pymethods]
|
||||
impl DexAnnotation {
|
||||
#[new]
|
||||
pub fn _new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn get_value(&self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
"DexAnnotation".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexNull;
|
||||
#[pymethods]
|
||||
impl DexNull {
|
||||
#[new]
|
||||
pub fn _new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
"DexNull".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexBoolean(pub bool);
|
||||
#[pymethods]
|
||||
impl DexBoolean {
|
||||
#[new]
|
||||
pub fn new(val: bool) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> bool {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexBoolean({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DexValue {
|
||||
Byte(DexByte),
|
||||
Short(DexShort),
|
||||
Char(DexChar),
|
||||
Int(DexInt),
|
||||
Long(DexLong),
|
||||
Float(DexFloat),
|
||||
Double(DexDouble),
|
||||
MethodType(DexMethodType),
|
||||
//MethodHandle(DexMethodHandle),
|
||||
String(DexString),
|
||||
Type(DexType),
|
||||
Field(DexField),
|
||||
Method(DexMethod),
|
||||
Enum(DexEnum),
|
||||
Array(DexArray),
|
||||
Annotation(DexAnnotation),
|
||||
Null(DexNull),
|
||||
Boolean(DexBoolean),
|
||||
}
|
||||
|
||||
impl<'source> FromPyObject<'source> for DexValue {
|
||||
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||
if let Ok(val) = DexByte::extract(ob) {
|
||||
Ok(Self::Byte(val))
|
||||
} else if let Ok(val) = DexShort::extract(ob) {
|
||||
Ok(Self::Short(val))
|
||||
} else if let Ok(val) = DexChar::extract(ob) {
|
||||
Ok(Self::Char(val))
|
||||
} else if let Ok(val) = DexInt::extract(ob) {
|
||||
Ok(Self::Int(val))
|
||||
} else if let Ok(val) = DexLong::extract(ob) {
|
||||
Ok(Self::Long(val))
|
||||
} else if let Ok(val) = DexFloat::extract(ob) {
|
||||
Ok(Self::Float(val))
|
||||
} else if let Ok(val) = DexDouble::extract(ob) {
|
||||
Ok(Self::Double(val))
|
||||
} else if let Ok(val) = DexString::extract(ob) {
|
||||
Ok(Self::String(val))
|
||||
} else if let Ok(val) = DexType::extract(ob) {
|
||||
Ok(Self::Type(val))
|
||||
} else if let Ok(val) = DexField::extract(ob) {
|
||||
Ok(Self::Field(val))
|
||||
} else if let Ok(val) = DexMethod::extract(ob) {
|
||||
Ok(Self::Method(val))
|
||||
} else if let Ok(val) = DexEnum::extract(ob) {
|
||||
Ok(Self::Enum(val))
|
||||
} else if let Ok(val) = DexArray::extract(ob) {
|
||||
Ok(Self::Array(val))
|
||||
} else if let Ok(val) = DexAnnotation::extract(ob) {
|
||||
Ok(Self::Annotation(val))
|
||||
} else if let Ok(val) = DexNull::extract(ob) {
|
||||
Ok(Self::Null(val))
|
||||
} else if let Ok(val) = DexBoolean::extract(ob) {
|
||||
Ok(Self::Boolean(val))
|
||||
} else if let Ok(val) = DexMethodType::extract(ob) {
|
||||
Ok(Self::MethodType(val))
|
||||
// } else if let Ok(val) = DexMethodHandle::extract(ob) { Ok(Self::MethodHandle(val))
|
||||
} else {
|
||||
Err(PyErr::new::<PyTypeError, _>(format!(
|
||||
"{} is not a castable as a DexValue",
|
||||
ob.repr()?
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for DexValue {
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
match self {
|
||||
DexValue::Byte(val) => val.into_py(py),
|
||||
DexValue::Short(val) => val.into_py(py),
|
||||
DexValue::Char(val) => val.into_py(py),
|
||||
DexValue::Int(val) => val.into_py(py),
|
||||
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::MethodHandle(val) => val.into_py(py),
|
||||
DexValue::String(val) => val.into_py(py),
|
||||
DexValue::Type(val) => val.into_py(py),
|
||||
DexValue::Field(val) => val.into_py(py),
|
||||
DexValue::Method(val) => val.into_py(py),
|
||||
DexValue::Enum(val) => val.into_py(py),
|
||||
DexValue::Array(val) => val.into_py(py),
|
||||
DexValue::Annotation(val) => val.into_py(py),
|
||||
DexValue::Null(val) => val.into_py(py),
|
||||
DexValue::Boolean(val) => val.into_py(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,11 +4,17 @@ use pyo3::prelude::*;
|
|||
|
||||
pub mod apk;
|
||||
pub mod class;
|
||||
pub mod dex_id;
|
||||
pub mod field;
|
||||
pub mod scalar;
|
||||
pub mod value;
|
||||
|
||||
pub use apk::*;
|
||||
pub use class::*;
|
||||
pub use dex_id::*;
|
||||
pub use field::*;
|
||||
pub use scalar::*;
|
||||
pub use value::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum Error {
|
||||
|
|
@ -158,12 +164,12 @@ fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
|
|||
// m.add_class::<DexMethodType>()?;
|
||||
// m.add_class::<DexMethodHandle>()?;
|
||||
m.add_class::<DexString>()?;
|
||||
m.add_class::<DexType>()?;
|
||||
m.add_class::<DexField>()?;
|
||||
m.add_class::<DexMethod>()?;
|
||||
m.add_class::<DexEnum>()?;
|
||||
m.add_class::<IdType>()?;
|
||||
m.add_class::<IdField>()?;
|
||||
m.add_class::<IdMethod>()?;
|
||||
m.add_class::<IdEnum>()?;
|
||||
m.add_class::<DexArray>()?;
|
||||
m.add_class::<DexAnnotation>()?;
|
||||
m.add_class::<IdAnnotation>()?;
|
||||
m.add_class::<DexNull>()?;
|
||||
m.add_class::<DexBoolean>()?;
|
||||
m.add_class::<DexString>()?;
|
||||
|
|
|
|||
256
androscalpel/src/scalar.rs
Normal file
256
androscalpel/src/scalar.rs
Normal file
|
|
@ -0,0 +1,256 @@
|
|||
//! The class identifying dex structure.
|
||||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
// TODO: move DexString here
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexByte(pub i8);
|
||||
#[pymethods]
|
||||
impl DexByte {
|
||||
#[new]
|
||||
pub fn new(val: i8) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i8 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexByte({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexShort(pub i16);
|
||||
#[pymethods]
|
||||
impl DexShort {
|
||||
#[new]
|
||||
pub fn new(val: i16) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i16 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexShort({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexChar(pub u16);
|
||||
#[pymethods]
|
||||
impl DexChar {
|
||||
#[new]
|
||||
pub fn new(val: u16) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u16 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexChar({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexInt(pub i32);
|
||||
#[pymethods]
|
||||
impl DexInt {
|
||||
#[new]
|
||||
pub fn new(val: i32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexInt({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexLong(pub i64);
|
||||
#[pymethods]
|
||||
impl DexLong {
|
||||
#[new]
|
||||
pub fn new(val: i64) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> i64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexLong({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DexFloat(pub f32);
|
||||
#[pymethods]
|
||||
impl DexFloat {
|
||||
#[new]
|
||||
pub fn new(val: f32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> f32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexFloat({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct DexDouble(pub f64);
|
||||
#[pymethods]
|
||||
impl DexDouble {
|
||||
#[new]
|
||||
pub fn new(val: f64) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> f64 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexDouble({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
/* DexString is already define in lib.rs, TODO: move the version in lib.rs here
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexString(pub u32);
|
||||
#[pymethods]
|
||||
impl DexString {
|
||||
#[new]
|
||||
pub fn new(val: u32) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> u32 {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexString({})", self.0)
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexNull;
|
||||
#[pymethods]
|
||||
impl DexNull {
|
||||
#[new]
|
||||
pub fn _new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
"DexNull".into()
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexBoolean(pub bool);
|
||||
#[pymethods]
|
||||
impl DexBoolean {
|
||||
#[new]
|
||||
pub fn new(val: bool) -> Self {
|
||||
Self(val)
|
||||
}
|
||||
|
||||
pub fn get_value(&self) -> bool {
|
||||
self.0
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
format!("DexBoolean({})", self.0)
|
||||
}
|
||||
}
|
||||
|
||||
#[pyclass]
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct DexArray;
|
||||
#[pymethods]
|
||||
impl DexArray {
|
||||
#[new]
|
||||
pub fn _new() -> Self {
|
||||
Self
|
||||
}
|
||||
|
||||
pub fn get_value(&self) {
|
||||
todo!()
|
||||
}
|
||||
|
||||
pub fn __str__(&self) -> String {
|
||||
self.__repr__()
|
||||
}
|
||||
|
||||
pub fn __repr__(&self) -> String {
|
||||
"DexArray".into()
|
||||
}
|
||||
}
|
||||
99
androscalpel/src/value.rs
Normal file
99
androscalpel/src/value.rs
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
//! The class identifying dex structure.
|
||||
|
||||
use pyo3::exceptions::PyTypeError;
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use crate::{dex_id::*, scalar::*, DexString};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum DexValue {
|
||||
Byte(DexByte),
|
||||
Short(DexShort),
|
||||
Char(DexChar),
|
||||
Int(DexInt),
|
||||
Long(DexLong),
|
||||
Float(DexFloat),
|
||||
Double(DexDouble),
|
||||
MethodType(IdMethodType),
|
||||
//MethodHandle(DexMethodHandle),
|
||||
String(DexString),
|
||||
Type(IdType),
|
||||
Field(IdField),
|
||||
Method(IdMethod),
|
||||
Enum(IdEnum),
|
||||
Array(DexArray),
|
||||
Annotation(IdAnnotation),
|
||||
Null(DexNull),
|
||||
Boolean(DexBoolean),
|
||||
}
|
||||
|
||||
impl<'source> FromPyObject<'source> for DexValue {
|
||||
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||
if let Ok(val) = DexByte::extract(ob) {
|
||||
Ok(Self::Byte(val))
|
||||
} else if let Ok(val) = DexShort::extract(ob) {
|
||||
Ok(Self::Short(val))
|
||||
} else if let Ok(val) = DexChar::extract(ob) {
|
||||
Ok(Self::Char(val))
|
||||
} else if let Ok(val) = DexInt::extract(ob) {
|
||||
Ok(Self::Int(val))
|
||||
} else if let Ok(val) = DexLong::extract(ob) {
|
||||
Ok(Self::Long(val))
|
||||
} else if let Ok(val) = DexFloat::extract(ob) {
|
||||
Ok(Self::Float(val))
|
||||
} else if let Ok(val) = DexDouble::extract(ob) {
|
||||
Ok(Self::Double(val))
|
||||
} else if let Ok(val) = DexString::extract(ob) {
|
||||
Ok(Self::String(val))
|
||||
} else if let Ok(val) = IdType::extract(ob) {
|
||||
Ok(Self::Type(val))
|
||||
} else if let Ok(val) = IdField::extract(ob) {
|
||||
Ok(Self::Field(val))
|
||||
} else if let Ok(val) = IdMethod::extract(ob) {
|
||||
Ok(Self::Method(val))
|
||||
} else if let Ok(val) = IdEnum::extract(ob) {
|
||||
Ok(Self::Enum(val))
|
||||
} else if let Ok(val) = DexArray::extract(ob) {
|
||||
Ok(Self::Array(val))
|
||||
} else if let Ok(val) = IdAnnotation::extract(ob) {
|
||||
Ok(Self::Annotation(val))
|
||||
} else if let Ok(val) = DexNull::extract(ob) {
|
||||
Ok(Self::Null(val))
|
||||
} else if let Ok(val) = DexBoolean::extract(ob) {
|
||||
Ok(Self::Boolean(val))
|
||||
} else if let Ok(val) = IdMethodType::extract(ob) {
|
||||
Ok(Self::MethodType(val))
|
||||
// } else if let Ok(val) = DexMethodHandle::extract(ob) { Ok(Self::MethodHandle(val))
|
||||
} else {
|
||||
Err(PyErr::new::<PyTypeError, _>(format!(
|
||||
"{} is not a castable as a DexValue",
|
||||
ob.repr()?
|
||||
)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoPy<PyObject> for DexValue {
|
||||
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||
match self {
|
||||
DexValue::Byte(val) => val.into_py(py),
|
||||
DexValue::Short(val) => val.into_py(py),
|
||||
DexValue::Char(val) => val.into_py(py),
|
||||
DexValue::Int(val) => val.into_py(py),
|
||||
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::MethodHandle(val) => val.into_py(py),
|
||||
DexValue::String(val) => val.into_py(py),
|
||||
DexValue::Type(val) => val.into_py(py),
|
||||
DexValue::Field(val) => val.into_py(py),
|
||||
DexValue::Method(val) => val.into_py(py),
|
||||
DexValue::Enum(val) => val.into_py(py),
|
||||
DexValue::Array(val) => val.into_py(py),
|
||||
DexValue::Annotation(val) => val.into_py(py),
|
||||
DexValue::Null(val) => val.into_py(py),
|
||||
DexValue::Boolean(val) => val.into_py(py),
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue