finally
This commit is contained in:
parent
bd725ba91b
commit
a0cb49fd77
2 changed files with 63 additions and 19 deletions
|
|
@ -32,6 +32,9 @@ def spinner(symbs: str = "-\\|/"):
|
||||||
yield s
|
yield s
|
||||||
|
|
||||||
|
|
||||||
|
CLASSLOADER_DONE = False
|
||||||
|
|
||||||
|
|
||||||
# Define handler to event generated by the scripts
|
# Define handler to event generated by the scripts
|
||||||
def on_message(message, data, data_storage: dict, file_storage: Path):
|
def on_message(message, data, data_storage: dict, file_storage: Path):
|
||||||
if message["type"] == "error":
|
if message["type"] == "error":
|
||||||
|
|
@ -47,6 +50,9 @@ def on_message(message, data, data_storage: dict, file_storage: Path):
|
||||||
handle_load_dex(message["payload"]["data"], data_storage, file_storage)
|
handle_load_dex(message["payload"]["data"], data_storage, file_storage)
|
||||||
elif message["type"] == "send" and message["payload"]["type"] == "classloader":
|
elif message["type"] == "send" and message["payload"]["type"] == "classloader":
|
||||||
handle_classloader_data(message["payload"]["data"], data_storage)
|
handle_classloader_data(message["payload"]["data"], data_storage)
|
||||||
|
elif message["type"] == "send" and message["payload"]["type"] == "classloader-done":
|
||||||
|
global CLASSLOADER_DONE
|
||||||
|
CLASSLOADER_DONE = True
|
||||||
else:
|
else:
|
||||||
print("[-] message:", message)
|
print("[-] message:", message)
|
||||||
|
|
||||||
|
|
@ -362,24 +368,65 @@ def collect_runtime(apk: Path, device_name: str, file_storage: Path, output: Tex
|
||||||
# Resume the execution of the APK
|
# Resume the execution of the APK
|
||||||
device.resume(pid)
|
device.resume(pid)
|
||||||
|
|
||||||
script.post({"type": "dump-class-loaders"})
|
print("==> Press ENTER to end the analysis <==")
|
||||||
print("==> Press ENTER to finish the analysis <==")
|
|
||||||
input()
|
input()
|
||||||
|
|
||||||
|
# Dump all known classloaders
|
||||||
|
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)
|
||||||
|
|
||||||
# Try to find the Main class loader
|
# Try to find the Main class loader
|
||||||
main_class_loader: str | None = None
|
main_class_loader: str | None = None
|
||||||
cls = {d["id"]: d for d in data_storage["classloaders"]}
|
# cls = {d["id"]: d for d in data_storage["classloaders"]}
|
||||||
for load_data in data_storage["dyn_code_load"]:
|
# for load_data in data_storage["dyn_code_load"]:
|
||||||
if load_data["classloader"] in cls:
|
# if load_data["classloader"] in cls:
|
||||||
del cls[load_data["classloader"]]
|
# del cls[load_data["classloader"]]
|
||||||
for id_ in list(cls.keys()):
|
# for id_ in list(cls.keys()):
|
||||||
if (
|
# if (
|
||||||
'dalvik.system.PathClassLoader[DexPathList[[directory "."],'
|
# 'dalvik.system.PathClassLoader[DexPathList[[directory "."],'
|
||||||
in cls[id_]["str"]
|
# in cls[id_]["str"]
|
||||||
):
|
# ):
|
||||||
del cls[id_]
|
# del cls[id_]
|
||||||
elif cls[id_]["cname"] == "java.lang.BootClassLoader":
|
# elif cls[id_]["cname"] == "java.lang.BootClassLoader":
|
||||||
del cls[id_]
|
# del cls[id_]
|
||||||
|
cls = {}
|
||||||
|
for cl in data_storage["classloaders"]:
|
||||||
|
# This is verry doubious
|
||||||
|
if cl["cname"] == "dalvik.system.PathClassLoader":
|
||||||
|
zip_files = list(
|
||||||
|
map(
|
||||||
|
lambda s: s.removeprefix('zip file "').removesuffix('"'),
|
||||||
|
filter(
|
||||||
|
lambda s: s.startswith('zip file "'),
|
||||||
|
(
|
||||||
|
w
|
||||||
|
for b in cl["str"].split("]")
|
||||||
|
for a in b.split("[")
|
||||||
|
for w in a.split(",")
|
||||||
|
),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
)
|
||||||
|
if len(zip_files) == 1:
|
||||||
|
zip_path = Path(zip_files[0])
|
||||||
|
if (
|
||||||
|
len(zip_path.parts) == 6
|
||||||
|
and zip_path.parts[0] == "/"
|
||||||
|
and zip_path.parts[1] == "data"
|
||||||
|
and zip_path.parts[2] == "app"
|
||||||
|
and zip_path.parts[4].startswith(app + "-")
|
||||||
|
and zip_path.parts[5] == "base.apk"
|
||||||
|
):
|
||||||
|
cls[cl["id"]] = cl
|
||||||
if len(cls) == 0:
|
if len(cls) == 0:
|
||||||
print("[!] No classloader found for the main APK")
|
print("[!] No classloader found for the main APK")
|
||||||
elif len(cls) > 1:
|
elif len(cls) > 1:
|
||||||
|
|
@ -401,10 +448,6 @@ def collect_runtime(apk: Path, device_name: str, file_storage: Path, output: Tex
|
||||||
main_class_loader = list(cls.keys())[0]
|
main_class_loader = list(cls.keys())[0]
|
||||||
data_storage["apk_cl_id"] = main_class_loader
|
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=" ")
|
json.dump(data_storage, output, indent=" ")
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,10 +10,11 @@ function dump_classloaders() {
|
||||||
"cname": cl.$className
|
"cname": cl.$className
|
||||||
}});
|
}});
|
||||||
}
|
}
|
||||||
|
send({"type": "classloader-done"})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
recv('dump-class-loaders', function onMessage(msg) {dump_classloaders()});
|
// recv('dump-class-loaders', function onMessage(msg) {dump_classloaders()});
|
||||||
|
|
||||||
Java.perform(() => {
|
Java.perform(() => {
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue