diff --git a/.gitignore b/.gitignore index a384fda..7c0dd26 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ *.dex *.idsig *.jks +/tests diff --git a/TODO.md b/TODO.md index a53f6fb..e5d08b5 100644 --- a/TODO.md +++ b/TODO.md @@ -2,3 +2,4 @@ - tests - https://source.android.com/docs/core/runtime/dex-format#system-annotation - goto size computation +- ord in python diff --git a/tests/dump_class_names.py b/tests/dump_class_names.py new file mode 100644 index 0000000..30661ee --- /dev/null +++ b/tests/dump_class_names.py @@ -0,0 +1,42 @@ +import logging + +FORMAT = "[%(levelname)s] %(name)s %(filename)s:%(lineno)d: %(message)s" +logging.basicConfig(format=FORMAT) +logging.getLogger().setLevel(logging.DEBUG) + +import json +import zipfile as z +import re +from pathlib import Path +import argparse + +from androscalpel import Apk, IdType, IdMethodType, ins, DexString, IdMethod, Code, utils # type: ignore + +RE_CHECK_DEXFILE = re.compile(r"classes\d*.dex") + + +def is_dexfile(filename: str) -> bool: + return bool(RE_CHECK_DEXFILE.fullmatch(filename)) + + +def load_apk(path_apk: Path) -> Apk: + print(f"[+] Load bytecode ") + apk = Apk() + with z.ZipFile(path_apk) as zipf: + for file in filter(is_dexfile, zipf.namelist()): + print(f"[-] {file}") + with zipf.open(file, "r") as dex_f: + dex = dex_f.read() + apk.add_dex_file(dex) + return apk + + +if __name__ == "__main__": + parser = argparse.ArgumentParser("Dump the name of classes defined in an apk") + parser.add_argument("apk", type=Path) + args = parser.parse_args() + apk = load_apk(args.apk) + cls = list(map(str, apk.classes.keys())) + cls.sort() + for cl in cls: + print(str(cl))