android_class_shadowing_sca.../android_class_shadowing_scanner/cmp_smali.py
Jean-Marie Mineau 7a83e118a3 update
2024-11-22 14:45:54 +01:00

62 lines
2.1 KiB
Python

def cmp_smali(sm1: str, sm2: str, sha256_1: str = "", sha256_2: str = "") -> bool:
meths_1 = get_methods(sm1, sha256_1)
meths_2 = get_methods(sm2, sha256_2)
if set(meths_1.keys()) != set(meths_2.keys()):
return False
for m in meths_1.keys():
s1 = meths_1[m]
s2 = meths_2[m]
if len(s1) > 1:
print(f"method {m} in {sha256_1} has multiple implementation")
if len(s2) > 1:
print(f"method {m} in {sha256_2} has multiple implementation")
for b1 in s1:
match = False
for b2 in s2:
if b1 == b2:
match = True
break
if not match:
return False
for b2 in s2:
match = False
for b1 in s1:
if b1 == b2:
match = True
break
if not match:
return False
return True
def get_methods(sm: str, sha256: str = "") -> dict[str, list[list[str]]]:
class_name = "UNINITIALIZED"
current_meth: None | str = None
current_body: list[str] = []
rest: dict[str, list[list[str]]] = {}
for line in sm.split("\n"):
striped = line.strip()
if striped.startswith(".class "):
class_name = striped.split(" ")[-1]
if striped == ".end method":
if current_meth is None:
print(f"ERROR PARSING SMALI of {class_name} {sha256}")
else:
if current_meth not in rest:
rest[current_meth] = []
rest[current_meth].append(current_body)
current_body = []
current_meth = None
if (
current_meth is not None
and striped
and not striped.startswith(".line ")
and not striped.startswith(".param ")
):
current_body.append(striped)
if striped.startswith(".method "):
if current_meth is not None:
print(f"ERROR PARSING SMALI of {class_name} {sha256}")
current_meth = striped.split(" ")[-1]
current_body = []
return rest