add annotation item
This commit is contained in:
parent
70e552339d
commit
b670649ed0
2 changed files with 235 additions and 0 deletions
235
androscalpel_serializer/src/annotation/mod.rs
Normal file
235
androscalpel_serializer/src/annotation/mod.rs
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
//! Annotation items.
|
||||
|
||||
pub mod encoded_annotation;
|
||||
pub use encoded_annotation::*;
|
||||
|
||||
use crate as androscalpel_serializer;
|
||||
use crate::{ReadSeek, Result, Serializable};
|
||||
use std::io::Write;
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#referenced-from-class_def_item_1
|
||||
/// alignment: 4 bytes
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AnnotationDirectoryItem {
|
||||
/// 0 if they are no annotation, else offset of an [`AnnotationSetItem`].
|
||||
pub class_annotations_off: u32,
|
||||
// pub fields_size: u32,
|
||||
// pub annotated_methods_size: u32,
|
||||
// pub annotated_parameters_size: u32,
|
||||
/// List of field annotation. The field annotations must be sorted by
|
||||
/// increasing order of [`FieldAnnotation.field_idx`].
|
||||
pub field_annotations: Vec<FieldAnnotation>,
|
||||
/// List of method annotation. The method annotations must be sorted by
|
||||
/// increasing order of [`MethodAnnotation.method_idx`].
|
||||
pub method_annotation: Vec<MethodAnnotation>,
|
||||
/// List of associated method parameter annotation. The parameter annotations
|
||||
/// must be sorted by increasing order of [`ParameterAnnotation.parameter_size`].
|
||||
pub parameter_annotations: Vec<ParameterAnnotation>,
|
||||
}
|
||||
|
||||
impl AnnotationDirectoryItem {
|
||||
pub fn fields_size_field(&self) -> u32 {
|
||||
self.field_annotations.len() as u32
|
||||
}
|
||||
pub fn annotated_methods_size_field(&self) -> u32 {
|
||||
self.method_annotation.len() as u32
|
||||
}
|
||||
pub fn parameter_annotations_field(&self) -> u32 {
|
||||
self.parameter_annotations.len() as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl Serializable for AnnotationDirectoryItem {
|
||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||
self.class_annotations_off.serialize(output)?;
|
||||
self.fields_size_field().serialize(output)?;
|
||||
self.annotated_methods_size_field().serialize(output)?;
|
||||
self.parameter_annotations_field().serialize(output)?;
|
||||
|
||||
for item in &self.field_annotations {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
for item in &self.method_annotation {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
for item in &self.parameter_annotations {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
let class_annotations_off = u32::deserialize(input)?;
|
||||
let fields_size = u32::deserialize(input)?;
|
||||
let annotated_methods_size = u32::deserialize(input)?;
|
||||
let annotated_parameters_size = u32::deserialize(input)?;
|
||||
let mut field_annotations = vec![];
|
||||
for _ in 0..fields_size {
|
||||
field_annotations.push(FieldAnnotation::deserialize(input)?);
|
||||
}
|
||||
let mut method_annotation = vec![];
|
||||
for _ in 0..annotated_methods_size {
|
||||
method_annotation.push(MethodAnnotation::deserialize(input)?);
|
||||
}
|
||||
let mut parameter_annotations = vec![];
|
||||
for _ in 0..annotated_parameters_size {
|
||||
parameter_annotations.push(ParameterAnnotation::deserialize(input)?);
|
||||
}
|
||||
|
||||
Ok(Self {
|
||||
class_annotations_off,
|
||||
field_annotations,
|
||||
method_annotation,
|
||||
parameter_annotations,
|
||||
})
|
||||
}
|
||||
fn size(&self) -> usize {
|
||||
self.class_annotations_off.size()
|
||||
+ self.fields_size_field().size()
|
||||
+ self.annotated_methods_size_field().size()
|
||||
+ self.parameter_annotations_field().size()
|
||||
+ self
|
||||
.field_annotations
|
||||
.iter()
|
||||
.map(|val| val.size())
|
||||
.sum::<usize>()
|
||||
+ self
|
||||
.method_annotation
|
||||
.iter()
|
||||
.map(|val| val.size())
|
||||
.sum::<usize>()
|
||||
+ self
|
||||
.parameter_annotations
|
||||
.iter()
|
||||
.map(|val| val.size())
|
||||
.sum::<usize>()
|
||||
}
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#field-annotation
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct FieldAnnotation {
|
||||
pub field_idx: u32,
|
||||
/// Offset to a [`AnnotationSetItem`]
|
||||
pub annotation_off: u32,
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#method-annotation
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct MethodAnnotation {
|
||||
pub method_idx: u32,
|
||||
/// Offset to a [`AnnotationSetItem`]
|
||||
pub annotation_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,
|
||||
/// Offset of a [`AnnotationSetRefList`]
|
||||
pub annotation_off: u32,
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#set-ref-list
|
||||
/// alignment: 4 bytes
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AnnotationSetRefList {
|
||||
// pub size: u32,
|
||||
pub list: Vec<AnnotationSetRefItem>,
|
||||
}
|
||||
|
||||
impl AnnotationSetRefList {
|
||||
pub fn size_field(&self) -> u32 {
|
||||
self.list.len() as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl Serializable for AnnotationSetRefList {
|
||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||
self.size_field().serialize(output)?;
|
||||
for item in &self.list {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
let size = u32::deserialize(input)?;
|
||||
let mut list = vec![];
|
||||
for _ in 0..size {
|
||||
list.push(AnnotationSetRefItem::deserialize(input)?);
|
||||
}
|
||||
Ok(Self { list })
|
||||
}
|
||||
fn size(&self) -> usize {
|
||||
self.size_field().size() + self.list.iter().map(|val| val.size()).sum::<usize>()
|
||||
}
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#set-ref-item
|
||||
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct AnnotationSetRefItem {
|
||||
/// 0 if there are no annotation, offset to a [`AnnotationSetItem`] else.
|
||||
pub annotations_off: u32,
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#annotation-set-item
|
||||
/// alignment: 4
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AnnotationSetItem {
|
||||
// pub size: u32,
|
||||
/// Must be sorted by increasing [`AnnotationOffItem.type_idx`].
|
||||
pub entries: Vec<AnnotationOffItem>,
|
||||
}
|
||||
|
||||
impl AnnotationSetItem {
|
||||
pub fn size_field(&self) -> u32 {
|
||||
self.entries.len() as u32
|
||||
}
|
||||
}
|
||||
|
||||
impl Serializable for AnnotationSetItem {
|
||||
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||
self.size_field().serialize(output)?;
|
||||
for item in &self.entries {
|
||||
item.serialize(output)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||
let size = u32::deserialize(input)?;
|
||||
let mut entries = vec![];
|
||||
for _ in 0..size {
|
||||
entries.push(AnnotationOffItem::deserialize(input)?);
|
||||
}
|
||||
Ok(Self { entries })
|
||||
}
|
||||
fn size(&self) -> usize {
|
||||
self.size_field().size() + self.entries.iter().map(|val| val.size()).sum::<usize>()
|
||||
}
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#off-item
|
||||
#[derive(Serializable, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
pub struct AnnotationOffItem {
|
||||
/// Offset to a [`AnnotationItem`]
|
||||
pub annotation_off: u32,
|
||||
}
|
||||
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#annotation-item
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
pub struct AnnotationItem {
|
||||
pub visibility: AnnotationVisibility,
|
||||
pub annotation: EncodedAnnotation,
|
||||
}
|
||||
|
||||
// TODO: Enum or flags ?
|
||||
/// https://source.android.com/docs/core/runtime/dex-format#annotation-item
|
||||
#[derive(Serializable, Debug, Clone, PartialEq, Eq)]
|
||||
#[prefix_type(u8)]
|
||||
pub enum AnnotationVisibility {
|
||||
#[prefix(0x00)]
|
||||
Build,
|
||||
#[prefix(0x01)]
|
||||
Runtime,
|
||||
#[prefix(0x02)]
|
||||
System,
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue