catch when nb method ids > 2^16
This commit is contained in:
parent
0b430fe187
commit
ed8c584647
3 changed files with 89 additions and 32 deletions
|
|
@ -185,8 +185,6 @@ impl DexWriter {
|
|||
.filter(|ty| self.type_ids.get(ty).is_none())
|
||||
.count();
|
||||
if new_nb_types >= u16::MAX as usize {
|
||||
// type_ids are not always u16, so this may not be a hard limit,
|
||||
// but it's easier to enforce it to avoid strange bugs.
|
||||
// TODO return structured error to handle this case by generating multiple dex files
|
||||
bail!("To many types for one dex file");
|
||||
}
|
||||
|
|
@ -203,8 +201,26 @@ impl DexWriter {
|
|||
}
|
||||
|
||||
let new_field_ids = class.get_all_field_ids();
|
||||
let new_nb_field_ids = self.field_ids.len()
|
||||
+ new_field_ids
|
||||
.iter()
|
||||
.filter(|field| self.field_ids.get(field).is_none())
|
||||
.count();
|
||||
if new_nb_field_ids >= u16::MAX as usize {
|
||||
// TODO return structured error to handle this case by generating multiple dex files
|
||||
bail!("To many field ids for one dex file");
|
||||
}
|
||||
|
||||
let new_method_ids = class.get_all_method_ids();
|
||||
let new_nb_method_ids = self.method_ids.len()
|
||||
+ new_method_ids
|
||||
.iter()
|
||||
.filter(|meth| self.method_ids.get(meth).is_none())
|
||||
.count();
|
||||
if new_nb_method_ids >= u16::MAX as usize {
|
||||
// TODO return structured error to handle this case by generating multiple dex files
|
||||
bail!("To many method ids for one dex file");
|
||||
}
|
||||
|
||||
for string in new_strings {
|
||||
self.strings.insert(string, 0);
|
||||
|
|
@ -1161,7 +1177,12 @@ impl DexWriter {
|
|||
meth.class_.__repr__(),
|
||||
method_id.__repr__()
|
||||
))?;
|
||||
let ins = ins.get_raw_ins(*meth_idx);
|
||||
debug_assert!(
|
||||
*meth_idx <= u16::MAX as usize,
|
||||
"methode id too big for invoke instruction"
|
||||
);
|
||||
let meth_idx = *meth_idx as u16;
|
||||
let ins = ins.get_raw_ins(meth_idx);
|
||||
addr += ins.size() / 2;
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
@ -1173,7 +1194,12 @@ impl DexWriter {
|
|||
meth.class_.__repr__(),
|
||||
method_id.__repr__()
|
||||
))?;
|
||||
let ins = ins.get_raw_ins(*meth_idx);
|
||||
debug_assert!(
|
||||
*meth_idx <= u16::MAX as usize,
|
||||
"methode id too big for invoke instruction"
|
||||
);
|
||||
let meth_idx = *meth_idx as u16;
|
||||
let ins = ins.get_raw_ins(meth_idx);
|
||||
addr += ins.size() / 2;
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
@ -1185,7 +1211,12 @@ impl DexWriter {
|
|||
meth.class_.__repr__(),
|
||||
method_id.__repr__()
|
||||
))?;
|
||||
let ins = ins.get_raw_ins(*meth_idx);
|
||||
debug_assert!(
|
||||
*meth_idx <= u16::MAX as usize,
|
||||
"methode id too big for invoke instruction"
|
||||
);
|
||||
let meth_idx = *meth_idx as u16;
|
||||
let ins = ins.get_raw_ins(meth_idx);
|
||||
addr += ins.size() / 2;
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
@ -1197,7 +1228,12 @@ impl DexWriter {
|
|||
meth.class_.__repr__(),
|
||||
method_id.__repr__()
|
||||
))?;
|
||||
let ins = ins.get_raw_ins(*meth_idx);
|
||||
debug_assert!(
|
||||
*meth_idx <= u16::MAX as usize,
|
||||
"methode id too big for invoke instruction"
|
||||
);
|
||||
let meth_idx = *meth_idx as u16;
|
||||
let ins = ins.get_raw_ins(meth_idx);
|
||||
addr += ins.size() / 2;
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
@ -1209,7 +1245,12 @@ impl DexWriter {
|
|||
meth.class_.__repr__(),
|
||||
method_id.__repr__()
|
||||
))?;
|
||||
let ins = ins.get_raw_ins(*meth_idx);
|
||||
debug_assert!(
|
||||
*meth_idx <= u16::MAX as usize,
|
||||
"methode id too big for invoke instruction"
|
||||
);
|
||||
let meth_idx = *meth_idx as u16;
|
||||
let ins = ins.get_raw_ins(meth_idx);
|
||||
addr += ins.size() / 2;
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
@ -1226,7 +1267,17 @@ impl DexWriter {
|
|||
ins.proto.__repr__(),
|
||||
method_id.__repr__()
|
||||
))?;
|
||||
let ins = ins.get_raw_ins(*meth_idx, *proto_idx);
|
||||
debug_assert!(
|
||||
*meth_idx <= u16::MAX as usize,
|
||||
"methode id too big for invoke instruction"
|
||||
);
|
||||
debug_assert!(
|
||||
*proto_idx <= u16::MAX as usize,
|
||||
"proto id too big for invoke instruction"
|
||||
);
|
||||
let meth_idx = *meth_idx as u16;
|
||||
let proto_idx = *proto_idx as u16;
|
||||
let ins = ins.get_raw_ins(meth_idx, proto_idx);
|
||||
addr += ins.size() / 2;
|
||||
insns.push(ins);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14863,7 +14863,7 @@ impl InvokeVirtual {
|
|||
/// Return the raw instruction ([`InsFormat`]).
|
||||
///
|
||||
/// `method_idx` is the index of the refered method.
|
||||
pub fn get_raw_ins(&self, meth_idx: usize) -> InsFormat {
|
||||
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
|
||||
let mut last = None;
|
||||
let mut first = None;
|
||||
let mut consec = true;
|
||||
|
|
@ -14916,7 +14916,7 @@ impl InvokeVirtual {
|
|||
op: 0x74,
|
||||
a,
|
||||
vc,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else {
|
||||
// Not supposed to happend with a sanitized invoke
|
||||
|
|
@ -15083,7 +15083,7 @@ impl InvokeSuper {
|
|||
/// Return the raw instruction ([`InsFormat`]).
|
||||
///
|
||||
/// `method_idx` is the index of the refered method.
|
||||
pub fn get_raw_ins(&self, meth_idx: usize) -> InsFormat {
|
||||
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
|
||||
let mut last = None;
|
||||
let mut first = None;
|
||||
let mut consec = true;
|
||||
|
|
@ -15127,7 +15127,7 @@ impl InvokeSuper {
|
|||
vd,
|
||||
vf,
|
||||
vg,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else if consec && len <= 255 {
|
||||
let a = self.args.len() as u8;
|
||||
|
|
@ -15136,7 +15136,7 @@ impl InvokeSuper {
|
|||
op: 0x75,
|
||||
a,
|
||||
vc,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else {
|
||||
// Not supposed to happend with a sanitized invoke
|
||||
|
|
@ -15303,7 +15303,7 @@ impl InvokeDirect {
|
|||
/// Return the raw instruction ([`InsFormat`]).
|
||||
///
|
||||
/// `method_idx` is the index of the refered method.
|
||||
pub fn get_raw_ins(&self, meth_idx: usize) -> InsFormat {
|
||||
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
|
||||
let mut last = None;
|
||||
let mut first = None;
|
||||
let mut consec = true;
|
||||
|
|
@ -15347,7 +15347,7 @@ impl InvokeDirect {
|
|||
vd,
|
||||
vf,
|
||||
vg,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else if consec && len <= 255 {
|
||||
let a = self.args.len() as u8;
|
||||
|
|
@ -15356,7 +15356,7 @@ impl InvokeDirect {
|
|||
op: 0x76,
|
||||
a,
|
||||
vc,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else {
|
||||
// Not supposed to happend with a sanitized invoke
|
||||
|
|
@ -15523,7 +15523,7 @@ impl InvokeStatic {
|
|||
/// Return the raw instruction ([`InsFormat`]).
|
||||
///
|
||||
/// `method_idx` is the index of the refered method.
|
||||
pub fn get_raw_ins(&self, meth_idx: usize) -> InsFormat {
|
||||
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
|
||||
let mut last = None;
|
||||
let mut first = None;
|
||||
let mut consec = true;
|
||||
|
|
@ -15567,7 +15567,7 @@ impl InvokeStatic {
|
|||
vd,
|
||||
vf,
|
||||
vg,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else if consec && len <= 255 {
|
||||
let a = self.args.len() as u8;
|
||||
|
|
@ -15576,7 +15576,7 @@ impl InvokeStatic {
|
|||
op: 0x77,
|
||||
a,
|
||||
vc,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else {
|
||||
// Not supposed to happend with a sanitized invoke
|
||||
|
|
@ -15743,7 +15743,7 @@ impl InvokeInterface {
|
|||
/// Return the raw instruction ([`InsFormat`]).
|
||||
///
|
||||
/// `method_idx` is the index of the refered method.
|
||||
pub fn get_raw_ins(&self, meth_idx: usize) -> InsFormat {
|
||||
pub fn get_raw_ins(&self, meth_idx: u16) -> InsFormat {
|
||||
let mut last = None;
|
||||
let mut first = None;
|
||||
let mut consec = true;
|
||||
|
|
@ -15787,7 +15787,7 @@ impl InvokeInterface {
|
|||
vd,
|
||||
vf,
|
||||
vg,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else if consec && len <= 255 {
|
||||
let a = self.args.len() as u8;
|
||||
|
|
@ -15796,7 +15796,7 @@ impl InvokeInterface {
|
|||
op: 0x78,
|
||||
a,
|
||||
vc,
|
||||
b: meth_idx as u16,
|
||||
b: meth_idx,
|
||||
}
|
||||
} else {
|
||||
// Not supposed to happend with a sanitized invoke
|
||||
|
|
@ -28356,7 +28356,7 @@ impl InvokePolymorphic {
|
|||
///
|
||||
/// - `method_idx` is the index of the refered method.
|
||||
/// - `proto_idx` is the index of the protoype used.
|
||||
pub fn get_raw_ins(&self, meth_idx: usize, proto_idx: usize) -> InsFormat {
|
||||
pub fn get_raw_ins(&self, meth_idx: u16, proto_idx: u16) -> InsFormat {
|
||||
let mut last = None;
|
||||
let mut first = None;
|
||||
let mut consec = true;
|
||||
|
|
@ -28400,8 +28400,8 @@ impl InvokePolymorphic {
|
|||
vd,
|
||||
vf,
|
||||
vg,
|
||||
b: meth_idx as u16,
|
||||
h: proto_idx as u16,
|
||||
b: meth_idx,
|
||||
h: proto_idx,
|
||||
}
|
||||
} else if consec && len <= 255 {
|
||||
let a = self.args.len() as u8;
|
||||
|
|
@ -28410,8 +28410,8 @@ impl InvokePolymorphic {
|
|||
op: 0xfb,
|
||||
a,
|
||||
vc,
|
||||
b: meth_idx as u16,
|
||||
h: proto_idx as u16,
|
||||
b: meth_idx,
|
||||
h: proto_idx,
|
||||
}
|
||||
} else {
|
||||
// Not supposed to happend with a sanitized invoke
|
||||
|
|
|
|||
|
|
@ -2,7 +2,8 @@ import logging
|
|||
|
||||
FORMAT = "[%(levelname)s] %(name)s %(filename)s:%(lineno)d: %(message)s"
|
||||
logging.basicConfig(format=FORMAT)
|
||||
logging.getLogger().setLevel(logging.DEBUG)
|
||||
# logging.getLogger().setLevel(logging.DEBUG)
|
||||
logging.getLogger().setLevel(logging.WARNING)
|
||||
|
||||
import json
|
||||
import zipfile as z
|
||||
|
|
@ -207,8 +208,8 @@ def cmp_other(a, b, req=0):
|
|||
len(f) < 2 or f[:2] != "__"
|
||||
):
|
||||
eq = getattr(a, f) == getattr(b, f)
|
||||
print(f"{f'{ident}{f}: ':<150}{nice_bool(eq)}")
|
||||
if not eq:
|
||||
print(f"{f'{ident}{f}: ':<150}{nice_bool(eq)}")
|
||||
if "descriptor" in dir(a):
|
||||
global last_id
|
||||
last_id = a.descriptor
|
||||
|
|
@ -227,8 +228,8 @@ def cmp_dict(a, b, req=0):
|
|||
eq = a[key] == b[key]
|
||||
tot += 1
|
||||
if not eq:
|
||||
nb_failed += 1
|
||||
print(f"{f'{ident}{str(key)}: ':<150}{nice_bool(eq)}")
|
||||
nb_failed += 1
|
||||
global last_id
|
||||
last_id = key
|
||||
cmp(a[key], b[key], req + 1)
|
||||
|
|
@ -243,8 +244,8 @@ 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}{nice_bool(eq)}")
|
||||
if not eq:
|
||||
print(f"{f'{ident}{str(i)}: ':<150}{nice_bool(eq)}")
|
||||
print(f"{ident}: {str(a[i])} != {str(b[i])}")
|
||||
cmp(a[i], b[i], req + 1)
|
||||
|
||||
|
|
@ -252,7 +253,9 @@ def cmp_list(a, b, req=0):
|
|||
instrumented_apk = Apk()
|
||||
instrumented_apk.add_dex_file(dex_raw[0])
|
||||
|
||||
cmp(instrumented_apk, dyn_load_apk)
|
||||
print("wtf?")
|
||||
|
||||
# cmp(instrumented_apk, dyn_load_apk)
|
||||
|
||||
MAX_REQ = 5
|
||||
|
||||
|
|
@ -330,3 +333,6 @@ for ty in tys:
|
|||
instrumented_apk.classes[ty],
|
||||
dyn_load_apk.classes[ty],
|
||||
)
|
||||
|
||||
# direct: Landroidx/compose/foundation/layout/IntrinsicSize;->values()[Landroidx/compose/foundation/layout/IntrinsicSize;
|
||||
# insns[3]: Landroidx/compose/foundation/layout/IntrinsicSize;->values()[Landroidx/compose/foundation/layout/IntrinsicSize;:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue