try (and fail) to fix issues with stack collection

This commit is contained in:
Jean-Marie 'Histausse' Mineau 2025-03-10 17:13:55 +01:00
parent b906988141
commit 95601d2dbe
Signed by: histausse
GPG key ID: B66AEEDA9B645AD2
3 changed files with 22 additions and 2 deletions

View file

@ -3,6 +3,8 @@ package theseus.android;
import java.util.function.Consumer;
import java.lang.StackWalker.StackFrame;
import java.util.ArrayList;
import java.util.function.Function;
import java.util.stream.Stream;
class StackConsumer implements Consumer<StackFrame> {
@ -20,4 +22,8 @@ class StackConsumer implements Consumer<StackFrame> {
public StackFrame[] getStack() {
return this.stack.toArray(new StackFrame[] {});
}
public Function<? super Stream<StackWalker.StackFrame>, StackFrame[]> walkNFrame(int n) {
return s -> { s.limit(n).forEach(this); return this.getStack(); };
}
}

View file

@ -143,7 +143,6 @@ def handle_load_dex(data, data_storage: dict, file_storage: Path):
print("DEX file loaded:")
print(f" by: {classloader_class} ({classloader})")
for file in dex:
print(f"{file=}")
file_bin = base64.b64decode(file)
hasher = hashlib.sha1()
hasher.update(file_bin)

View file

@ -22,11 +22,26 @@ Java.perform(() => {
const StackConsumer = Java.ClassFactory.get(myClassLoader).use("theseus.android.StackConsumer");
const get_stack = function () {
// console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Exception").$new()));
//
// TODO: use this instead? (https://developer.android.com/reference/java/lang/StackTraceElement)
// Pro: - more robust (cf crash of maltoy app)
// - Works with any android version
// Con: - Use java string: may require a lot of parsing
// - Use getLineNumber is iffy: returns either a line number when debug info are available or the dex address
// when no debug info. We prefere the address, but does this means we need to strip the apk before running?
// var stack = Java.use("java.lang.Exception").$new().getStackTrace();
// for (var i = 0; i < stack.length; i++) {
// console.log(stack[i].toString());
// }
// return [];
var stackConsumer = StackConsumer.$new();
var walker = StackWalker.getInstance(StackWalkerOptionsRetainClassReference);
walker.forEach(stackConsumer);
//walker.walk(stackConsumer.walkNFrame(20));
var stack = stackConsumer.getStack()
//send({"type": "stack", "data": stackConsumer.getStack()});
return stackConsumer.getStack().map((frame) => {
return stack.map((frame) => {
return {
"bytecode_index": frame.getByteCodeIndex(),
"is_native": frame.isNativeMethod(),