add annotations for methods and parameters
This commit is contained in:
parent
cf55766653
commit
224d1efdba
4 changed files with 160 additions and 14 deletions
|
|
@ -92,7 +92,7 @@ impl Apk {
|
|||
Some(dex.get_struct_at_offset::<AnnotationDirectoryItem>(class_item.annotations_off)?)
|
||||
};
|
||||
let mut annotations = vec![];
|
||||
if let Some(annotations_directory) = annotations_directory {
|
||||
if let Some(annotations_directory) = &annotations_directory {
|
||||
if annotations_directory.class_annotations_off != 0 {
|
||||
annotations = Self::get_annotation_items_from_annotation_set_off(
|
||||
annotations_directory.class_annotations_off,
|
||||
|
|
@ -137,6 +137,134 @@ impl Apk {
|
|||
field.value = None;
|
||||
}
|
||||
}
|
||||
if let Some(annotations_directory) = annotations_directory {
|
||||
for field_annotation in annotations_directory.field_annotations {
|
||||
let field_id =
|
||||
Self::get_id_field_from_idx(field_annotation.field_idx as usize, dex)?;
|
||||
let annotations = if field_annotation.annotations_off != 0 {
|
||||
Self::get_annotation_items_from_annotation_set_off(
|
||||
field_annotation.annotations_off,
|
||||
dex,
|
||||
)?
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
if field_id.class_.get_name() != name {
|
||||
info!(
|
||||
"Annotation for field {} found in class {}, dropping it",
|
||||
field_id.__str__(),
|
||||
name.__str__(),
|
||||
);
|
||||
}
|
||||
let mut found = false;
|
||||
for field in &mut instance_fields {
|
||||
if field.descriptor == field_id {
|
||||
field.annotations.append(&mut (annotations.clone())); // the clone is prob
|
||||
// unnecessary
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
for field in &mut static_fields {
|
||||
if field.descriptor == field_id {
|
||||
field.annotations.append(&mut (annotations.clone())); // the clone is prob
|
||||
// unnecessary
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
info!(
|
||||
"Annotation found for field {} but could not find the field definition, dropping it",
|
||||
field_id.__str__(),
|
||||
);
|
||||
}
|
||||
}
|
||||
for method_annotation in annotations_directory.method_annotations {
|
||||
let method_id =
|
||||
Self::get_id_method_from_idx(method_annotation.method_idx as usize, dex)?;
|
||||
let annotations = if method_annotation.annotations_off != 0 {
|
||||
Self::get_annotation_items_from_annotation_set_off(
|
||||
method_annotation.annotations_off,
|
||||
dex,
|
||||
)?
|
||||
} else {
|
||||
vec![]
|
||||
};
|
||||
if method_id.class_.get_name() != name {
|
||||
info!(
|
||||
"Annotation for method {} found in class {}, dropping it",
|
||||
method_id.__str__(),
|
||||
name.__str__(),
|
||||
);
|
||||
}
|
||||
let mut found = false;
|
||||
for method in &mut direct_methods {
|
||||
if method.descriptor == method_id {
|
||||
method.annotations.append(&mut (annotations.clone())); // the clone is prob
|
||||
// unnecessary
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
for method in &mut virtual_methods {
|
||||
if method.descriptor == method_id {
|
||||
method.annotations.append(&mut (annotations.clone())); // the clone is prob
|
||||
// unnecessary
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
info!(
|
||||
"Annotation found for method {} but could not find the method definition, dropping it",
|
||||
method_id.__str__(),
|
||||
);
|
||||
}
|
||||
}
|
||||
for parameter_annotation in annotations_directory.parameter_annotations {
|
||||
let method_id =
|
||||
Self::get_id_method_from_idx(parameter_annotation.method_idx as usize, dex)?;
|
||||
let annotation_set_ref_list = dex.get_struct_at_offset::<AnnotationSetRefList>(
|
||||
parameter_annotation.annotations_off,
|
||||
)?;
|
||||
let mut annotations_list = vec![];
|
||||
for annotation_set in annotation_set_ref_list.list {
|
||||
if annotation_set.annotations_off != 0 {
|
||||
annotations_list.push(Self::get_annotation_items_from_annotation_set_off(
|
||||
annotation_set.annotations_off,
|
||||
dex,
|
||||
)?);
|
||||
} else {
|
||||
annotations_list.push(vec![]);
|
||||
}
|
||||
}
|
||||
if method_id.class_.get_name() != name {
|
||||
info!(
|
||||
"Annotation for parameter of method {} found in class {}, dropping it",
|
||||
method_id.__str__(),
|
||||
name.__str__(),
|
||||
);
|
||||
}
|
||||
let mut found = false;
|
||||
for method in &mut direct_methods {
|
||||
if method.descriptor == method_id {
|
||||
method.parameters_annotations = annotations_list.clone(); // the clone is prob
|
||||
// unnecessary
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
for method in &mut virtual_methods {
|
||||
if method.descriptor == method_id {
|
||||
method.parameters_annotations = annotations_list.clone(); // the clone is prob
|
||||
// unnecessary
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
info!(
|
||||
"Annotation found for parameter of method {} but could not find the method definition, dropping it",
|
||||
method_id.__str__(),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(Class {
|
||||
name,
|
||||
superclass,
|
||||
|
|
@ -427,6 +555,7 @@ impl Apk {
|
|||
is_synthetic,
|
||||
is_enum,
|
||||
value: None,
|
||||
annotations: vec![],
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -546,6 +675,8 @@ impl Apk {
|
|||
is_synthetic,
|
||||
is_constructor,
|
||||
is_declared_syncrhonized,
|
||||
annotations: vec![],
|
||||
parameters_annotations: vec![],
|
||||
code: (),
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use crate::{DexValue, IdField};
|
||||
use crate::{DexAnnotationItem, DexValue, IdField};
|
||||
|
||||
/// Represent a field.
|
||||
#[pyclass]
|
||||
|
|
@ -34,6 +34,9 @@ pub struct Field {
|
|||
pub is_enum: bool,
|
||||
/// The default value of this field
|
||||
pub value: Option<DexValue>,
|
||||
/// The annotations for this field
|
||||
#[pyo3(get, set)]
|
||||
pub annotations: Vec<DexAnnotationItem>,
|
||||
}
|
||||
|
||||
/// Represent the visibility of a field
|
||||
|
|
@ -60,6 +63,7 @@ impl Field {
|
|||
is_synthetic: false,
|
||||
is_enum: false,
|
||||
value: None,
|
||||
annotations: vec![],
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
use pyo3::prelude::*;
|
||||
|
||||
use crate::IdMethod;
|
||||
use crate::{DexAnnotationItem, IdMethod};
|
||||
|
||||
/// Represent a method.
|
||||
#[pyclass]
|
||||
|
|
@ -49,6 +49,12 @@ pub struct Method {
|
|||
/// If the method is declared as synchronize (just indicatif)
|
||||
#[pyo3(get, set)]
|
||||
pub is_declared_syncrhonized: bool,
|
||||
/// The annotations for this method
|
||||
#[pyo3(get, set)]
|
||||
pub annotations: Vec<DexAnnotationItem>,
|
||||
/// The annotations for the parameters of this method method
|
||||
#[pyo3(get, set)]
|
||||
pub parameters_annotations: Vec<Vec<DexAnnotationItem>>,
|
||||
|
||||
/// The code of the method
|
||||
pub code: (),
|
||||
|
|
@ -82,6 +88,8 @@ impl Method {
|
|||
is_synthetic: false,
|
||||
is_constructor: false,
|
||||
is_declared_syncrhonized: false,
|
||||
annotations: vec![],
|
||||
parameters_annotations: vec![],
|
||||
code: (),
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ pub struct AnnotationDirectoryItem {
|
|||
pub field_annotations: Vec<FieldAnnotation>,
|
||||
/// List of method annotation. The method annotations must be sorted by
|
||||
/// increasing order of [`crate::MethodAnnotation.method_idx`].
|
||||
pub method_annotation: Vec<MethodAnnotation>,
|
||||
pub method_annotations: Vec<MethodAnnotation>,
|
||||
/// List of associated method parameter annotation. The parameter annotations
|
||||
/// must be sorted by increasing order of [`crate::ParameterAnnotation.parameter_size`].
|
||||
pub parameter_annotations: Vec<ParameterAnnotation>,
|
||||
|
|
@ -32,7 +32,7 @@ impl AnnotationDirectoryItem {
|
|||
self.field_annotations.len() as u32
|
||||
}
|
||||
pub fn annotated_methods_size_field(&self) -> u32 {
|
||||
self.method_annotation.len() as u32
|
||||
self.method_annotations.len() as u32
|
||||
}
|
||||
pub fn parameter_annotations_field(&self) -> u32 {
|
||||
self.parameter_annotations.len() as u32
|
||||
|
|
@ -49,7 +49,7 @@ impl Serializable for AnnotationDirectoryItem {
|
|||
for item in &self.field_annotations {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
for item in &self.method_annotation {
|
||||
for item in &self.method_annotations {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
for item in &self.parameter_annotations {
|
||||
|
|
@ -66,9 +66,9 @@ impl Serializable for AnnotationDirectoryItem {
|
|||
for _ in 0..fields_size {
|
||||
field_annotations.push(FieldAnnotation::deserialize(input)?);
|
||||
}
|
||||
let mut method_annotation = vec![];
|
||||
let mut method_annotations = vec![];
|
||||
for _ in 0..annotated_methods_size {
|
||||
method_annotation.push(MethodAnnotation::deserialize(input)?);
|
||||
method_annotations.push(MethodAnnotation::deserialize(input)?);
|
||||
}
|
||||
let mut parameter_annotations = vec![];
|
||||
for _ in 0..annotated_parameters_size {
|
||||
|
|
@ -78,7 +78,7 @@ impl Serializable for AnnotationDirectoryItem {
|
|||
Ok(Self {
|
||||
class_annotations_off,
|
||||
field_annotations,
|
||||
method_annotation,
|
||||
method_annotations,
|
||||
parameter_annotations,
|
||||
})
|
||||
}
|
||||
|
|
@ -93,7 +93,7 @@ impl Serializable for AnnotationDirectoryItem {
|
|||
.map(|val| val.size())
|
||||
.sum::<usize>()
|
||||
+ self
|
||||
.method_annotation
|
||||
.method_annotations
|
||||
.iter()
|
||||
.map(|val| val.size())
|
||||
.sum::<usize>()
|
||||
|
|
@ -108,25 +108,28 @@ impl Serializable for AnnotationDirectoryItem {
|
|||
/// <https://source.android.com/docs/core/runtime/dex-format#field-annotation>
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FieldAnnotation {
|
||||
/// Index of the field annotated in `field_ids`
|
||||
pub field_idx: u32,
|
||||
/// Offset to a [`AnnotationSetItem`]
|
||||
pub annotation_off: u32,
|
||||
pub annotations_off: u32,
|
||||
}
|
||||
|
||||
/// <https://source.android.com/docs/core/runtime/dex-format#method-annotation>
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MethodAnnotation {
|
||||
/// Index of the method annotated in `method_ids`
|
||||
pub method_idx: u32,
|
||||
/// Offset to a [`AnnotationSetItem`]
|
||||
pub annotation_off: u32,
|
||||
pub annotations_off: u32,
|
||||
}
|
||||
|
||||
/// <https://source.android.com/docs/core/runtime/dex-format#parameter-annotation>
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct ParameterAnnotation {
|
||||
pub field_idx: u32,
|
||||
/// Index of the method whose parameters are annotated in `method_ids`
|
||||
pub method_idx: u32,
|
||||
/// Offset of a [`AnnotationSetRefList`]
|
||||
pub annotation_off: u32,
|
||||
pub annotations_off: u32,
|
||||
}
|
||||
|
||||
/// <https://source.android.com/docs/core/runtime/dex-format#set-ref-list>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue