add hiddenapi item
This commit is contained in:
parent
b670649ed0
commit
b5ae8c5088
2 changed files with 143 additions and 0 deletions
141
androscalpel_serializer/src/items/hiddenapi.rs
Normal file
141
androscalpel_serializer/src/items/hiddenapi.rs
Normal file
|
|
@ -0,0 +1,141 @@
|
||||||
|
//! Hidden api items.
|
||||||
|
|
||||||
|
use crate as androscalpel_serializer;
|
||||||
|
use crate::{Error, ReadSeek, Result, Serializable, Uleb128};
|
||||||
|
use std::io::{Cursor, Write};
|
||||||
|
|
||||||
|
/// https://source.android.com/docs/core/runtime/dex-format#hiddenapi-class-data-item
|
||||||
|
/// Hard to serialize/deserialize without additional data like the number of classes
|
||||||
|
/// or the method/field of the classes.
|
||||||
|
#[derive(Clone, PartialEq, Eq)]
|
||||||
|
pub struct HiddenapiClassDataItem {
|
||||||
|
//pub size: u32,
|
||||||
|
pub data: Vec<u8>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl HiddenapiClassDataItem {
|
||||||
|
pub fn size_field(&self) -> u32 {
|
||||||
|
self.data.len() as u32
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return `hiddenapi_class_data_item.offsets[class_idx]`.
|
||||||
|
///
|
||||||
|
/// If `0`: Either no data for this class or all API flags are zero.
|
||||||
|
/// Else: offset from the begining of the [`HiddenapiClassDataItem`]
|
||||||
|
/// (including the size /!\).
|
||||||
|
///
|
||||||
|
/// # Warning
|
||||||
|
///
|
||||||
|
/// They are no check weither the `class_idx` is valid one or not.
|
||||||
|
/// Giving an invalid idx (like an idx >= nb class) is UB.
|
||||||
|
pub fn get_offset(&self, class_idx: u32) -> Result<u32> {
|
||||||
|
let index = (class_idx as usize) * 4;
|
||||||
|
if self.data.len() < index - 4 {
|
||||||
|
Err(Error::InconsistantStruct(format!(
|
||||||
|
"class index 0x{class_idx:x} out of bound of HiddenapiClassDataItem data"
|
||||||
|
)))
|
||||||
|
} else {
|
||||||
|
u32::deserialize_from_slice(&self.data[index..])
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return `hiddenapi_class_data_item.offsets`.
|
||||||
|
///
|
||||||
|
/// # Warning
|
||||||
|
///
|
||||||
|
/// They are no check weither the `nb_class` is valid one or not.
|
||||||
|
/// Giving an invalid `nb_class`.
|
||||||
|
pub fn get_offsets(&self, nb_class: u32) -> Result<Vec<u32>> {
|
||||||
|
let mut offsets = vec![];
|
||||||
|
let mut buffer = Cursor::new(self.data.as_slice());
|
||||||
|
for _ in 0..nb_class {
|
||||||
|
offsets.push(u32::deserialize(&mut buffer)?);
|
||||||
|
}
|
||||||
|
Ok(offsets)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get a list of `nb_flags` flags from the `offset`.
|
||||||
|
/// `nb_flags` should be the number of field + the number of method
|
||||||
|
/// of the class associated to `offset`.
|
||||||
|
///
|
||||||
|
/// # Warning
|
||||||
|
///
|
||||||
|
/// They are no check weither the `nb_flags` or `offset`
|
||||||
|
/// are valid. Providing invalid values is UB.
|
||||||
|
pub fn get_flags(&self, nb_flags: usize, offset: u32) -> Result<Vec<Uleb128>> {
|
||||||
|
if offset == 0 {
|
||||||
|
Ok(vec![Uleb128(0); nb_flags])
|
||||||
|
} else if offset < 4 {
|
||||||
|
// < 8 is almost certainly false
|
||||||
|
panic!()
|
||||||
|
} else {
|
||||||
|
let mut buffer = Cursor::new(self.data.as_slice());
|
||||||
|
let mut flags = vec![];
|
||||||
|
for _ in 0..nb_flags {
|
||||||
|
flags.push(Uleb128::deserialize(&mut buffer)?);
|
||||||
|
}
|
||||||
|
Ok(flags)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Serializable for HiddenapiClassDataItem {
|
||||||
|
fn serialize(&self, output: &mut dyn Write) -> Result<()> {
|
||||||
|
self.size_field().serialize(output)?;
|
||||||
|
for byte in &self.data {
|
||||||
|
byte.serialize(output)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deserialize(input: &mut dyn ReadSeek) -> Result<Self> {
|
||||||
|
let size = u32::deserialize(input)?;
|
||||||
|
let mut data = vec![];
|
||||||
|
for _ in 0..size {
|
||||||
|
data.push(u8::deserialize(input)?);
|
||||||
|
}
|
||||||
|
Ok(Self { data })
|
||||||
|
}
|
||||||
|
|
||||||
|
fn size(&self) -> usize {
|
||||||
|
self.size_field().size() + self.data.iter().map(|val| val.size()).sum::<usize>()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Flags for hidden api
|
||||||
|
#[derive(Serializable, Debug, PartialEq, Eq, Copy, Clone)]
|
||||||
|
#[prefix_type(Uleb128)]
|
||||||
|
pub enum HiddenApiFlag {
|
||||||
|
/// Interfaces that can be freely used and are supported as
|
||||||
|
/// part of the officially documented Android framework Package Index
|
||||||
|
#[prefix(Uleb128(0x00))]
|
||||||
|
Whitelist,
|
||||||
|
/// Non-SDK interfaces that can be used regardless of the
|
||||||
|
/// application's target API level
|
||||||
|
#[prefix(Uleb128(0x01))]
|
||||||
|
Greylist,
|
||||||
|
/// Non-SDK interfaces that cannot be used regardless of the
|
||||||
|
/// application's target API level. Accessing one of these
|
||||||
|
/// interfaces causes a runtime error.
|
||||||
|
#[prefix(Uleb128(0x02))]
|
||||||
|
Blacklist,
|
||||||
|
/// Non-SDK interfaces that can be used for Android 8.x and
|
||||||
|
/// below unless they are restricted.
|
||||||
|
#[prefix(Uleb128(0x03))]
|
||||||
|
GreylistMaxO,
|
||||||
|
/// Non-SDK interfaces that can be used for Android 9.x unless
|
||||||
|
/// they are restricted.
|
||||||
|
#[prefix(Uleb128(0x04))]
|
||||||
|
GreylistMaxP,
|
||||||
|
/// Non-SDK interfaces that can be used for Android 10.x unless
|
||||||
|
/// they are restricted.
|
||||||
|
#[prefix(Uleb128(0x05))]
|
||||||
|
GreylistMaxQ,
|
||||||
|
/// Non-SDK interfaces that can be used for Android 11.x unless
|
||||||
|
/// they are restricted.
|
||||||
|
#[prefix(Uleb128(0x06))]
|
||||||
|
GreylistMaxR,
|
||||||
|
/// Unknown flag, either an error or this crate is out of date.
|
||||||
|
#[default_variant]
|
||||||
|
Unknwon(Uleb128),
|
||||||
|
}
|
||||||
|
|
@ -6,11 +6,13 @@ use crate::{EncodedArray, Serializable};
|
||||||
pub mod class;
|
pub mod class;
|
||||||
pub mod code;
|
pub mod code;
|
||||||
pub mod header;
|
pub mod header;
|
||||||
|
pub mod hiddenapi;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
|
|
||||||
pub use class::*;
|
pub use class::*;
|
||||||
pub use code::*;
|
pub use code::*;
|
||||||
pub use header::*;
|
pub use header::*;
|
||||||
|
pub use hiddenapi::*;
|
||||||
pub use map::*;
|
pub use map::*;
|
||||||
|
|
||||||
/// https://source.android.com/docs/core/runtime/dex-format#string-item
|
/// https://source.android.com/docs/core/runtime/dex-format#string-item
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue