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 pyo3::prelude::*;
|
||||
|
||||
use crate::{Class, DexString, Field, Result};
|
||||
use crate::{Class, DexString, Error, Field, FieldVisibility, Result};
|
||||
use androscalpel_serializer::*;
|
||||
|
||||
/// Represent an apk.
|
||||
|
|
@ -34,11 +34,11 @@ impl Apk {
|
|||
.get_type_id(class_item.class_idx as usize)?
|
||||
.descriptor_idx;
|
||||
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
|
||||
} else {
|
||||
let superclass_idx = dex
|
||||
.get_type_id(class_item.class_idx as usize)?
|
||||
.get_type_id(class_item.superclass_idx as usize)?
|
||||
.descriptor_idx;
|
||||
Some(dex.get_string(superclass_idx)?.into())
|
||||
};
|
||||
|
|
@ -116,13 +116,49 @@ impl Apk {
|
|||
let mut fields = vec![];
|
||||
for field in encoded_fields {
|
||||
idx += field.field_idx_diff.0;
|
||||
// TODO: flags
|
||||
|
||||
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_string(ty.descriptor_idx)?.into();
|
||||
let name = dex.get_string(id_item.name_idx)?.into();
|
||||
fields.push(Field { name, type_: ty })
|
||||
let name: DexString = dex.get_string(id_item.name_idx)?.into();
|
||||
|
||||
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)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ impl Class {
|
|||
pub fn new(name: DexString) -> Self {
|
||||
Self {
|
||||
name,
|
||||
superclass: None,
|
||||
superclass: Some("Ljava/lang/Object;".into()),
|
||||
interfaces: vec![],
|
||||
source_file: None,
|
||||
is_public: true,
|
||||
|
|
|
|||
|
|
@ -15,13 +15,54 @@ pub struct Field {
|
|||
/// The type of the field, format described at <>
|
||||
#[pyo3(get, set)]
|
||||
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]
|
||||
impl Field {
|
||||
#[new]
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -148,8 +148,9 @@ impl DexString {
|
|||
#[pymodule]
|
||||
fn androscalpel(_py: Python, m: &PyModule) -> PyResult<()> {
|
||||
pyo3_log::init();
|
||||
m.add_class::<DexString>()?;
|
||||
m.add_class::<FieldVisibility>()?;
|
||||
m.add_class::<Class>()?;
|
||||
m.add_class::<Apk>()?;
|
||||
m.add_class::<DexString>()?;
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue