From d44e2b624b5326b845ca2e9182f04e84f454e947 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Wed, 23 Aug 2023 12:59:29 +0200 Subject: [PATCH] add some consts --- Cargo.lock | 8 +- androscalpel_serializer/src/constant.rs | 262 ++++++++++++++++++++++ androscalpel_serializer/src/core/leb.rs | 6 +- androscalpel_serializer/src/lib.rs | 2 + androscalpel_serializer_derive/src/lib.rs | 12 +- 5 files changed, 280 insertions(+), 10 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6bb036e..550ea9f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -30,18 +30,18 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.31" +version = "1.0.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5fe8a65d69dd0808184ebb5f836ab526bb259db23c657efa38711b1072ee47f0" +checksum = "5267fca4496028628a95160fc423a33e8b2e6af8a5302579e322e4b520293cae" dependencies = [ "proc-macro2", ] [[package]] name = "syn" -version = "2.0.27" +version = "2.0.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b60f673f44a8255b9c8c657daf66a596d435f2da81a555b06dc644d080ba45e0" +checksum = "c324c494eba9d92503e6f1ef2e6df781e78f6a7705a0202d9801b198807d518a" dependencies = [ "proc-macro2", "quote", diff --git a/androscalpel_serializer/src/constant.rs b/androscalpel_serializer/src/constant.rs index 23f4b3e..ed322fd 100644 --- a/androscalpel_serializer/src/constant.rs +++ b/androscalpel_serializer/src/constant.rs @@ -1,3 +1,265 @@ //! Constants definition +use crate as androscalpel_serializer; +use crate::core::Serializable; pub use androscalpel_serializer_derive::*; + +/// [dex-file-magic](https://source.android.com/docs/core/runtime/dex-format#dex-file-magic) +/// `version` is the Dex version of this file (encoded decimal digit). +#[derive(Serializable, PartialEq, Eq, Debug)] +pub struct DexFileMagic { + #[prefix([0x64, 0x65, 0x78, 0x0a])] + #[suffix([0x00])] + pub version: [u8; 3], +} + +/// [endian-constant](https://source.android.com/docs/core/runtime/dex-format#endian-constant) +/// +/// The only supported value as of 2023 is [`EndianConstant`] +/// ([because](https://cs.android.com/android/platform/superproject/main/+/main:art/libdexfile/dex/dex_file_verifier.cc;l=597;drc=397dd78fcdcfed36ee62302e2b90712e2d784364)) +#[derive(Serializable, PartialEq, Eq, Debug)] +#[prefix_type(u32)] +pub enum EndianConstant { + #[prefix(0x12345678)] + EndianConstant, + #[prefix(0x78563412)] + ReverseEndianConstant, +} + +/// [no-index](https://source.android.com/docs/core/runtime/dex-format#no-index) +pub const NO_INDEX: crate::Uleb128p1 = crate::Uleb128p1(0xFFFFFFFF); + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// public: visible everywhere +/// +/// # For Fields +/// +/// public: visible everywhere +/// +/// # For Methods +/// +/// public: visible everywhere +pub const ACC_PUBLIC: u32 = 0x1; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// private: only visible to defining class +/// +/// Only allowed on for `InnerClass` annotations, and must not ever be on in a `class_def_item` +/// +/// # For Fields +/// +/// private: only visible to defining class +/// +/// # For Methods +/// +/// private: only visible to defining class +pub const ACC_PRIVATE: u32 = 0x2; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// protected: visible to package and subclasses +/// +/// Only allowed on for `InnerClass` annotations, and must not ever be on in a `class_def_item` +/// +/// # For Fields +/// +/// protected: visible to package and subclasses +/// +/// # For Methods +/// +/// protected: visible to package and subclasses +pub const ACC_PROTECTED: u32 = 0x4; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// static: is not constructed with an outer this reference +/// +/// Only allowed on for `InnerClass` annotations, and must not ever be on in a `class_def_item` +/// +/// # For Fields +/// +/// static: global to defining class +/// +/// # For Methods +/// +/// static: does not take a this argument +pub const ACC_STATIC: u32 = 0x8; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// final: not subclassable +/// +/// # For Fields +/// +/// final: immutable after construction +/// +/// # For Methods +/// +/// final: not overridable +pub const ACC_FINAL: u32 = 0x10; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// synchronized: associated lock automatically acquired around call to this method. +/// +/// Note: This is only valid to set when ACC_NATIVE is also set. +pub const ACC_SYNCHRONIZED: u32 = 0x20; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Fields +/// +/// volatile: special access rules to help with thread safety +pub const ACC_VOLATILE: u32 = 0x40; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// bridge method, added automatically by compiler as a type-safe bridge +pub const ACC_BRIDGE: u32 = 0x40; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Fields +/// +/// transient: not to be saved by default serialization +pub const ACC_TRANSIENT: u32 = 0x80; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// last argument should be treated as a "rest" argument by compiler +pub const ACC_VARARGS: u32 = 0x80; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// native: implemented in native code +pub const ACC_NATIVE: u32 = 0x100; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// interface: multiply-implementable abstract class +pub const ACC_INTERFACE: u32 = 0x200; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// abstract: not directly instantiable +/// +/// # For Methods +/// +/// abstract: unimplemented by this class +pub const ACC_ABSTRACT: u32 = 0x400; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// strictfp: strict rules for floating-point arithmetic +pub const ACC_STRICT: u32 = 0x800; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// not directly defined in source code +/// +/// # For Fields +/// +/// not directly defined in source code +/// +/// # For Methods +/// +/// not directly defined in source code +pub const ACC_SYNTHETIC: u32 = 0x1000; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// declared as an annotation class +pub const ACC_ANNOTATION: u32 = 0x2000; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Classes / InnerClass annotation +/// +/// declared as an enumerated type +/// +/// # For Fields +/// +/// declared as an enumerated value +pub const ACC_ENUM: u32 = 0x4000; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// constructor method (class or instance initializer) +pub const ACC_CONSTRUCTOR: u32 = 0x10000; + +/// [access-flags](https://source.android.com/docs/core/runtime/dex-format#access-flags) +/// +/// # For Methods +/// +/// declared synchronized. +/// +/// Note: This has no effect on execution (other than in reflection of this flag, per se). +pub const ACC_DECLARED_SYNCHRONIZED: u32 = 0x20000; + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_dexfilemagic() { + assert_eq!( + DexFileMagic { + version: [b'0', b'3', b'9'] + } + .serialize_to_vec() + .unwrap(), + vec![0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x39, 0x00] + ); + assert_eq!( + DexFileMagic::deserialize_from_slice(&[0x64, 0x65, 0x78, 0x0a, 0x30, 0x33, 0x39, 0x00]) + .unwrap(), + DexFileMagic { + version: [b'0', b'3', b'9'] + } + ); + } + + #[test] + fn test_endianconstant() { + assert_eq!( + EndianConstant::EndianConstant.serialize_to_vec().unwrap(), + vec![0x12, 0x34, 0x56, 0x78] + ); + assert_eq!( + EndianConstant::deserialize_from_slice(&[0x12, 0x34, 0x56, 0x78]).unwrap(), + EndianConstant::EndianConstant + ); + } +} diff --git a/androscalpel_serializer/src/core/leb.rs b/androscalpel_serializer/src/core/leb.rs index 75ee847..348d816 100644 --- a/androscalpel_serializer/src/core/leb.rs +++ b/androscalpel_serializer/src/core/leb.rs @@ -6,15 +6,15 @@ use crate::{Error, ReadSeek, Result, Serializable}; /// Signed LEB128, variable-length #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Sleb128(i32); +pub struct Sleb128(pub i32); /// Unsigned LEB128, variable-length #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Uleb128(u32); +pub struct Uleb128(pub u32); /// Unsigned LEB128 plus 1, variable-length #[derive(Debug, Clone, PartialEq, Eq)] -pub struct Uleb128p1(u32); +pub struct Uleb128p1(pub u32); impl Sleb128 { fn get_serialized_bytes(&self) -> Vec { diff --git a/androscalpel_serializer/src/lib.rs b/androscalpel_serializer/src/lib.rs index 5ea5c63..b68d672 100644 --- a/androscalpel_serializer/src/lib.rs +++ b/androscalpel_serializer/src/lib.rs @@ -1,5 +1,7 @@ pub mod constant; pub mod core; +pub use androscalpel_serializer_derive::*; + pub use crate::core::*; pub use constant::*; diff --git a/androscalpel_serializer_derive/src/lib.rs b/androscalpel_serializer_derive/src/lib.rs index e41a2cb..bab4b98 100644 --- a/androscalpel_serializer_derive/src/lib.rs +++ b/androscalpel_serializer_derive/src/lib.rs @@ -42,6 +42,10 @@ use syn::{ /// ); /// ``` /// +/// ## Enum +/// +/// TODO +/// /// ## Prefix and suffix /// /// To define a constant prefix before a serialised field or suffixe after, use `#[prefix()]` @@ -74,10 +78,12 @@ pub fn derive_serializable(input: proc_macro::TokenStream) -> proc_macro::TokenS let implem_size = get_implem_size(&input.data, ¶ms); let expanded = quote! { impl androscalpel_serializer::Serializable for #name { + #[allow(clippy::single_element_loop)] fn serialize(&self, output: &mut dyn std::io::Write) -> androscalpel_serializer::Result<()> { #implem_serialize } + #[allow(clippy::single_element_loop)] fn deserialize(input: &mut dyn androscalpel_serializer::ReadSeek) -> androscalpel_serializer::Result { #implem_deserialize } @@ -175,7 +181,7 @@ impl ParamsStruct { Meta::List(MetaList { path, tokens, .. }) if path.is_ident("prefix_type") => { params.prefix_type = Some(syn::parse2(tokens.clone()).unwrap()); } - _ => unimplemented!(), + _ => (), } } params @@ -198,7 +204,7 @@ impl ParamsField { Meta::List(MetaList { path, .. }) if path.is_ident("prefix_type") => { panic!("Fields cannot take the attribut 'prefix_type'") } - _ => unimplemented!(), + _ => (), } } params @@ -218,7 +224,7 @@ impl ParamsVariant { Meta::List(MetaList { path, .. }) if path.is_ident("prefix_type") => { panic!("Variant cannot take the attribut 'prefix_type'") } - _ => unimplemented!(), + _ => (), } } params