From e3b3717324ca3c556c45fb3b39959cbd62aa66dd Mon Sep 17 00:00:00 2001 From: axhlzy Date: Wed, 27 Mar 2024 11:11:52 +0800 Subject: [PATCH] add args ( parseIl2cppMethodName ) for breakWithStack --- Il2cppHook/agent/base/breaker.ts | 12 ++++++++--- Il2cppHook/agent/utils/stack.ts | 36 +++++++++++++++++--------------- 2 files changed, 28 insertions(+), 20 deletions(-) diff --git a/Il2cppHook/agent/base/breaker.ts b/Il2cppHook/agent/base/breaker.ts index 8eeaec48..40648f4b 100644 --- a/Il2cppHook/agent/base/breaker.ts +++ b/Il2cppHook/agent/base/breaker.ts @@ -297,12 +297,18 @@ export class Breaker { }, (retval: InvocationReturnValue) => LOGD(`Retval\t---> ${retval}`)) } - static breakWithStack = (mPtr: NativePointer, accurate: boolean = true) => { + /** + * print stack trace + * @param mPtr function address + * @param accurate is accurate (default true) + * @param parseIl2cppMethodName enable parse il2cpp method name in stack (default true) + */ + static breakWithStack = (mPtr: NativePointer, accurate: boolean = true, parseIl2cppMethodName:boolean = true) => { mPtr = this.fakeMethodPtr(mPtr, JSHOOKTYPE.STACK) A(mPtr, (_args: InvocationArguments, ctx: CpuContext, _passValue: Map) => { LOGO(`\n${getLine(65)}\n`) LOGH(`Called from ${mPtr} ---> ${mPtr.sub(soAddr)}\t| LR : ${checkCtx(getPlatformCtx(ctx))}\n`) - PrintStackTraceNative(ctx, accurate) + PrintStackTraceNative(ctx, accurate, false, 6, parseIl2cppMethodName) LOGO(`\n${getLine(65)}`) }) } @@ -629,7 +635,7 @@ declare global { var BM: (className: string) => void var breakWithArgs: (mPtr: NativePointer, argCount?: number) => void var breakInline: (mPtr: NativePointer, callback?: (value: CpuContext) => void) => void - var breakWithStack: (mPtr: NativePointer, accurate?: boolean) => void + var breakWithStack: (mPtr: NativePointer, accurate?: boolean, parseIl2cppMethodName?:boolean) => void var breakMemRW: (mPtr: NativePointer, length?: number) => void var getPlatform: () => string var getPlatformCtx: (ctx: CpuContext) => ArmCpuContext | Arm64CpuContext diff --git a/Il2cppHook/agent/utils/stack.ts b/Il2cppHook/agent/utils/stack.ts index 10082e84..004e8111 100644 --- a/Il2cppHook/agent/utils/stack.ts +++ b/Il2cppHook/agent/utils/stack.ts @@ -12,8 +12,8 @@ const ptrMightBeMethod = (mPtr: NativePointer, withLog: boolean = true): Il2Cpp. localSortedMethods = allMethodsCacheArray.sort((a: Il2Cpp.Method, b: Il2Cpp.Method) => a.virtualAddress.compare(b.virtualAddress)) let tmpMethod: Il2Cpp.Method | null = null for (let i = 0; i < allMethodsCacheArray.length - 1; i++) { - let method: Il2Cpp.Method = allMethodsCacheArray[i] - let nextMethod: Il2Cpp.Method = allMethodsCacheArray[i + 1] + const method: Il2Cpp.Method = allMethodsCacheArray[i] + const nextMethod: Il2Cpp.Method = allMethodsCacheArray[i + 1] if (mPtr.compare(method.virtualAddress) >= 0 && Math.abs(mPtr.sub(method.virtualAddress).toInt32()) < 0x10000 && mPtr.compare(nextMethod.virtualAddress) < 0) { @@ -25,26 +25,28 @@ const ptrMightBeMethod = (mPtr: NativePointer, withLog: boolean = true): Il2Cpp. } var symbMethod: Map = new Map() // 放成全局的有重复的直接使用不在重复去查找以提高速度 -const PrintStackTraceNative = (ctx: CpuContext, fuzzy: boolean = false, retText: boolean = false, slice: number = 6): string | void => { +const PrintStackTraceNative = (ctx: CpuContext, fuzzy: boolean = false, retText: boolean = false, slice: number = 6, parseIl2cppMethodName:boolean = true): string | void => { let stacks: NativePointer[] = Thread.backtrace(ctx, fuzzy ? Backtracer.FUZZY : Backtracer.ACCURATE) - stacks.forEach((frame: NativePointer, _index: number, _thisArr: NativePointer[]) => { - if (symbMethod.has(frame.toString())) return - let symb: DebugSymbol = DebugSymbol.fromAddress(frame) - if (symb.moduleName == "libil2cpp.so" && symb.name?.startsWith("0x")) { - let il2cppMethod: Il2Cpp.Method | null = ptrMightBeMethod(frame) - if (il2cppMethod != null) { - let offset = symb.address.sub(il2cppMethod.virtualAddress) - symbMethod.set(frame.toString(), `MI:${il2cppMethod.handle} -> ${il2cppMethod.class.name}::${getMethodDesFromMethodInfo(il2cppMethod)} ${offset}↓`) + if (parseIl2cppMethodName) { + stacks.forEach((frame: NativePointer, _index: number, _thisArr: NativePointer[]) => { + if (symbMethod.has(frame.toString())) return + const symb: DebugSymbol = DebugSymbol.fromAddress(frame) + if (symb.moduleName == "libil2cpp.so" && symb.name?.startsWith("0x")) { + const il2cppMethod: Il2Cpp.Method | null = ptrMightBeMethod(frame) + if (il2cppMethod != null) { + const offset = symb.address.sub(il2cppMethod.virtualAddress) + symbMethod.set(frame.toString(), `MI:${il2cppMethod.handle} -> ${il2cppMethod.class.name}::${getMethodDesFromMethodInfo(il2cppMethod)} ${offset}↓`) + } } - } - }) - let tmpText: string = stacks + }) + } + const tmpText: string = stacks .slice(0, slice) .map(DebugSymbol.fromAddress) .map((sym: DebugSymbol) => { let strRet: string = `${sym}` - let md: Module | null = Process.findModuleByAddress(sym.address) - let methodstr: string | undefined = symbMethod.get(sym.address.toString()) + const md: Module | null = Process.findModuleByAddress(sym.address) + const methodstr: string | undefined = symbMethod.get(sym.address.toString()) if (md != null && md.name == "libil2cpp.so" && strRet.startsWith('0x')) strRet = `${strRet}\t| ${methodstr == undefined ? "null" : methodstr}` return strRet @@ -68,7 +70,7 @@ export { PrintStackTrace, PrintStackTraceNative, GetStackTrace, GetStackTraceNat declare global { var PrintStackTraceJava: () => void var GetStackTraceJava: () => void - var PrintStackTraceNative: (ctx: CpuContext, fuzzy?: boolean, retText?: boolean, slice?: number, reverse?: boolean) => string | void + var PrintStackTraceNative: (ctx: CpuContext, fuzzy?: boolean, retText?: boolean, slice?: number, reverse?: boolean, parseIl2cppMethodName?:boolean) => string | void var GetStackTraceNative: (ctx: CpuContext, level?: number) => string }