diff --git a/frida/pyproject.toml b/frida/pyproject.toml index 1dfb7d6..3921e4f 100644 --- a/frida/pyproject.toml +++ b/frida/pyproject.toml @@ -3,7 +3,7 @@ name = "theseus-frida" version = "0.1.0" description = "" authors = [ - {name = "Jean-Marie Mineau",email = "jean-marie.mineau@inria.fr"} + {name = "Jean-Marie Mineau",email = "jean-marie.mineau@centralesupelec.fr"} ] readme = "README.md" requires-python = ">=3.13,<4.0.0" diff --git a/frida/theseus_frida/__init__.py b/frida/theseus_frida/__init__.py index 4837be8..7a264ec 100644 --- a/frida/theseus_frida/__init__.py +++ b/frida/theseus_frida/__init__.py @@ -12,6 +12,8 @@ import lzma from pathlib import Path from typing import TextIO, Any +from .app_exploration import explore_app + import frida # type: ignore from androguard.core.apk import get_apkid # type: ignore from loguru import logger # type: ignore @@ -76,6 +78,7 @@ def cl_id_to_string(classloader: int) -> str | None: def handle_classloader_data(data: dict, data_storage: dict): data["id"] = cl_id_to_string(data["id"]) data["parent_id"] = cl_id_to_string(data["parent_id"]) + print(f"[+] Got classloader {data['id']}({data['str']})") data_storage["classloaders"].append(data) @@ -363,21 +366,21 @@ def collect_runtime(apk: Path, device_name: str, file_storage: Path, output: Tex # Resume the execution of the APK device.resume(pid) - print("==> Press ENTER to end the analysis <==") - input() - # Dump all known classloaders - global CLASSLOADER_DONE - CLASSLOADER_DONE = False + # Don't wait for confirmation that all cl were sended + # global CLASSLOADER_DONE + # CLASSLOADER_DONE = False script.post({"type": "dump-class-loaders"}) - t = spinner() - while not CLASSLOADER_DONE: - print( - f"[{t.__next__()}] Waiting for the list of classloaders to be sent", - end="\r", - ) - time.sleep(0.3) - print(f"[*] Classloader list received" + " " * 20) + # t = spinner() + # while not CLASSLOADER_DONE: + # print( + # f"[{t.__next__()}] Waiting for the list of classloaders to be sent", + # end="\r", + # ) + # time.sleep(0.3) + # print(f"[*] Classloader list received" + " " * 20) + + explore_app() # Try to find the Main class loader main_class_loader: str | None = None diff --git a/frida/theseus_frida/app_exploration.py b/frida/theseus_frida/app_exploration.py new file mode 100644 index 0000000..d6ff862 --- /dev/null +++ b/frida/theseus_frida/app_exploration.py @@ -0,0 +1,7 @@ +def explore_app(): + manual_exploration() + + +def manual_exploration(): + print("==> Press ENTER to end the analysis <==") + input() diff --git a/frida/theseus_frida/hook.js b/frida/theseus_frida/hook.js index 1b463dd..e6f24fa 100644 --- a/frida/theseus_frida/hook.js +++ b/frida/theseus_frida/hook.js @@ -1,14 +1,26 @@ +const sended_class_loaders = new Set(); + +function send_class_loader(cl) { + const System = Java.use('java.lang.System'); + let cl_id = System.identityHashCode(cl); + while (cl != null && !sended_class_loaders.has(cl_id)) { + let parent_ = cl.getParent(); + send({"type": "classloader", "data": { + "id": cl_id, + "parent_id": System.identityHashCode(parent_), + "str": cl.toString(), + "cname": cl.$className + }}); + sended_class_loaders.add(cl_id); + cl = parent_; + } +} + function dump_classloaders() { Java.perform(() => { - const System = Java.use('java.lang.System'); var class_loader = Java.enumerateClassLoadersSync(); for (var cl of class_loader) { - send({"type": "classloader", "data": { - "id": System.identityHashCode(cl), - "parent_id": System.identityHashCode(cl.getParent()), - "str": cl.toString(), - "cname": cl.$className - }}); + send_class_loader(cl); } send({"type": "classloader-done"}) }); @@ -125,11 +137,13 @@ Java.perform(() => { var stack = stackConsumer.getStack() //send({"type": "stack", "data": stackConsumer.getStack()}); return stack.map((frame) => { + let cl = frame.getDeclaringClass().getClassLoader(); + send_class_loader(cl); return { "bytecode_index": frame.getByteCodeIndex(), "is_native": frame.isNativeMethod(), "method": frame.getDeclaringClass().descriptorString() + "->" + frame.getMethodName() + frame.getDescriptor(), - "cl_id": System.identityHashCode(frame.getDeclaringClass().getClassLoader()), + "cl_id": System.identityHashCode(cl), //{ //"descriptor": frame.getDescriptor(), //"name": frame.getMethodName(), @@ -170,11 +184,13 @@ Java.perform(() => { Method.invoke.overload( "java.lang.Object", "[Ljava.lang.Object;" // the Frida type parser is so cursted... ).implementation = function (obj, args) { + let cl = this.getDeclaringClass().getClassLoader(); + send_class_loader(cl); send({ "type": "invoke", "data": { "method": get_method_dsc(this), - "method_cl_id": System.identityHashCode(this.getDeclaringClass().getClassLoader()), + "method_cl_id": System.identityHashCode(cl), /*{ "name": this.getName(), "class": this.getDeclaringClass().getName(), @@ -193,11 +209,13 @@ Java.perform(() => { // Class.newInstance() Class.newInstance.overload( ).implementation = function () { + let cl = this.getClassLoader(); + send_class_loader(cl); send({ "type": "class-new-inst", "data": { "constructor": this.descriptorString() + "->()V", - "constructor_cl_id": System.identityHashCode(this.getClassLoader()), + "constructor_cl_id": System.identityHashCode(cl), /*{ "name": "", "class": this.getName(), @@ -215,11 +233,13 @@ Java.perform(() => { Constructor.newInstance.overload( "[Ljava.lang.Object;" ).implementation = function (args) { + let cl = this.getDeclaringClass().getClassLoader(); + send_class_loader(cl); send({ "type": "cnstr-new-isnt", "data": { "constructor": get_constr_dsc(this), - "constructor_cl_id": System.identityHashCode(this.getDeclaringClass().getClassLoader()), + "constructor_cl_id": System.identityHashCode(cl), /* { "name": "", @@ -262,6 +282,7 @@ Java.perform(() => { let classloader_class = null; let classloader_id = System.identityHashCode(loader); if (loader !== null) { + send_class_loader(loader); classloader_class = loader.getClass().descriptorString(); } send({ @@ -334,6 +355,7 @@ Java.perform(() => { let classloader_id = System.identityHashCode(loader); if (loader !== null) { classloader_class = loader.getClass().descriptorString(); + send_class_loader(loader); } send({ "type": "load-dex", diff --git a/theseus_autopatcher/pyproject.toml b/theseus_autopatcher/pyproject.toml index f21eb96..bc9d6a8 100644 --- a/theseus_autopatcher/pyproject.toml +++ b/theseus_autopatcher/pyproject.toml @@ -3,7 +3,7 @@ name = "theseus-autopatcher" version = "0.1.0" description = "" authors = [ - {name = "Jean-Marie 'Histausse' Mineau",email = "histausse@protonmail.com"} + {name = "Jean-Marie MINEAU",email = "jean-marie.mineau@centralesupelec.fr"} ] readme = "README.md" requires-python = ">=3.13,<4.0.0"