wip
This commit is contained in:
parent
edd15fce67
commit
bd725ba91b
9 changed files with 187 additions and 67 deletions
|
|
@ -59,7 +59,9 @@ def print_stack(stack, prefix: str):
|
|||
print(f" {prefix}{frame['method']}:{frame['bytecode_index']}{native}")
|
||||
|
||||
|
||||
def cl_id_to_string(classloader: int) -> str:
|
||||
def cl_id_to_string(classloader: int) -> str | None:
|
||||
if classloader == 0: # 0 is the hash of java Null
|
||||
return None
|
||||
if classloader < 0:
|
||||
classloader += 2 << (HASH_NB_BYTES * 8 - 1)
|
||||
return classloader.to_bytes(HASH_NB_BYTES).hex()
|
||||
|
|
@ -67,7 +69,8 @@ def cl_id_to_string(classloader: int) -> str:
|
|||
|
||||
def handle_classloader_data(data: dict, data_storage: dict):
|
||||
data["id"] = cl_id_to_string(data["id"])
|
||||
data_storage["initial_classloaders"].append(data)
|
||||
data["parent_id"] = cl_id_to_string(data["parent_id"])
|
||||
data_storage["classloaders"].append(data)
|
||||
|
||||
|
||||
def handle_invoke_data(data, data_storage: dict):
|
||||
|
|
@ -184,6 +187,7 @@ def handle_load_dex(data, data_storage: dict, file_storage: Path):
|
|||
dex = data["dex"]
|
||||
classloader_class = data["classloader_class"]
|
||||
classloader = cl_id_to_string(data["classloader"])
|
||||
classloader_parent = cl_id_to_string(data["classloader_parent"])
|
||||
short_class = classloader_class.split("/")[-1].removesuffix(";")
|
||||
files = []
|
||||
print("[+] DEX file loaded:")
|
||||
|
|
@ -212,6 +216,7 @@ def handle_load_dex(data, data_storage: dict, file_storage: Path):
|
|||
"classloader_class": classloader_class,
|
||||
"classloader": classloader,
|
||||
"files": files,
|
||||
"classloader_parent": classloader_parent,
|
||||
}
|
||||
)
|
||||
|
||||
|
|
@ -344,7 +349,7 @@ def collect_runtime(apk: Path, device_name: str, file_storage: Path, output: Tex
|
|||
"class_new_inst_data": [],
|
||||
"cnstr_new_inst_data": [],
|
||||
"dyn_code_load": [],
|
||||
"initial_classloaders": [],
|
||||
"classloaders": [],
|
||||
}
|
||||
|
||||
script.on(
|
||||
|
|
@ -357,10 +362,13 @@ def collect_runtime(apk: Path, device_name: str, file_storage: Path, output: Tex
|
|||
# Resume the execution of the APK
|
||||
device.resume(pid)
|
||||
|
||||
script.post({"type": "dump-class-loaders"})
|
||||
print("==> Press ENTER to finish the analysis <==")
|
||||
input()
|
||||
|
||||
# Try to find the Main class loader
|
||||
main_class_loader: str | None = None
|
||||
cls = {d["id"]: d for d in data_storage["initial_classloaders"]}
|
||||
cls = {d["id"]: d for d in data_storage["classloaders"]}
|
||||
for load_data in data_storage["dyn_code_load"]:
|
||||
if load_data["classloader"] in cls:
|
||||
del cls[load_data["classloader"]]
|
||||
|
|
@ -393,6 +401,10 @@ def collect_runtime(apk: Path, device_name: str, file_storage: Path, output: Tex
|
|||
main_class_loader = list(cls.keys())[0]
|
||||
data_storage["apk_cl_id"] = main_class_loader
|
||||
|
||||
# Dump all known classloaders
|
||||
script.post({"type": "dump-class-loaders"})
|
||||
time.sleep(1) # TODO: wait for ack from frida
|
||||
|
||||
json.dump(data_storage, output, indent=" ")
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,20 @@
|
|||
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
|
||||
}});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
recv('dump-class-loaders', function onMessage(msg) {dump_classloaders()});
|
||||
|
||||
Java.perform(() => {
|
||||
|
||||
/*
|
||||
|
|
@ -15,6 +32,18 @@ Java.perform(() => {
|
|||
const Base64 = Java.use("android.util.Base64");
|
||||
const InMemoryDexClassLoader = Java.use("dalvik.system.InMemoryDexClassLoader");
|
||||
const ByteBuffer = Java.use("java.nio.ByteBuffer");
|
||||
const Method = Java.use("java.lang.reflect.Method");
|
||||
const Class = Java.use("java.lang.Class");
|
||||
const Constructor = Java.use("java.lang.reflect.Constructor");
|
||||
const Modifier = Java.use("java.lang.reflect.Modifier");
|
||||
const DexFile = Java.use("dalvik.system.DexFile");
|
||||
const File = Java.use('java.io.File');
|
||||
const Files = Java.use('java.nio.file.Files');
|
||||
const Path = Java.use('java.nio.file.Path');
|
||||
const System = Java.use('java.lang.System');
|
||||
const Arrays = Java.use('java.util.Arrays');
|
||||
|
||||
|
||||
const myClassLoader = InMemoryDexClassLoader.$new(
|
||||
ByteBuffer.wrap(Base64.decode("<PYTHON REPLACE StackConsumer.dex.b64>", Base64.DEFAULT.value)),
|
||||
null
|
||||
|
|
@ -80,17 +109,6 @@ Java.perform(() => {
|
|||
")V";
|
||||
};
|
||||
|
||||
const Method = Java.use("java.lang.reflect.Method");
|
||||
const Class = Java.use("java.lang.Class");
|
||||
const Constructor = Java.use("java.lang.reflect.Constructor");
|
||||
const Modifier = Java.use("java.lang.reflect.Modifier");
|
||||
const DexFile = Java.use("dalvik.system.DexFile");
|
||||
|
||||
const File = Java.use('java.io.File');
|
||||
const Files = Java.use('java.nio.file.Files');
|
||||
const Path = Java.use('java.nio.file.Path');
|
||||
const System = Java.use('java.lang.System');
|
||||
const Arrays = Java.use('java.util.Arrays');
|
||||
|
||||
// ****** Reflexive Method Calls ******
|
||||
|
||||
|
|
@ -198,6 +216,7 @@ Java.perform(() => {
|
|||
"dex": [b64],
|
||||
"classloader_class": classloader_class,
|
||||
"classloader": classloader_id,
|
||||
"classloader_parent": System.identityHashCode(loader.getParent()),
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -268,6 +287,7 @@ Java.perform(() => {
|
|||
"dex": dex,
|
||||
"classloader_class": classloader_class,
|
||||
"classloader": classloader_id,
|
||||
"classloader_parent": System.identityHashCode(loader.getParent()),
|
||||
}
|
||||
});
|
||||
return this.openInMemoryDexFilesNative(
|
||||
|
|
@ -279,22 +299,6 @@ Java.perform(() => {
|
|||
elements,
|
||||
);
|
||||
};
|
||||
|
||||
// Find the main APK class loader:
|
||||
// Not so easy, just send all class loader and sort this out later:
|
||||
var class_loader = Java.enumerateClassLoadersSync();
|
||||
for (var cl of class_loader) {
|
||||
//if (cl.toString().includes("dalvik.system.PathClassLoader[DexPathList[[directory \".\"],")) {
|
||||
// continue;
|
||||
//}
|
||||
//if (cl.$className == "java.lang.BootClassLoader") {
|
||||
// continue;
|
||||
//}
|
||||
send({"type": "classloader", "data": {
|
||||
"id": System.identityHashCode(cl),
|
||||
"str": cl.toString(),
|
||||
"cname": cl.$className
|
||||
}});
|
||||
}
|
||||
});
|
||||
|
||||
recv('dump-class-loaders', function onMessage(msg) {dump_classloaders()});
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue