fix encoded value sign extention

This commit is contained in:
Jean-Marie Mineau 2024-02-07 17:31:09 +01:00
parent e950b77475
commit abe7fb6a50
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
2 changed files with 164 additions and 24 deletions

View file

@ -290,7 +290,7 @@ impl Serializable for EncodedValue {
})?; })?;
// Sign extention // Sign extention
if (buffer[size - 1] & 0b1000_0000) != 0 { 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; *b = 0xff;
} }
} }
@ -330,7 +330,7 @@ impl Serializable for EncodedValue {
})?; })?;
// Sign extention // Sign extention
if (buffer[size - 1] & 0b1000_0000) != 0 { 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; *b = 0xff;
} }
} }
@ -353,7 +353,7 @@ impl Serializable for EncodedValue {
})?; })?;
// Sign extention // Sign extention
if (buffer[size - 1] & 0b1000_0000) != 0 { 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; *b = 0xff;
} }
} }
@ -727,4 +727,139 @@ mod test {
.unwrap() .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),
);
}
} }

47
test.py
View file

@ -73,8 +73,8 @@ classes = list(
apk.classes.keys(), apk.classes.keys(),
) )
) )
for cls in classes: # for cls in classes:
apk.remove_class(cls) # apk.remove_class(cls)
print("[+] Recompile") print("[+] Recompile")
@ -140,13 +140,18 @@ def cmp_dict(a, b, req=0):
keys_b = set(b.keys()) keys_b = set(b.keys())
if keys_a != keys_b: if keys_a != keys_b:
print(f"{ident}a.keys() != b.keys()") print(f"{ident}a.keys() != b.keys()")
tot = 0
nb_failed = 0
for key in keys_a & keys_b: for key in keys_a & keys_b:
eq = a[key] == b[key] eq = a[key] == b[key]
print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}") tot += 1
if not eq: if not eq:
nb_failed += 1
print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}")
global last_id global last_id
last_id = key last_id = key
cmp(a[key], b[key], req + 1) 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): def cmp_list(a, b, req=0):
@ -180,21 +185,21 @@ if not apk_eq:
# nm = new_apk.classes[mid.class_].direct_methods[mid] # nm = new_apk.classes[mid.class_].direct_methods[mid]
mid = IdMethod( # mid = IdMethod(
"setValue", # "setValue",
IdMethodType( # IdMethodType(
IdType("Z"), # IdType("Z"),
[ # [
IdType("Ljava/lang/String;"), # IdType("Ljava/lang/String;"),
IdType("Landroidx/constraintlayout/core/parser/CLElement;"), # IdType("Landroidx/constraintlayout/core/parser/CLElement;"),
], # ],
), # ),
IdType("Landroidx/constraintlayout/core/state/WidgetFrame;"), # IdType("Landroidx/constraintlayout/core/state/WidgetFrame;"),
) # )
#
m = apk.classes[mid.class_].virtual_methods[mid] # m = apk.classes[mid.class_].virtual_methods[mid]
nm = new_apk.classes[mid.class_].virtual_methods[mid] # nm = new_apk.classes[mid.class_].virtual_methods[mid]
c = m.code # c = m.code
nc = nm.code # nc = nm.code
cc = c.with_normalized_labels() # cc = c.with_normalized_labels()
ncc = nc.with_normalized_labels() # ncc = nc.with_normalized_labels()