add annotations for methods and parameters

This commit is contained in:
Jean-Marie Mineau 2023-11-29 12:12:41 +01:00
parent cf55766653
commit 224d1efdba
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
4 changed files with 160 additions and 14 deletions

View file

@ -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: (),
})
}

View file

@ -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![],
}
}

View file

@ -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: (),
}
}