From abe7fb6a5093c9a04ae09e5960c3aa1978013c93 Mon Sep 17 00:00:00 2001 From: Jean-Marie Mineau Date: Wed, 7 Feb 2024 17:31:09 +0100 Subject: [PATCH] fix encoded value sign extention --- androscalpel_serializer/src/value.rs | 141 ++++++++++++++++++++++++++- test.py | 47 +++++---- 2 files changed, 164 insertions(+), 24 deletions(-) diff --git a/androscalpel_serializer/src/value.rs b/androscalpel_serializer/src/value.rs index 84a1e1a..05e88c8 100644 --- a/androscalpel_serializer/src/value.rs +++ b/androscalpel_serializer/src/value.rs @@ -290,7 +290,7 @@ impl Serializable for EncodedValue { })?; // Sign extention if (buffer[size - 1] & 0b1000_0000) != 0 { - for b in buffer.iter_mut().take(size) { + for b in buffer.iter_mut().skip(size) { *b = 0xff; } } @@ -330,7 +330,7 @@ impl Serializable for EncodedValue { })?; // Sign extention if (buffer[size - 1] & 0b1000_0000) != 0 { - for b in buffer.iter_mut().take(size) { + for b in buffer.iter_mut().skip(size) { *b = 0xff; } } @@ -353,7 +353,7 @@ impl Serializable for EncodedValue { })?; // Sign extention if (buffer[size - 1] & 0b1000_0000) != 0 { - for b in buffer.iter_mut().take(size) { + for b in buffer.iter_mut().skip(size) { *b = 0xff; } } @@ -727,4 +727,139 @@ mod test { .unwrap() ); } + + #[test] + fn long_serialize() { + assert_eq!( + vec![ + 0x06 | 7 << 5, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x80 + ], + EncodedValue::Long(-9223372036854775808) + .serialize_to_vec() + .unwrap(), + ); + assert_eq!( + vec![0x06 | 0 << 5, 0xff], + EncodedValue::Long(-1).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x06 | 0 << 5, 0x01], + EncodedValue::Long(1).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x06 | 1 << 5, 0x23, 0x01], + EncodedValue::Long(0x0123).serialize_to_vec().unwrap(), + ); + } + + #[test] + fn long_deserialize() { + assert_eq!( + EncodedValue::deserialize_from_slice(&[ + 0x06 | 7 << 5, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x00, + 0x80 + ]) + .unwrap(), + EncodedValue::Long(-9223372036854775808), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x06 | 0 << 5, 0xff]).unwrap(), + EncodedValue::Long(-1), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x06 | 0 << 5, 0x01]).unwrap(), + EncodedValue::Long(1), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x06 | 1 << 5, 0x23, 0x01]).unwrap(), + EncodedValue::Long(0x0123), + ); + } + + #[test] + fn short_serialize() { + assert_eq!( + vec![0x02 | 0 << 5, 0xff], + EncodedValue::Short(-1).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x02 | 0 << 5, 0x01], + EncodedValue::Short(1).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x02 | 1 << 5, 0x23, 0x01], + EncodedValue::Short(0x0123).serialize_to_vec().unwrap(), + ); + } + + #[test] + fn short_deserialize() { + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x02 | 0 << 5, 0xff]).unwrap(), + EncodedValue::Short(-1), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x02 | 0 << 5, 0x01]).unwrap(), + EncodedValue::Short(1), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x02 | 1 << 5, 0x23, 0x01]).unwrap(), + EncodedValue::Short(0x0123), + ); + } + + #[test] + fn int_serialize() { + assert_eq!( + vec![0x04 | 3 << 5, 0x00, 0x00, 0x00, 0x80], + EncodedValue::Int(-2147483648).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x04 | 0 << 5, 0xff], + EncodedValue::Int(-1).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x04 | 0 << 5, 0x01], + EncodedValue::Int(1).serialize_to_vec().unwrap(), + ); + assert_eq!( + vec![0x04 | 1 << 5, 0x23, 0x01], + EncodedValue::Int(0x0123).serialize_to_vec().unwrap(), + ); + } + + #[test] + fn int_deserialize() { + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x04 | 3 << 5, 0x00, 0x00, 0x00, 0x80]).unwrap(), + EncodedValue::Int(-2147483648), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x04 | 0 << 5, 0xff]).unwrap(), + EncodedValue::Int(-1), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x04 | 0 << 5, 0x01]).unwrap(), + EncodedValue::Int(1), + ); + assert_eq!( + EncodedValue::deserialize_from_slice(&[0x04 | 1 << 5, 0x23, 0x01]).unwrap(), + EncodedValue::Int(0x0123), + ); + } } diff --git a/test.py b/test.py index 9deb1cf..05a5504 100644 --- a/test.py +++ b/test.py @@ -73,8 +73,8 @@ classes = list( apk.classes.keys(), ) ) -for cls in classes: - apk.remove_class(cls) +# for cls in classes: +# apk.remove_class(cls) print("[+] Recompile") @@ -140,13 +140,18 @@ def cmp_dict(a, b, req=0): keys_b = set(b.keys()) if keys_a != keys_b: print(f"{ident}a.keys() != b.keys()") + tot = 0 + nb_failed = 0 for key in keys_a & keys_b: eq = a[key] == b[key] - print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}") + tot += 1 if not eq: + nb_failed += 1 + print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}") global last_id last_id = key cmp(a[key], b[key], req + 1) + print(f"\033[32m{tot-nb_failed}\033[0m + \033[31m{nb_failed}\033[0m = {tot}") def cmp_list(a, b, req=0): @@ -180,21 +185,21 @@ if not apk_eq: # nm = new_apk.classes[mid.class_].direct_methods[mid] -mid = IdMethod( - "setValue", - IdMethodType( - IdType("Z"), - [ - IdType("Ljava/lang/String;"), - IdType("Landroidx/constraintlayout/core/parser/CLElement;"), - ], - ), - IdType("Landroidx/constraintlayout/core/state/WidgetFrame;"), -) - -m = apk.classes[mid.class_].virtual_methods[mid] -nm = new_apk.classes[mid.class_].virtual_methods[mid] -c = m.code -nc = nm.code -cc = c.with_normalized_labels() -ncc = nc.with_normalized_labels() +# mid = IdMethod( +# "setValue", +# IdMethodType( +# IdType("Z"), +# [ +# IdType("Ljava/lang/String;"), +# IdType("Landroidx/constraintlayout/core/parser/CLElement;"), +# ], +# ), +# IdType("Landroidx/constraintlayout/core/state/WidgetFrame;"), +# ) +# +# m = apk.classes[mid.class_].virtual_methods[mid] +# nm = new_apk.classes[mid.class_].virtual_methods[mid] +# c = m.code +# nc = nm.code +# cc = c.with_normalized_labels() +# ncc = nc.with_normalized_labels()