add method handle
This really needs more checks
This commit is contained in:
parent
77be653786
commit
feff847310
6 changed files with 351 additions and 36 deletions
|
|
@ -199,6 +199,44 @@ impl Apk {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a [`MethodHandle`] from its idx.
|
||||||
|
pub fn get_method_handle_from_idx(idx: usize, dex: &DexFileReader) -> Result<MethodHandle> {
|
||||||
|
let handle = dex.get_method_handle(idx)?;
|
||||||
|
match handle.method_handle_type {
|
||||||
|
MethodHandleType::StaticPut => Ok(MethodHandle::StaticPut(StaticPut(
|
||||||
|
Self::get_id_field_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::StaticGet => Ok(MethodHandle::StaticGet(StaticGet(
|
||||||
|
Self::get_id_field_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::InstancePut => Ok(MethodHandle::InstancePut(InstancePut(
|
||||||
|
Self::get_id_field_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::InstanceGet => Ok(MethodHandle::InstanceGet(InstanceGet(
|
||||||
|
Self::get_id_field_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::InvokeStatic => Ok(MethodHandle::InvokeStatic(InvokeStatic(
|
||||||
|
Self::get_id_method_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::InvokeInstance => Ok(MethodHandle::InvokeInstance(InvokeInstance(
|
||||||
|
Self::get_id_method_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::InvokeConstructor => {
|
||||||
|
Ok(MethodHandle::InvokeConstructor(InvokeConstructor(
|
||||||
|
Self::get_id_method_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
MethodHandleType::InvokeDirect => Ok(MethodHandle::InvokeDirect(InvokeDirect(
|
||||||
|
Self::get_id_method_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
))),
|
||||||
|
MethodHandleType::InvokeInterface => {
|
||||||
|
Ok(MethodHandle::InvokeInterface(InvokeInterface(
|
||||||
|
Self::get_id_method_from_idx(handle.field_or_method_id as usize, dex)?,
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn encoded_value_to_dex_value(
|
pub fn encoded_value_to_dex_value(
|
||||||
encoded_value: &EncodedValue,
|
encoded_value: &EncodedValue,
|
||||||
dex: &DexFileReader,
|
dex: &DexFileReader,
|
||||||
|
|
@ -214,8 +252,9 @@ impl Apk {
|
||||||
EncodedValue::MethodType(val) => Ok(DexValue::MethodType(
|
EncodedValue::MethodType(val) => Ok(DexValue::MethodType(
|
||||||
Self::get_id_method_type_from_idx(*val as usize, dex)?,
|
Self::get_id_method_type_from_idx(*val as usize, dex)?,
|
||||||
)),
|
)),
|
||||||
// TODO: need method to be implemented first
|
EncodedValue::MethodHandle(val) => Ok(DexValue::MethodHandle(
|
||||||
EncodedValue::MethodHandle(_val) => todo!(), //Ok(DexValue::MethodHandle(DexMethodHandle(*val))),
|
Self::get_method_handle_from_idx(*val as usize, dex)?,
|
||||||
|
)),
|
||||||
EncodedValue::String(val) => Ok(DexValue::String(dex.get_string(*val)?.into())),
|
EncodedValue::String(val) => Ok(DexValue::String(dex.get_string(*val)?.into())),
|
||||||
EncodedValue::Type(val) => Ok(DexValue::Type(Self::get_id_type_from_idx(
|
EncodedValue::Type(val) => Ok(DexValue::Type(Self::get_id_type_from_idx(
|
||||||
*val as usize,
|
*val as usize,
|
||||||
|
|
|
||||||
|
|
@ -58,31 +58,6 @@ impl IdMethodType {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[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.
|
/// A type.
|
||||||
/// Type represented by [`DexString`] that follow the TypeDescriptor format
|
/// Type represented by [`DexString`] that follow the TypeDescriptor format
|
||||||
/// as described here <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
/// as described here <https://source.android.com/docs/core/runtime/dex-format#typedescriptor>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@ pub mod apk;
|
||||||
pub mod class;
|
pub mod class;
|
||||||
pub mod dex_id;
|
pub mod dex_id;
|
||||||
pub mod field;
|
pub mod field;
|
||||||
|
pub mod method_handle;
|
||||||
pub mod scalar;
|
pub mod scalar;
|
||||||
pub mod value;
|
pub mod value;
|
||||||
|
|
||||||
|
|
@ -13,6 +14,7 @@ pub use apk::*;
|
||||||
pub use class::*;
|
pub use class::*;
|
||||||
pub use dex_id::*;
|
pub use dex_id::*;
|
||||||
pub use field::*;
|
pub use field::*;
|
||||||
|
pub use method_handle::*;
|
||||||
pub use scalar::*;
|
pub use scalar::*;
|
||||||
pub use value::*;
|
pub use value::*;
|
||||||
|
|
||||||
|
|
@ -154,6 +156,8 @@ impl DexString {
|
||||||
#[pymodule]
|
#[pymodule]
|
||||||
fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
|
fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
pyo3_log::init();
|
pyo3_log::init();
|
||||||
|
m.add_class::<DexNull>()?;
|
||||||
|
m.add_class::<DexBoolean>()?;
|
||||||
m.add_class::<DexByte>()?;
|
m.add_class::<DexByte>()?;
|
||||||
m.add_class::<DexShort>()?;
|
m.add_class::<DexShort>()?;
|
||||||
m.add_class::<DexChar>()?;
|
m.add_class::<DexChar>()?;
|
||||||
|
|
@ -161,18 +165,26 @@ fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||||
m.add_class::<DexLong>()?;
|
m.add_class::<DexLong>()?;
|
||||||
m.add_class::<DexFloat>()?;
|
m.add_class::<DexFloat>()?;
|
||||||
m.add_class::<DexDouble>()?;
|
m.add_class::<DexDouble>()?;
|
||||||
// m.add_class::<DexMethodType>()?;
|
|
||||||
// m.add_class::<DexMethodHandle>()?;
|
|
||||||
m.add_class::<DexString>()?;
|
m.add_class::<DexString>()?;
|
||||||
|
|
||||||
|
m.add_class::<IdMethodType>()?;
|
||||||
m.add_class::<IdType>()?;
|
m.add_class::<IdType>()?;
|
||||||
m.add_class::<IdField>()?;
|
m.add_class::<IdField>()?;
|
||||||
m.add_class::<IdMethod>()?;
|
m.add_class::<IdMethod>()?;
|
||||||
m.add_class::<IdEnum>()?;
|
m.add_class::<IdEnum>()?;
|
||||||
|
|
||||||
|
m.add_class::<StaticPut>()?;
|
||||||
|
m.add_class::<StaticGet>()?;
|
||||||
|
m.add_class::<InstancePut>()?;
|
||||||
|
m.add_class::<InstanceGet>()?;
|
||||||
|
m.add_class::<InvokeStatic>()?;
|
||||||
|
m.add_class::<InvokeInstance>()?;
|
||||||
|
m.add_class::<InvokeConstructor>()?;
|
||||||
|
m.add_class::<InvokeDirect>()?;
|
||||||
|
m.add_class::<InvokeInterface>()?;
|
||||||
|
|
||||||
m.add_class::<DexArray>()?;
|
m.add_class::<DexArray>()?;
|
||||||
m.add_class::<IdAnnotation>()?;
|
m.add_class::<IdAnnotation>()?;
|
||||||
m.add_class::<DexNull>()?;
|
|
||||||
m.add_class::<DexBoolean>()?;
|
|
||||||
m.add_class::<DexString>()?;
|
|
||||||
m.add_class::<FieldVisibility>()?;
|
m.add_class::<FieldVisibility>()?;
|
||||||
m.add_class::<Class>()?;
|
m.add_class::<Class>()?;
|
||||||
m.add_class::<Apk>()?;
|
m.add_class::<Apk>()?;
|
||||||
|
|
|
||||||
278
androscalpel/src/method_handle.rs
Normal file
278
androscalpel/src/method_handle.rs
Normal file
|
|
@ -0,0 +1,278 @@
|
||||||
|
//! The structure use to reference a method invocation.
|
||||||
|
|
||||||
|
use pyo3::exceptions::PyTypeError;
|
||||||
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
|
use crate::dex_id::*;
|
||||||
|
|
||||||
|
/// The structure use to reference a method invocation.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub enum MethodHandle {
|
||||||
|
StaticPut(StaticPut),
|
||||||
|
StaticGet(StaticGet),
|
||||||
|
InstancePut(InstancePut),
|
||||||
|
InstanceGet(InstanceGet),
|
||||||
|
InvokeStatic(InvokeStatic),
|
||||||
|
InvokeInstance(InvokeInstance),
|
||||||
|
InvokeConstructor(InvokeConstructor),
|
||||||
|
InvokeDirect(InvokeDirect),
|
||||||
|
InvokeInterface(InvokeInterface),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct StaticPut(pub IdField);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl StaticPut {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdField) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_field(&self) -> IdField {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("StaticPut({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct StaticGet(pub IdField);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl StaticGet {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdField) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_field(&self) -> IdField {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("StaticGet({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InstancePut(pub IdField);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InstancePut {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdField) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_field(&self) -> IdField {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InstancePut({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InstanceGet(pub IdField);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InstanceGet {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdField) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_field(&self) -> IdField {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InstanceGet({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InvokeStatic(pub IdMethod);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InvokeStatic {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdMethod) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_method(&self) -> IdMethod {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InvokeStatic({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InvokeInstance(pub IdMethod);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InvokeInstance {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdMethod) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_method(&self) -> IdMethod {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InvokeInstance({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InvokeConstructor(pub IdMethod);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InvokeConstructor {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdMethod) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_method(&self) -> IdMethod {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InvokeConstructor({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InvokeDirect(pub IdMethod);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InvokeDirect {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdMethod) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_method(&self) -> IdMethod {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InvokeDirect({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub struct InvokeInterface(pub IdMethod);
|
||||||
|
|
||||||
|
#[pymethods]
|
||||||
|
impl InvokeInterface {
|
||||||
|
#[new]
|
||||||
|
pub fn new(val: IdMethod) -> Self {
|
||||||
|
Self(val)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn get_method(&self) -> IdMethod {
|
||||||
|
self.0.clone()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __str__(&self) -> String {
|
||||||
|
self.__repr__()
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn __repr__(&self) -> String {
|
||||||
|
format!("InvokeInterface({})", self.0.__str__())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'source> FromPyObject<'source> for MethodHandle {
|
||||||
|
fn extract(ob: &'source PyAny) -> PyResult<Self> {
|
||||||
|
if let Ok(val) = StaticPut::extract(ob) {
|
||||||
|
Ok(Self::StaticPut(val))
|
||||||
|
} else if let Ok(val) = StaticGet::extract(ob) {
|
||||||
|
Ok(Self::StaticGet(val))
|
||||||
|
} else if let Ok(val) = InstancePut::extract(ob) {
|
||||||
|
Ok(Self::InstancePut(val))
|
||||||
|
} else if let Ok(val) = InstanceGet::extract(ob) {
|
||||||
|
Ok(Self::InstanceGet(val))
|
||||||
|
} else if let Ok(val) = InvokeStatic::extract(ob) {
|
||||||
|
Ok(Self::InvokeStatic(val))
|
||||||
|
} else if let Ok(val) = InvokeInstance::extract(ob) {
|
||||||
|
Ok(Self::InvokeInstance(val))
|
||||||
|
} else if let Ok(val) = InvokeConstructor::extract(ob) {
|
||||||
|
Ok(Self::InvokeConstructor(val))
|
||||||
|
} else if let Ok(val) = InvokeDirect::extract(ob) {
|
||||||
|
Ok(Self::InvokeDirect(val))
|
||||||
|
} else if let Ok(val) = InvokeInterface::extract(ob) {
|
||||||
|
Ok(Self::InvokeInterface(val))
|
||||||
|
} else {
|
||||||
|
Err(PyErr::new::<PyTypeError, _>(format!(
|
||||||
|
"{} is not a castable as a MethodHandle",
|
||||||
|
ob.repr()?
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoPy<PyObject> for MethodHandle {
|
||||||
|
fn into_py(self, py: Python<'_>) -> PyObject {
|
||||||
|
match self {
|
||||||
|
Self::StaticPut(val) => val.into_py(py),
|
||||||
|
Self::StaticGet(val) => val.into_py(py),
|
||||||
|
Self::InstancePut(val) => val.into_py(py),
|
||||||
|
Self::InstanceGet(val) => val.into_py(py),
|
||||||
|
Self::InvokeStatic(val) => val.into_py(py),
|
||||||
|
Self::InvokeInstance(val) => val.into_py(py),
|
||||||
|
Self::InvokeConstructor(val) => val.into_py(py),
|
||||||
|
Self::InvokeDirect(val) => val.into_py(py),
|
||||||
|
Self::InvokeInterface(val) => val.into_py(py),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -3,7 +3,7 @@
|
||||||
use pyo3::exceptions::PyTypeError;
|
use pyo3::exceptions::PyTypeError;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{dex_id::*, scalar::*, DexString};
|
use crate::{dex_id::*, scalar::*, DexString, MethodHandle};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum DexValue {
|
pub enum DexValue {
|
||||||
|
|
@ -15,7 +15,7 @@ pub enum DexValue {
|
||||||
Float(DexFloat),
|
Float(DexFloat),
|
||||||
Double(DexDouble),
|
Double(DexDouble),
|
||||||
MethodType(IdMethodType),
|
MethodType(IdMethodType),
|
||||||
//MethodHandle(DexMethodHandle),
|
MethodHandle(MethodHandle),
|
||||||
String(DexString),
|
String(DexString),
|
||||||
Type(IdType),
|
Type(IdType),
|
||||||
Field(IdField),
|
Field(IdField),
|
||||||
|
|
@ -63,7 +63,8 @@ impl<'source> FromPyObject<'source> for DexValue {
|
||||||
Ok(Self::Boolean(val))
|
Ok(Self::Boolean(val))
|
||||||
} else if let Ok(val) = IdMethodType::extract(ob) {
|
} else if let Ok(val) = IdMethodType::extract(ob) {
|
||||||
Ok(Self::MethodType(val))
|
Ok(Self::MethodType(val))
|
||||||
// } else if let Ok(val) = DexMethodHandle::extract(ob) { Ok(Self::MethodHandle(val))
|
} else if let Ok(val) = MethodHandle::extract(ob) {
|
||||||
|
Ok(Self::MethodHandle(val))
|
||||||
} else {
|
} else {
|
||||||
Err(PyErr::new::<PyTypeError, _>(format!(
|
Err(PyErr::new::<PyTypeError, _>(format!(
|
||||||
"{} is not a castable as a DexValue",
|
"{} is not a castable as a DexValue",
|
||||||
|
|
@ -84,7 +85,7 @@ impl IntoPy<PyObject> for DexValue {
|
||||||
DexValue::Float(val) => val.into_py(py),
|
DexValue::Float(val) => val.into_py(py),
|
||||||
DexValue::Double(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::MethodHandle(val) => val.into_py(py),
|
||||||
DexValue::String(val) => val.into_py(py),
|
DexValue::String(val) => val.into_py(py),
|
||||||
DexValue::Type(val) => val.into_py(py),
|
DexValue::Type(val) => val.into_py(py),
|
||||||
DexValue::Field(val) => val.into_py(py),
|
DexValue::Field(val) => val.into_py(py),
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,16 @@ impl<'a> DexFileReader<'a> {
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Return a [`MethodHandleItem`] reference from its idx.
|
||||||
|
pub fn get_method_handle(&self, idx: usize) -> Result<&MethodHandleItem> {
|
||||||
|
self.method_handles
|
||||||
|
.get(idx)
|
||||||
|
.ok_or(Error::InconsistantStruct(format!(
|
||||||
|
"method handle {idx} is out of bound (|method_handles|={})",
|
||||||
|
self.method_handles.len()
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
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] {
|
||||||
warn!(
|
warn!(
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue