add flags for fields
This commit is contained in:
parent
c84e3e36cc
commit
68520d0c30
4 changed files with 88 additions and 10 deletions
|
|
@ -2,7 +2,7 @@
|
||||||
use log::info;
|
use log::info;
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{Class, DexString, Field, Result};
|
use crate::{Class, DexString, Error, Field, FieldVisibility, Result};
|
||||||
use androscalpel_serializer::*;
|
use androscalpel_serializer::*;
|
||||||
|
|
||||||
/// Represent an apk.
|
/// Represent an apk.
|
||||||
|
|
@ -34,11 +34,11 @@ impl Apk {
|
||||||
.get_type_id(class_item.class_idx as usize)?
|
.get_type_id(class_item.class_idx as usize)?
|
||||||
.descriptor_idx;
|
.descriptor_idx;
|
||||||
let name: DexString = dex.get_string(name_idx)?.into();
|
let name: DexString = dex.get_string(name_idx)?.into();
|
||||||
let superclass = if class_item.class_idx == NO_INDEX.0 {
|
let superclass = if class_item.superclass_idx == NO_INDEX.0 {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let superclass_idx = dex
|
let superclass_idx = dex
|
||||||
.get_type_id(class_item.class_idx as usize)?
|
.get_type_id(class_item.superclass_idx as usize)?
|
||||||
.descriptor_idx;
|
.descriptor_idx;
|
||||||
Some(dex.get_string(superclass_idx)?.into())
|
Some(dex.get_string(superclass_idx)?.into())
|
||||||
};
|
};
|
||||||
|
|
@ -116,13 +116,49 @@ impl Apk {
|
||||||
let mut fields = vec![];
|
let mut fields = vec![];
|
||||||
for field in encoded_fields {
|
for field in encoded_fields {
|
||||||
idx += field.field_idx_diff.0;
|
idx += field.field_idx_diff.0;
|
||||||
// TODO: flags
|
|
||||||
let id_item = dex.get_field_id(idx as usize)?;
|
let id_item = dex.get_field_id(idx as usize)?;
|
||||||
// Check class_idx == class? ¯\_(ツ)/¯
|
// Check class_idx == class? ¯\_(ツ)/¯ at list it usefull for debug
|
||||||
|
let class_ty = dex.get_type_id(id_item.class_idx as usize)?;
|
||||||
|
let class: DexString = dex.get_string(class_ty.descriptor_idx)?.into();
|
||||||
|
let class: String = class.into();
|
||||||
let ty = dex.get_type_id(id_item.type_idx as usize)?;
|
let ty = dex.get_type_id(id_item.type_idx as usize)?;
|
||||||
let ty = dex.get_string(ty.descriptor_idx)?.into();
|
let ty = dex.get_string(ty.descriptor_idx)?.into();
|
||||||
let name = dex.get_string(id_item.name_idx)?.into();
|
let name: DexString = dex.get_string(id_item.name_idx)?.into();
|
||||||
fields.push(Field { name, type_: ty })
|
|
||||||
|
let is_public = (field.access_flags.0 & ACC_PUBLIC) != 0;
|
||||||
|
let is_private = (field.access_flags.0 & ACC_PRIVATE) != 0;
|
||||||
|
let is_protected = (field.access_flags.0 & ACC_PROTECTED) != 0;
|
||||||
|
let is_static = (field.access_flags.0 & ACC_STATIC) != 0;
|
||||||
|
let is_final = (field.access_flags.0 & ACC_FINAL) != 0;
|
||||||
|
let is_volatile = (field.access_flags.0 & ACC_VOLATILE) != 0;
|
||||||
|
let is_transient = (field.access_flags.0 & ACC_TRANSIENT) != 0;
|
||||||
|
let is_synthetic = (field.access_flags.0 & ACC_SYNTHETIC) != 0;
|
||||||
|
let is_enum = (field.access_flags.0 & ACC_ENUM) != 0;
|
||||||
|
let visibility = match (is_public, is_private, is_protected) {
|
||||||
|
(true, false, false) => FieldVisibility::Public,
|
||||||
|
(false, true, false) => FieldVisibility::Private,
|
||||||
|
(false, false, true) => FieldVisibility::Protected,
|
||||||
|
(false, false, false) => FieldVisibility::None_,
|
||||||
|
(pbl, prv, prt) => {
|
||||||
|
let name: String = name.into();
|
||||||
|
return Err(Error::InconsistantStruct(format!(
|
||||||
|
"Inconsistant visiblity found in {class}.{name}: \
|
||||||
|
(public: {pbl}, private: {prv}, protected: {prt})"
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
fields.push(Field {
|
||||||
|
name,
|
||||||
|
type_: ty,
|
||||||
|
visibility,
|
||||||
|
is_static,
|
||||||
|
is_final,
|
||||||
|
is_volatile,
|
||||||
|
is_transient,
|
||||||
|
is_synthetic,
|
||||||
|
is_enum,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
Ok(fields)
|
Ok(fields)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -69,7 +69,7 @@ impl Class {
|
||||||
pub fn new(name: DexString) -> Self {
|
pub fn new(name: DexString) -> Self {
|
||||||
Self {
|
Self {
|
||||||
name,
|
name,
|
||||||
superclass: None,
|
superclass: Some("Ljava/lang/Object;".into()),
|
||||||
interfaces: vec![],
|
interfaces: vec![],
|
||||||
source_file: None,
|
source_file: None,
|
||||||
is_public: true,
|
is_public: true,
|
||||||
|
|
|
||||||
|
|
@ -15,13 +15,54 @@ pub struct Field {
|
||||||
/// The type of the field, format described at <>
|
/// The type of the field, format described at <>
|
||||||
#[pyo3(get, set)]
|
#[pyo3(get, set)]
|
||||||
pub type_: DexString,
|
pub type_: DexString,
|
||||||
|
/// The field visibility
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub visibility: FieldVisibility,
|
||||||
|
/// If the field is defined for the class globally
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub is_static: bool,
|
||||||
|
/// If the field is immutable after construction
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub is_final: bool,
|
||||||
|
/// For thread safety
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub is_volatile: bool,
|
||||||
|
/// If the field should **not** be saved by default serialization
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub is_transient: bool,
|
||||||
|
/// If the field is not defined in the source code
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub is_synthetic: bool,
|
||||||
|
/// If the field is an enumerated value
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub is_enum: bool,
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Represent the visibility of a field
|
||||||
|
#[pyclass]
|
||||||
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
||||||
|
pub enum FieldVisibility {
|
||||||
|
Public,
|
||||||
|
Private,
|
||||||
|
Protected,
|
||||||
|
None_, // Actually quite common
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
impl Field {
|
impl Field {
|
||||||
#[new]
|
#[new]
|
||||||
pub fn new(name: DexString, type_: DexString) -> Self {
|
pub fn new(name: DexString, type_: DexString) -> Self {
|
||||||
Self { name, type_ }
|
Self {
|
||||||
|
name,
|
||||||
|
type_,
|
||||||
|
visibility: FieldVisibility::Public,
|
||||||
|
is_static: false,
|
||||||
|
is_final: false,
|
||||||
|
is_volatile: false,
|
||||||
|
is_transient: false,
|
||||||
|
is_synthetic: false,
|
||||||
|
is_enum: false,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn __str__(&self) -> String {
|
pub fn __str__(&self) -> String {
|
||||||
|
|
|
||||||
|
|
@ -148,8 +148,9 @@ 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::<DexString>()?;
|
||||||
|
m.add_class::<FieldVisibility>()?;
|
||||||
m.add_class::<Class>()?;
|
m.add_class::<Class>()?;
|
||||||
m.add_class::<Apk>()?;
|
m.add_class::<Apk>()?;
|
||||||
m.add_class::<DexString>()?;
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue