diff --git a/Cargo.lock b/Cargo.lock index 419f5ee..84c38ef 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,13 +2,29 @@ # It is not intended for manual editing. version = 3 +[[package]] +name = "addr2line" +version = "0.21.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8a30b2e23b9e17a9f90641c7ab1549cd9b44f296d3ccbf309d2863cfe398a0cb" +dependencies = [ + "gimli", +] + +[[package]] +name = "adler" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" + [[package]] name = "androscalpel" version = "0.1.0" dependencies = [ "androscalpel_serializer", + "anyhow", "log", - "pyo3", + "pyo3 0.20.0", "pyo3-log", ] @@ -27,7 +43,16 @@ dependencies = [ "androscalpel_serializer", "proc-macro2", "quote", - "syn 2.0.29", + "syn", +] + +[[package]] +name = "anyhow" +version = "1.0.75" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +dependencies = [ + "backtrace", ] [[package]] @@ -42,12 +67,36 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" +[[package]] +name = "backtrace" +version = "0.3.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2089b7e3f35b9dd2d0ed921ead4f6d318c27680d4a5bd167b3ee120edb105837" +dependencies = [ + "addr2line", + "cc", + "cfg-if", + "libc", + "miniz_oxide", + "object", + "rustc-demangle", +] + [[package]] name = "bitflags" version = "1.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" +[[package]] +name = "cc" +version = "1.0.83" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1174fb0b6ec23863f8b971027804a42614e347eafb0a95bf0b12cdae21fc4d0" +dependencies = [ + "libc", +] + [[package]] name = "cfg-if" version = "1.0.0" @@ -55,10 +104,31 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] -name = "indoc" -version = "1.0.9" +name = "gimli" +version = "0.28.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" +checksum = "4271d37baee1b8c7e4b708028c57d816cf9d2434acb33a549475f78c181f6253" + +[[package]] +name = "heck" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" + +[[package]] +name = "indoc" +version = "2.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1e186cfbae8084e513daff4240b4797e342f988cecda4fb6c939150f96315fd8" + +[[package]] +name = "instant" +version = "0.1.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c" +dependencies = [ + "cfg-if", +] [[package]] name = "libc" @@ -82,6 +152,12 @@ version = "0.4.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b5e6163cb8c49088c2c36f57875e58ccd8c87c7427f7fbd50ea6710b2f3f2e8f" +[[package]] +name = "memchr" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" + [[package]] name = "memoffset" version = "0.9.0" @@ -91,12 +167,41 @@ dependencies = [ "autocfg", ] +[[package]] +name = "miniz_oxide" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +dependencies = [ + "adler", +] + +[[package]] +name = "object" +version = "0.32.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" +dependencies = [ + "memchr", +] + [[package]] name = "once_cell" version = "1.18.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dd8b5dd2ae5ed71462c540258bedcb51965123ad7e7ccf4b9a8cafaa4a63576d" +[[package]] +name = "parking_lot" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99" +dependencies = [ + "instant", + "lock_api", + "parking_lot_core 0.8.6", +] + [[package]] name = "parking_lot" version = "0.12.1" @@ -104,7 +209,21 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" dependencies = [ "lock_api", - "parking_lot_core", + "parking_lot_core 0.9.8", +] + +[[package]] +name = "parking_lot_core" +version = "0.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "60a2cfe6f0ad2bfc16aefa463b497d5c7a5ecd44a23efa72aa342d90177356dc" +dependencies = [ + "cfg-if", + "instant", + "libc", + "redox_syscall 0.2.16", + "smallvec", + "winapi", ] [[package]] @@ -115,7 +234,7 @@ checksum = "93f00c865fe7cabf650081affecd3871070f26767e7b2070a3ffae14c654b447" dependencies = [ "cfg-if", "libc", - "redox_syscall", + "redox_syscall 0.3.5", "smallvec", "windows-targets", ] @@ -131,16 +250,29 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.19.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" +checksum = "35100f9347670a566a67aa623369293703322bb9db77d99d7df7313b575ae0c8" dependencies = [ + "cfg-if", + "libc", + "parking_lot 0.11.2", + "pyo3-build-config 0.14.5", +] + +[[package]] +name = "pyo3" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04e8453b658fe480c3e70c8ed4e3d3ec33eb74988bd186561b0cc66b85c3bc4b" +dependencies = [ + "anyhow", "cfg-if", "indoc", "libc", "memoffset", - "parking_lot", - "pyo3-build-config", + "parking_lot 0.12.1", + "pyo3-build-config 0.20.0", "pyo3-ffi", "pyo3-macros", "unindent", @@ -148,9 +280,18 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.19.2" +version = "0.14.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" +checksum = "d12961738cacbd7f91b7c43bc25cfeeaa2698ad07a04b3be0aa88b950865738f" +dependencies = [ + "once_cell", +] + +[[package]] +name = "pyo3-build-config" +version = "0.20.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a96fe70b176a89cff78f2fa7b3c930081e163d5379b4dcdf993e3ae29ca662e5" dependencies = [ "once_cell", "target-lexicon", @@ -158,12 +299,12 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" +checksum = "214929900fd25e6604661ed9cf349727c8920d47deff196c4e28165a6ef2a96b" dependencies = [ "libc", - "pyo3-build-config", + "pyo3-build-config 0.20.0", ] [[package]] @@ -174,30 +315,31 @@ checksum = "f47b0777feb17f61eea78667d61103758b243a871edc09a7786500a50467b605" dependencies = [ "arc-swap", "log", - "pyo3", + "pyo3 0.14.5", ] [[package]] name = "pyo3-macros" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" +checksum = "dac53072f717aa1bfa4db832b39de8c875b7c7af4f4a6fe93cdbf9264cf8383b" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "pyo3-macros-backend" -version = "0.19.2" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" +checksum = "7774b5a8282bd4f25f803b1f0d945120be959a36c72e08e7cd031c792fdfd424" dependencies = [ + "heck", "proc-macro2", "quote", - "syn 1.0.109", + "syn", ] [[package]] @@ -209,6 +351,15 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "redox_syscall" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" +dependencies = [ + "bitflags", +] + [[package]] name = "redox_syscall" version = "0.3.5" @@ -218,6 +369,12 @@ dependencies = [ "bitflags", ] +[[package]] +name = "rustc-demangle" +version = "0.1.23" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d626bb9dae77e28219937af045c257c28bfd3f69333c512553507f5f9798cb76" + [[package]] name = "scopeguard" version = "1.2.0" @@ -230,17 +387,6 @@ version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62bb4feee49fdd9f707ef802e22365a35de4b7b299de4763d44bfea899442ff9" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.29" @@ -266,9 +412,31 @@ checksum = "301abaae475aa91687eb82514b328ab47a211a533026cb25fc3e519b86adfc3c" [[package]] name = "unindent" -version = "0.1.11" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" + +[[package]] +name = "winapi" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" +dependencies = [ + "winapi-i686-pc-windows-gnu", + "winapi-x86_64-pc-windows-gnu", +] + +[[package]] +name = "winapi-i686-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" + +[[package]] +name = "winapi-x86_64-pc-windows-gnu" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" [[package]] name = "windows-targets" diff --git a/androscalpel/Cargo.toml b/androscalpel/Cargo.toml index 841d100..08d42d9 100644 --- a/androscalpel/Cargo.toml +++ b/androscalpel/Cargo.toml @@ -10,6 +10,7 @@ crate-type = ["cdylib"] [dependencies] androscalpel_serializer = { version = "0.1.0", path = "../androscalpel_serializer" } +anyhow = { version = "1.0.75", features = ["backtrace"] } log = "0.4.20" -pyo3 = "0.19.0" +pyo3 = { version = "0.20.0", features = ["anyhow"] } pyo3-log = "0.8.3" diff --git a/androscalpel/src/apk.rs b/androscalpel/src/apk.rs index e15e512..be7ae30 100644 --- a/androscalpel/src/apk.rs +++ b/androscalpel/src/apk.rs @@ -1,5 +1,6 @@ //! Representation of an apk. +use anyhow::{anyhow, Result}; use std::collections::HashMap; use log::info; @@ -8,10 +9,6 @@ use pyo3::prelude::*; use crate::*; use androscalpel_serializer::*; -// Prioritize Results from this crate -use crate::Error; -use crate::Result; - /// Represent an apk. #[pyclass] #[derive(Debug, Clone)] @@ -124,14 +121,14 @@ impl Apk { .get_struct_at_offset::(class_item.static_values_off)? .values; if values.len() > static_fields.len() { - return Err(Error::InconsistantStruct(format!( + return Err(anyhow!( "Inconsistant static_values array found in {}: \ |static_values| = {}, |static_fields| = {}, \ |static_values| should be <= |static_fields|", <&DexString as Into>::into(&name), values.len(), static_fields.len() - ))); + )); } for (i, value) in values.iter().enumerate() { static_fields[i].value = Some(Self::encoded_value_to_dex_value(value, dex)?); @@ -210,11 +207,14 @@ impl Apk { let parameters: Vec = if proto.parameters_off == 0 { vec![] } else { - dex.get_struct_at_offset::(proto.parameters_off)? + let mut parameters = vec![]; + for ty in dex + .get_struct_at_offset::(proto.parameters_off)? .list - .iter() - .map(|ty| Self::get_id_type_from_idx(ty.type_idx as usize, dex).clone()) - .collect::>()? + { + parameters.push(Self::get_id_type_from_idx(ty.type_idx as usize, dex)?); + } + parameters }; Ok(IdMethodType { shorty, @@ -372,10 +372,10 @@ impl Apk { (pbl, prv, prt) => { let class: String = descriptor.class_.0.into(); let name: String = descriptor.name.into(); - return Err(Error::InconsistantStruct(format!( + return Err(anyhow!( "Inconsistant visiblity found in {class}.{name}: \ (public: {pbl}, private: {prv}, protected: {prt})" - ))); + )); } }; if access_flags @@ -474,11 +474,11 @@ impl Apk { (false, false, true) => MethodVisibility::Protected, (false, false, false) => MethodVisibility::None_, (pbl, prv, prt) => { - return Err(Error::InconsistantStruct(format!( + return Err(anyhow!( "Inconsistant visiblity found in {}: \ (public: {pbl}, private: {prv}, protected: {prt})", descriptor.__repr__() - ))); + )); // TODO: replace by public? } }; diff --git a/androscalpel/src/dex_id.rs b/androscalpel/src/dex_id.rs index f709581..3aaefb0 100644 --- a/androscalpel/src/dex_id.rs +++ b/androscalpel/src/dex_id.rs @@ -1,8 +1,9 @@ //! The class identifying dex structure. +use anyhow::anyhow; use pyo3::prelude::*; -use crate::{DexString, Error, Result}; +use crate::{DexString, Result}; use androscalpel_serializer::{StringDataItem, Uleb128}; #[pyclass] @@ -289,9 +290,7 @@ impl IdType { Ok(()) } else { let format: String = (&self.0).into(); - Err(Error::InconsistantStruct(format!( - "{format} is not a valid type" - ))) + Err(anyhow!("{format} is not a valid type")) } } diff --git a/androscalpel/src/lib.rs b/androscalpel/src/lib.rs index a3d0356..895364f 100644 --- a/androscalpel/src/lib.rs +++ b/androscalpel/src/lib.rs @@ -1,5 +1,6 @@ +use anyhow::Result; + use pyo3::class::basic::CompareOp; -use pyo3::exceptions::PyValueError; use pyo3::prelude::*; pub mod annotation; @@ -22,62 +23,6 @@ pub use method_handle::*; pub use scalar::*; pub use value::*; -#[derive(Debug, Clone)] -pub enum Error { - InputTooSmall(String), - SerializationError(String), - DeserializationError(String), - InvalidStringEncoding(String), - InconsistantStruct(String), -} - -impl From for Error { - fn from(error: androscalpel_serializer::Error) -> Self { - match error { - androscalpel_serializer::Error::InputTooSmall(err) => Self::InputTooSmall(err), - androscalpel_serializer::Error::SerializationError(err) => { - Self::SerializationError(err) - } - androscalpel_serializer::Error::DeserializationError(err) => { - Self::DeserializationError(err) - } - androscalpel_serializer::Error::InvalidStringEncoding(err) => { - Self::InvalidStringEncoding(err) - } - androscalpel_serializer::Error::InconsistantStruct(err) => { - Self::InconsistantStruct(err) - } - } - } -} - -impl std::fmt::Display for Error { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Self::InputTooSmall(msg) => write!(f, "InputTooSmall: {}", msg), - Self::SerializationError(msg) => write!(f, "SerializationError: {}", msg), - Self::DeserializationError(msg) => write!(f, "DeserializationError: {}", msg), - Self::InvalidStringEncoding(msg) => write!(f, "InvalidStringEncoding: {}", msg), - Self::InconsistantStruct(msg) => write!(f, "InconsistantStruct: {}", msg), - } - } -} -impl std::error::Error for Error {} - -impl From for PyErr { - fn from(error: Error) -> Self { - match error { - Error::InputTooSmall(err) => PyValueError::new_err(err.to_string()), - Error::SerializationError(err) => PyValueError::new_err(err.to_string()), - Error::DeserializationError(err) => PyValueError::new_err(err.to_string()), - Error::InvalidStringEncoding(err) => PyValueError::new_err(err.to_string()), - Error::InconsistantStruct(err) => PyValueError::new_err(err.to_string()), - } - } -} - -pub type Result = core::result::Result; - #[pyclass] #[derive(Clone, PartialEq, Eq, Debug)] pub struct DexString(androscalpel_serializer::StringDataItem); diff --git a/androscalpel_serializer/src/annotation/encoded_annotation.rs b/androscalpel_serializer/src/annotation/encoded_annotation.rs index fd5add6..5763da1 100644 --- a/androscalpel_serializer/src/annotation/encoded_annotation.rs +++ b/androscalpel_serializer/src/annotation/encoded_annotation.rs @@ -78,4 +78,108 @@ impl Serializable for EncodedAnnotation { } } -// TODO: add tests +// TODO: add more tests +#[cfg(test)] +mod test { + use super::*; + + const ENCODED_ANNOTATION_RAW: &[u8] = &[ + 0xbe, 0x37, 0x01, 0xa8, 0x9f, 0x03, 0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f, + ]; + const ENCODED_ANNOTATION_RAW_2: &[u8] = &[0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f]; + const ANNOTATION_ELEMENT_RAW: &[u8] = &[ + 0xa8, 0x9f, 0x03, 0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f, + ]; + const ENCODED_VALUE_RAW: &[u8] = &[0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f]; + + #[test] + fn deserialize_encoded_annotation() { + assert_eq!( + EncodedAnnotation::deserialize_from_slice(ENCODED_ANNOTATION_RAW_2).unwrap(), + EncodedAnnotation { + type_idx: Uleb128(6646), + elements: vec![AnnotationElement { + name_idx: Uleb128(46163), + value: EncodedValue::Boolean(true) + }], + } + ); + assert_eq!( + EncodedAnnotation::deserialize_from_slice(ENCODED_ANNOTATION_RAW).unwrap(), + EncodedAnnotation { + type_idx: Uleb128(7102), + elements: vec![AnnotationElement { + name_idx: Uleb128(53160), + value: EncodedValue::Annotation(EncodedAnnotation { + type_idx: Uleb128(6646), + elements: vec![AnnotationElement { + name_idx: Uleb128(46163), + value: EncodedValue::Boolean(true) + }] + }) + }], + } + ); + } + + #[test] + fn serialize_encoded_annotation() { + assert_eq!( + ENCODED_ANNOTATION_RAW_2, + EncodedAnnotation { + type_idx: Uleb128(6646), + elements: vec![AnnotationElement { + name_idx: Uleb128(46163), + value: EncodedValue::Boolean(true) + }], + } + .serialize_to_vec() + .unwrap() + .as_slice() + ); + assert_eq!( + ENCODED_ANNOTATION_RAW, + EncodedAnnotation { + type_idx: Uleb128(7102), + elements: vec![AnnotationElement { + name_idx: Uleb128(53160), + value: EncodedValue::Annotation(EncodedAnnotation { + type_idx: Uleb128(6646), + elements: vec![AnnotationElement { + name_idx: Uleb128(46163), + value: EncodedValue::Boolean(true) + }] + }) + }], + } + .serialize_to_vec() + .unwrap() + .as_slice() + ); + } + + #[test] + fn deserialize_annotation_element() { + assert_eq!( + AnnotationElement::deserialize_from_slice(ANNOTATION_ELEMENT_RAW).unwrap(), + AnnotationElement { + name_idx: Uleb128(53160), + value: EncodedValue::deserialize_from_slice(ENCODED_VALUE_RAW).unwrap(), + } + ); + } + + #[test] + fn serialize_annotation_element() { + assert_eq!( + ANNOTATION_ELEMENT_RAW, + AnnotationElement { + name_idx: Uleb128(53160), + value: EncodedValue::deserialize_from_slice(ENCODED_VALUE_RAW).unwrap(), + } + .serialize_to_vec() + .unwrap() + .as_slice(), + ); + } +} diff --git a/androscalpel_serializer/src/annotation/mod.rs b/androscalpel_serializer/src/annotation/mod.rs index 578a57a..96e8fae 100644 --- a/androscalpel_serializer/src/annotation/mod.rs +++ b/androscalpel_serializer/src/annotation/mod.rs @@ -233,3 +233,39 @@ pub enum AnnotationVisibility { #[prefix(0x02)] System, } + +#[cfg(test)] +mod test { + use super::*; + + const ANNOTATION_ITEM: &[u8] = &[ + 0x02, 0xbe, 0x37, 0x01, 0xa8, 0x9f, 0x03, 0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f, + ]; + + #[test] + fn deserialize_annotation_item() { + assert_eq!( + AnnotationItem::deserialize_from_slice(ANNOTATION_ITEM).unwrap(), + AnnotationItem { + visibility: AnnotationVisibility::System, + annotation: EncodedAnnotation::deserialize_from_slice(&ANNOTATION_ITEM[1..]) + .unwrap(), + } + ); + } + + #[test] + fn serialize_annotation_item() { + assert_eq!( + ANNOTATION_ITEM, + AnnotationItem { + visibility: AnnotationVisibility::System, + annotation: EncodedAnnotation::deserialize_from_slice(&ANNOTATION_ITEM[1..]) + .unwrap(), + } + .serialize_to_vec() + .unwrap() + .as_slice() + ); + } +} diff --git a/androscalpel_serializer/src/file_reader.rs b/androscalpel_serializer/src/file_reader.rs index a1e1933..6bdd453 100644 --- a/androscalpel_serializer/src/file_reader.rs +++ b/androscalpel_serializer/src/file_reader.rs @@ -197,7 +197,7 @@ impl<'a> DexFileReader<'a> { fn sanity_check(&self) -> Result<()> { if self.header.magic.version != [0x30, 0x33, 0x39] { warn!( - "DEX 039 is the only verion currently supported, found {}", + "DEX 039 is the only version currently supported, found {}", std::str::from_utf8(self.header.magic.version.as_slice()) .unwrap_or(&format!("{:x?}", self.header.magic.version)) ); diff --git a/androscalpel_serializer/src/value.rs b/androscalpel_serializer/src/value.rs index 2119759..87c27a7 100644 --- a/androscalpel_serializer/src/value.rs +++ b/androscalpel_serializer/src/value.rs @@ -539,7 +539,7 @@ impl Serializable for EncodedValue { "Unexpected value argument 0x{arg:02x}: expected 0 for VALUE_ANNOTATION" ))) } else { - Ok(Self::Array(EncodedArray::deserialize(input)?)) + Ok(Self::Annotation(EncodedAnnotation::deserialize(input)?)) } } VALUE_NULL => { @@ -681,6 +681,7 @@ impl Serializable for Idx { #[cfg(test)] mod test { use super::*; + use crate::*; #[test] fn boolean_deserialize() { @@ -706,4 +707,35 @@ mod test { vec![0b0011_1111] ); } + + #[test] + fn annotation_deserialize() { + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f]) + .unwrap(), + EncodedValue::Annotation(EncodedAnnotation { + type_idx: Uleb128(6646), + elements: vec![AnnotationElement { + name_idx: Uleb128(46163), + value: EncodedValue::Boolean(true) + }] + }) + ); + } + + #[test] + fn annotation_serialize() { + assert_eq!( + vec![0x1d, 0xf6, 0x33, 0x01, 0xd3, 0xe8, 0x02, 0x3f], + EncodedValue::Annotation(EncodedAnnotation { + type_idx: Uleb128(6646), + elements: vec![AnnotationElement { + name_idx: Uleb128(46163), + value: EncodedValue::Boolean(true) + }] + }) + .serialize_to_vec() + .unwrap() + ); + } } diff --git a/test.sh b/test.sh index 2063d57..6cf2f2f 100755 --- a/test.sh +++ b/test.sh @@ -1,6 +1,7 @@ #!/usr/bin/env sh source venv_maturin/bin/activate +export RUST_BACKTRACE=full cd androscalpel maturin develop cd ..