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)?)
|
Some(dex.get_struct_at_offset::<AnnotationDirectoryItem>(class_item.annotations_off)?)
|
||||||
};
|
};
|
||||||
let mut annotations = vec![];
|
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 {
|
if annotations_directory.class_annotations_off != 0 {
|
||||||
annotations = Self::get_annotation_items_from_annotation_set_off(
|
annotations = Self::get_annotation_items_from_annotation_set_off(
|
||||||
annotations_directory.class_annotations_off,
|
annotations_directory.class_annotations_off,
|
||||||
|
|
@ -137,6 +137,134 @@ impl Apk {
|
||||||
field.value = None;
|
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 {
|
Ok(Class {
|
||||||
name,
|
name,
|
||||||
superclass,
|
superclass,
|
||||||
|
|
@ -427,6 +555,7 @@ impl Apk {
|
||||||
is_synthetic,
|
is_synthetic,
|
||||||
is_enum,
|
is_enum,
|
||||||
value: None,
|
value: None,
|
||||||
|
annotations: vec![],
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -546,6 +675,8 @@ impl Apk {
|
||||||
is_synthetic,
|
is_synthetic,
|
||||||
is_constructor,
|
is_constructor,
|
||||||
is_declared_syncrhonized,
|
is_declared_syncrhonized,
|
||||||
|
annotations: vec![],
|
||||||
|
parameters_annotations: vec![],
|
||||||
code: (),
|
code: (),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::{DexValue, IdField};
|
use crate::{DexAnnotationItem, DexValue, IdField};
|
||||||
|
|
||||||
/// Represent a field.
|
/// Represent a field.
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
|
|
@ -34,6 +34,9 @@ pub struct Field {
|
||||||
pub is_enum: bool,
|
pub is_enum: bool,
|
||||||
/// The default value of this field
|
/// The default value of this field
|
||||||
pub value: Option<DexValue>,
|
pub value: Option<DexValue>,
|
||||||
|
/// The annotations for this field
|
||||||
|
#[pyo3(get, set)]
|
||||||
|
pub annotations: Vec<DexAnnotationItem>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represent the visibility of a field
|
/// Represent the visibility of a field
|
||||||
|
|
@ -60,6 +63,7 @@ impl Field {
|
||||||
is_synthetic: false,
|
is_synthetic: false,
|
||||||
is_enum: false,
|
is_enum: false,
|
||||||
value: None,
|
value: None,
|
||||||
|
annotations: vec![],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
use pyo3::prelude::*;
|
use pyo3::prelude::*;
|
||||||
|
|
||||||
use crate::IdMethod;
|
use crate::{DexAnnotationItem, IdMethod};
|
||||||
|
|
||||||
/// Represent a method.
|
/// Represent a method.
|
||||||
#[pyclass]
|
#[pyclass]
|
||||||
|
|
@ -49,6 +49,12 @@ pub struct Method {
|
||||||
/// If the method is declared as synchronize (just indicatif)
|
/// If the method is declared as synchronize (just indicatif)
|
||||||
#[pyo3(get, set)]
|
#[pyo3(get, set)]
|
||||||
pub is_declared_syncrhonized: bool,
|
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
|
/// The code of the method
|
||||||
pub code: (),
|
pub code: (),
|
||||||
|
|
@ -82,6 +88,8 @@ impl Method {
|
||||||
is_synthetic: false,
|
is_synthetic: false,
|
||||||
is_constructor: false,
|
is_constructor: false,
|
||||||
is_declared_syncrhonized: false,
|
is_declared_syncrhonized: false,
|
||||||
|
annotations: vec![],
|
||||||
|
parameters_annotations: vec![],
|
||||||
code: (),
|
code: (),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,7 @@ pub struct AnnotationDirectoryItem {
|
||||||
pub field_annotations: Vec<FieldAnnotation>,
|
pub field_annotations: Vec<FieldAnnotation>,
|
||||||
/// List of method annotation. The method annotations must be sorted by
|
/// List of method annotation. The method annotations must be sorted by
|
||||||
/// increasing order of [`crate::MethodAnnotation.method_idx`].
|
/// 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
|
/// List of associated method parameter annotation. The parameter annotations
|
||||||
/// must be sorted by increasing order of [`crate::ParameterAnnotation.parameter_size`].
|
/// must be sorted by increasing order of [`crate::ParameterAnnotation.parameter_size`].
|
||||||
pub parameter_annotations: Vec<ParameterAnnotation>,
|
pub parameter_annotations: Vec<ParameterAnnotation>,
|
||||||
|
|
@ -32,7 +32,7 @@ impl AnnotationDirectoryItem {
|
||||||
self.field_annotations.len() as u32
|
self.field_annotations.len() as u32
|
||||||
}
|
}
|
||||||
pub fn annotated_methods_size_field(&self) -> 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 {
|
pub fn parameter_annotations_field(&self) -> u32 {
|
||||||
self.parameter_annotations.len() as u32
|
self.parameter_annotations.len() as u32
|
||||||
|
|
@ -49,7 +49,7 @@ impl Serializable for AnnotationDirectoryItem {
|
||||||
for item in &self.field_annotations {
|
for item in &self.field_annotations {
|
||||||
item.serialize(output)?;
|
item.serialize(output)?;
|
||||||
}
|
}
|
||||||
for item in &self.method_annotation {
|
for item in &self.method_annotations {
|
||||||
item.serialize(output)?;
|
item.serialize(output)?;
|
||||||
}
|
}
|
||||||
for item in &self.parameter_annotations {
|
for item in &self.parameter_annotations {
|
||||||
|
|
@ -66,9 +66,9 @@ impl Serializable for AnnotationDirectoryItem {
|
||||||
for _ in 0..fields_size {
|
for _ in 0..fields_size {
|
||||||
field_annotations.push(FieldAnnotation::deserialize(input)?);
|
field_annotations.push(FieldAnnotation::deserialize(input)?);
|
||||||
}
|
}
|
||||||
let mut method_annotation = vec![];
|
let mut method_annotations = vec![];
|
||||||
for _ in 0..annotated_methods_size {
|
for _ in 0..annotated_methods_size {
|
||||||
method_annotation.push(MethodAnnotation::deserialize(input)?);
|
method_annotations.push(MethodAnnotation::deserialize(input)?);
|
||||||
}
|
}
|
||||||
let mut parameter_annotations = vec![];
|
let mut parameter_annotations = vec![];
|
||||||
for _ in 0..annotated_parameters_size {
|
for _ in 0..annotated_parameters_size {
|
||||||
|
|
@ -78,7 +78,7 @@ impl Serializable for AnnotationDirectoryItem {
|
||||||
Ok(Self {
|
Ok(Self {
|
||||||
class_annotations_off,
|
class_annotations_off,
|
||||||
field_annotations,
|
field_annotations,
|
||||||
method_annotation,
|
method_annotations,
|
||||||
parameter_annotations,
|
parameter_annotations,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +93,7 @@ impl Serializable for AnnotationDirectoryItem {
|
||||||
.map(|val| val.size())
|
.map(|val| val.size())
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
+ self
|
+ self
|
||||||
.method_annotation
|
.method_annotations
|
||||||
.iter()
|
.iter()
|
||||||
.map(|val| val.size())
|
.map(|val| val.size())
|
||||||
.sum::<usize>()
|
.sum::<usize>()
|
||||||
|
|
@ -108,25 +108,28 @@ impl Serializable for AnnotationDirectoryItem {
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#field-annotation>
|
/// <https://source.android.com/docs/core/runtime/dex-format#field-annotation>
|
||||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct FieldAnnotation {
|
pub struct FieldAnnotation {
|
||||||
|
/// Index of the field annotated in `field_ids`
|
||||||
pub field_idx: u32,
|
pub field_idx: u32,
|
||||||
/// Offset to a [`AnnotationSetItem`]
|
/// Offset to a [`AnnotationSetItem`]
|
||||||
pub annotation_off: u32,
|
pub annotations_off: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#method-annotation>
|
/// <https://source.android.com/docs/core/runtime/dex-format#method-annotation>
|
||||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct MethodAnnotation {
|
pub struct MethodAnnotation {
|
||||||
|
/// Index of the method annotated in `method_ids`
|
||||||
pub method_idx: u32,
|
pub method_idx: u32,
|
||||||
/// Offset to a [`AnnotationSetItem`]
|
/// Offset to a [`AnnotationSetItem`]
|
||||||
pub annotation_off: u32,
|
pub annotations_off: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#parameter-annotation>
|
/// <https://source.android.com/docs/core/runtime/dex-format#parameter-annotation>
|
||||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct ParameterAnnotation {
|
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`]
|
/// Offset of a [`AnnotationSetRefList`]
|
||||||
pub annotation_off: u32,
|
pub annotations_off: u32,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <https://source.android.com/docs/core/runtime/dex-format#set-ref-list>
|
/// <https://source.android.com/docs/core/runtime/dex-format#set-ref-list>
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue