collect classloaders on the fly
This commit is contained in:
parent
b86bf08229
commit
ba02e70dcc
5 changed files with 58 additions and 26 deletions
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
7
frida/theseus_frida/app_exploration.py
Normal file
7
frida/theseus_frida/app_exploration.py
Normal file
|
|
@ -0,0 +1,7 @@
|
|||
def explore_app():
|
||||
manual_exploration()
|
||||
|
||||
|
||||
def manual_exploration():
|
||||
print("==> Press ENTER to end the analysis <==")
|
||||
input()
|
||||
|
|
@ -1,14 +1,26 @@
|
|||
function dump_classloaders() {
|
||||
Java.perform(() => {
|
||||
const sended_class_loaders = new Set();
|
||||
|
||||
function send_class_loader(cl) {
|
||||
const System = Java.use('java.lang.System');
|
||||
var class_loader = Java.enumerateClassLoadersSync();
|
||||
for (var cl of class_loader) {
|
||||
let cl_id = System.identityHashCode(cl);
|
||||
while (cl != null && !sended_class_loaders.has(cl_id)) {
|
||||
let parent_ = cl.getParent();
|
||||
send({"type": "classloader", "data": {
|
||||
"id": System.identityHashCode(cl),
|
||||
"parent_id": System.identityHashCode(cl.getParent()),
|
||||
"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(() => {
|
||||
var class_loader = Java.enumerateClassLoadersSync();
|
||||
for (var cl of class_loader) {
|
||||
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() + "-><init>()V",
|
||||
"constructor_cl_id": System.identityHashCode(this.getClassLoader()),
|
||||
"constructor_cl_id": System.identityHashCode(cl),
|
||||
/*{
|
||||
"name": "<init>",
|
||||
"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": "<init>",
|
||||
|
|
@ -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",
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue