From fcfe2dc6e9e58662308e89a6c73e81dcd56aa9c6 Mon Sep 17 00:00:00 2001 From: Jean-Marie 'Histausse' Mineau Date: Tue, 6 Feb 2024 19:37:12 +0100 Subject: [PATCH] fix sleb serializer --- androscalpel/src/hashmap_vectorize.rs | 2 +- androscalpel_serializer/src/core/leb.rs | 11 +++--- androscalpel_serializer/src/core/string.rs | 4 +-- androscalpel_serializer/src/debug.rs | 39 ++++++++++++++++++++++ test.py | 35 +++++++++++-------- 5 files changed, 70 insertions(+), 21 deletions(-) diff --git a/androscalpel/src/hashmap_vectorize.rs b/androscalpel/src/hashmap_vectorize.rs index a2666ab..13db7ae 100644 --- a/androscalpel/src/hashmap_vectorize.rs +++ b/androscalpel/src/hashmap_vectorize.rs @@ -19,5 +19,5 @@ where V: Deserialize<'de>, { let container: Vec<_> = serde::Deserialize::deserialize(des)?; - Ok(T::from_iter(container.into_iter())) + Ok(T::from_iter(container)) } diff --git a/androscalpel_serializer/src/core/leb.rs b/androscalpel_serializer/src/core/leb.rs index eab6121..eff1081 100644 --- a/androscalpel_serializer/src/core/leb.rs +++ b/androscalpel_serializer/src/core/leb.rs @@ -23,12 +23,10 @@ impl Sleb128 { let mut bytes = vec![]; loop { let byte = val as u8 & 0b0111_1111; - val /= 64; - if val == 0 || val == -1 { + val >>= 7; + if (val == 0 && (byte & 0b0100_0000) == 0) || (val == -1 && (byte & 0b0100_0000) != 0) { bytes.push(byte); return bytes; - } else { - val /= 2; } bytes.push(byte | 0b1000_0000); } @@ -202,6 +200,7 @@ mod test { assert_eq!(Sleb128(0).serialize_to_vec().unwrap(), vec![0x00u8]); assert_eq!(Sleb128(1).serialize_to_vec().unwrap(), vec![0x01u8]); assert_eq!(Sleb128(-1).serialize_to_vec().unwrap(), vec![0x7Fu8]); + assert_eq!(Sleb128(-1551).serialize_to_vec().unwrap(), vec![0xf1, 0x73]); assert_eq!( Sleb128(-128).serialize_to_vec().unwrap(), vec![0x80u8, 0x7F] @@ -222,6 +221,10 @@ mod test { Sleb128::deserialize_from_slice(&[0x7Fu8]).unwrap(), Sleb128(-1) ); + assert_eq!( + Sleb128::deserialize_from_slice(&[0xf1, 0x73]).unwrap(), + Sleb128(-1551) + ); assert_eq!( Sleb128::deserialize_from_slice(&[0x80u8, 0x7Fu8]).unwrap(), Sleb128(-128) diff --git a/androscalpel_serializer/src/core/string.rs b/androscalpel_serializer/src/core/string.rs index e15ddf0..fb520a4 100644 --- a/androscalpel_serializer/src/core/string.rs +++ b/androscalpel_serializer/src/core/string.rs @@ -44,9 +44,7 @@ impl Ord for StringDataItem { impl PartialOrd for StringDataItem { fn partial_cmp(&self, other: &Self) -> Option { - self.data - .partial_cmp(&other.data) - .map(|ord| ord.then(self.utf16_size.cmp(&other.utf16_size))) + Some(self.cmp(other)) } } diff --git a/androscalpel_serializer/src/debug.rs b/androscalpel_serializer/src/debug.rs index 4b4cec6..488cb02 100644 --- a/androscalpel_serializer/src/debug.rs +++ b/androscalpel_serializer/src/debug.rs @@ -92,3 +92,42 @@ impl Serializable for DebugInfoItem { + self.bytecode.size(DbgBytecode::EndSequence) } } + +#[cfg(test)] +mod test { + use super::DbgBytecode::*; + use super::*; + + #[test] + fn test_debug_reserialize() { + let debug = DebugInfoItem { + line_start: Uleb128(2902), + parameter_names: vec![], + bytecode: vec![ + SpecialOpcode(14), + AdvanceLine { + line_diff: Sleb128(-1551), + }, + AdvancePC { + addr_diff: Uleb128(51), + }, + SpecialOpcode(14), + ], + }; + assert_eq!( + debug, + DebugInfoItem::deserialize_from_slice(&debug.serialize_to_vec().unwrap()).unwrap() + ); + } + + #[test] + fn test_advance_line_reserialize() { + let advance_line = AdvanceLine { + line_diff: Sleb128(-1551), + }; + assert_eq!( + advance_line, + DbgBytecode::deserialize_from_slice(&advance_line.serialize_to_vec().unwrap()).unwrap() + ); + } +} diff --git a/test.py b/test.py index 968582c..cb3417a 100644 --- a/test.py +++ b/test.py @@ -106,12 +106,19 @@ def cmp(a, b, req=0): cmp_other(a, b, req) +def nice_bool(b) -> str: + if b: + return "\033[32mTrue\033[0m" + else: + return "\033[31mFalse\033[0m" + + def cmp_other(a, b, req=0): ident = " " * req for f in dir(a): if getattr(getattr(a, f), "__call__", None) is None: eq = getattr(a, f) == getattr(b, f) - print(f"{f'{ident}{f}: ':<150}{eq}") + print(f"{f'{ident}{f}: ':<150}{nice_bool(eq)}") if not eq: cmp(getattr(a, f), getattr(b, f), req + 1) @@ -124,7 +131,7 @@ def cmp_dict(a, b, req=0): print(f"{ident}a.keys() != b.keys()") for key in keys_a & keys_b: eq = a[key] == b[key] - print(f"{f'{ident}{str(key)}: ':<150}{eq}") + print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}") if not eq: cmp(a[key], b[key], req + 1) @@ -137,7 +144,7 @@ def cmp_list(a, b, req=0): print(f"{ident}len(a) != len(b)") for i in range(min(la, lb)): eq = a[i] == b[i] - print(f"{f'{ident}{str(i)}: ':<150}{eq}") + print(f"{f'{ident}{str(i)}: ':<150}{nice_bool(eq)}") if not eq: cmp(a[i], b[i], req + 1) @@ -147,13 +154,15 @@ print(f"apk are equals: {apk_eq}") if not apk_eq: cmp(new_apk, apk) -mid = IdMethod( - "setAction", - IdMethodType( - IdType("Landroidx/navigation/NavDeepLink$Builder;"), - [IdType("Ljava/lang/String;")], - ), - IdType("Landroidx/navigation/NavDeepLink$Builder;"), -) -m = apk.classes[mid.class_].virtual_methods[mid] -nm = new_apk.classes[mid.class_].virtual_methods[mid] +# Landroidx/constraintlayout/core/widgets/ConstraintWidget$1;.()V +# mid = IdMethod( +# "", +# IdMethodType( +# IdType.void(), +# [], +# ), +# IdType("Landroidx/constraintlayout/core/widgets/ConstraintWidget$1;"), +# ) +# m = apk.classes[mid.class_].direct_methods[mid] +# nm = new_apk.classes[mid.class_].direct_methods[mid] +#