From 7a1f9e99a55413bd498d9ce9c9b3da91ea99269c Mon Sep 17 00:00:00 2001 From: yincong Date: Fri, 28 Nov 2025 12:49:08 +0800 Subject: [PATCH] update frida script --- frida/button_trigger.js | 21 +++++ encrypt1.js => frida/encrypt1.js | 0 frida/enumhook.js | 127 +++++++++++++++++++++++++++++++ frida/function.js | 103 +++++++++++++++++++++++++ frida/idapro.js | 45 +++++++++++ frida/keydown.js | 29 +++++++ frida/keyword.js | 89 ++++++++++++++++++++++ frida/log.js | 64 ++++++++++++++++ frida/log_memaddress.js | 64 ++++++++++++++++ frida/matchFun.js | 36 +++++++++ frida/memcpy.js | 43 +++++++++++ frida/memo_check.js | 13 ++++ frida/other_memo_check.js | 17 +++++ frida/script.js | 63 +++++++++++++++ frida/tracelog.js | 21 +++++ frida/writedata.js | 63 +++++++++++++++ 16 files changed, 798 insertions(+) create mode 100644 frida/button_trigger.js rename encrypt1.js => frida/encrypt1.js (100%) create mode 100644 frida/enumhook.js create mode 100644 frida/function.js create mode 100644 frida/idapro.js create mode 100644 frida/keydown.js create mode 100644 frida/keyword.js create mode 100644 frida/log.js create mode 100644 frida/log_memaddress.js create mode 100644 frida/matchFun.js create mode 100644 frida/memcpy.js create mode 100644 frida/memo_check.js create mode 100644 frida/other_memo_check.js create mode 100644 frida/script.js create mode 100644 frida/tracelog.js create mode 100644 frida/writedata.js diff --git a/frida/button_trigger.js b/frida/button_trigger.js new file mode 100644 index 0000000..65f2c35 --- /dev/null +++ b/frida/button_trigger.js @@ -0,0 +1,21 @@ +Interceptor.attach( + ObjC.classes.NSEvent["- keyCode"].implementation, + { + onLeave(retval) { + try { + // 36 = Return(Enter) + if (retval.toInt32() === 36) { + console.log("\n===== ENTER PRESSED (System Level) ====="); + + // 打印调用栈 + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress) + .join("\n") + ); + console.log("========================================\n"); + } + } catch (e) {} + } + } +); diff --git a/encrypt1.js b/frida/encrypt1.js similarity index 100% rename from encrypt1.js rename to frida/encrypt1.js diff --git a/frida/enumhook.js b/frida/enumhook.js new file mode 100644 index 0000000..1389da2 --- /dev/null +++ b/frida/enumhook.js @@ -0,0 +1,127 @@ +// ====================== +// 安全参数打印 +// ====================== +function safePrintArg(ptr) { + try { + if (!ptr || ptr.isNull()) return ""; + + // 如果能包装成 ObjC 对象 + try { + try { + let o = new ObjC.Object(args[0]); + console.log(o.$className); + + desc = o.toString(); + if (desc.length > 300) desc = desc.slice(0, 300) + "..."; + return `[${cls}] ${desc}`; + } catch (_) { + console.log("raw:", args[0]); + } + } catch (_) { + // 不能包装成 OC 对象,则返回 pointer 地址 + return ptr.toString(); + } + + } catch (e) { + return ``; + } +} + +// ====================== +// Hook 方法工具 +// ====================== +function hookMethod(clsName, methodName) { + try { + const cls = ObjC.classes[clsName]; + if (!cls) return; + + const method = cls[methodName]; + if (!method || !method.implementation) return; + + console.log(`\n🔥 Hooking ${clsName} ${methodName}`); + Interceptor.attach(method.implementation, { + onEnter(args) { + console.log(`\n🚀 ${clsName} ${methodName} called`); + + // 打印参数 x0~x5 + for (let i = 0; i < 6; i++) { + try { + console.log(`arg[${i}]: ${safePrintArg(args[i])}`); + } catch (e) { + console.log(`arg[${i}]: `); + } + } + }, + onLeave(retval) { + console.log(`⬅️ return: ${safePrintArg(retval)}`); + } + }); + } catch (e) { + console.log(`❌ Hook ${clsName} ${methodName} failed: ${e}`); + } +} + +// ====================== +// WeChat 消息加密关键入口列表 +// ====================== +const HOOK_TARGETS = [ + ["WCMessageWrap", "- protobufEncode"], + ["WCMessageWrap", "- serialize"], + + // 发送消息必走 + ["WCProtoBuf", "- encodeMessage:"], + ["WCProtoBuf", "- data"], + + // 尝试抓取 key/data + ["MMEncryptMessage", "- encryptMessage:key:"], + ["WCEncryptHelper", "- encrypt:withKey:"], + ["WCEncryptHelper", "- encryptData:key:"], + + // 发送消息必走路径 + ["WCMessageMgr", "- SendAppMsg:"], + ["WCMessageMgr", "- SendTextMessage:"], + ["WCMessageMgr", "- SendImageMessage:"], + + // 底层 protobuf builder + ["PBGeneratedMessage", "- data"], + ["PBGeneratedMessage", "- serialize"], + + // 经常出现的 encode 函数 + ["MMProtoBase", "- serialize"], + ["MMProtoBase", "- encode"] +]; + +// ====================== +// 挂钩所有关键点 +// ====================== +function hookAll() { + console.log("🚀 WeChat 上层加密 Hook 正在启动...\n"); + + HOOK_TARGETS.forEach(([cls, method]) => { + hookMethod(cls, method); + }); + + // 额外扫描所有类名包含 Encode 或 Message 的 class + console.log("\n🔍 自动扫描 Encode / Message 类..."); + for (const name in ObjC.classes) { + if (!name.includes("Encode") && !name.includes("Message")) continue; + + const cls = ObjC.classes[name]; + const methods = cls.$ownMethods; + + methods.forEach(m => { + if (m.includes("encode") || m.includes("Encrypt") || m.includes("serialize")) { + hookMethod(name, m); + } + }); + } + + console.log("\n🎉 Hook 完成,开始抓取 WeChat 消息明文 / proto / encrypt 信息...\n"); +} + +// ====================== +if (ObjC.available) { + hookAll(); +} else { + setTimeout(hookAll, 1000); +} diff --git a/frida/function.js b/frida/function.js new file mode 100644 index 0000000..07af9c7 --- /dev/null +++ b/frida/function.js @@ -0,0 +1,103 @@ +// ====== 配置:你想 Hook 的 WeChat 函数偏移 ====== +const WECHAT_OFFSETS = [ + 0x4565b2c, + 0x4566f1c, + 0x4564860, + 0x4591ff8, + 0x45d09cc, + 0x45cebbc, + 0x4591fa0, + 0x4581834, + 0x4581760, + 0x4387d08, + 0x4334e88, + 0x4328ebc, + 0x4384764, + 0x43811e8 +]; + +// ====== 统一安全打印函数 ====== +function safePrintRegister(args) { + for (let i = 0; i < 8; i++) { + try { + console.log(`x${i}: ${args[i]}`); + } catch (e) { + console.log(`x${i}: <无法读取> (${e})`); + } + } +} + +function safePrintBacktrace(context) { + try { + let bt = Thread.backtrace( + context, + Backtracer.FUZZY // 更稳定,遇到系统函数更不容易崩 + ).map(DebugSymbol.fromAddress) + .join("\n"); + + console.log("\n--- 调用堆栈 ---"); + console.log(bt); + console.log("-----------------\n"); + + } catch (e) { + console.log("无法获取堆栈:" + e); + } +} + +// ====== 主逻辑:Hook 偏移量函数 ====== +function hook_wechat_internal_functions() { + const wechatModule = Process.findModuleByName("WeChat"); + if (!wechatModule) { + console.error("❌ 找不到 WeChat 模块"); + return; + } + + const base = wechatModule.base; + console.log("📌 WeChat Base:", base); + + WECHAT_OFFSETS.forEach(offset => { + const target = base.add(offset); + + // 尝试符号化 + let funcName = `WeChat!0x${offset.toString(16)}`; + try { + const sym = DebugSymbol.fromAddress(target); + if (sym && sym.name) funcName = sym.name; + } catch (_) {} + + console.log(`\n🔧 准备 Hook: ${funcName} @ 0x${target}`); + + try { + Interceptor.attach(target, { + onEnter(args) { + console.log("\n=============================================="); + console.log(`🚀 进入函数: ${funcName}`); + console.log(`📍 地址: 0x${target}`); + + console.log("\n--- 🧩 寄存器参数 x0-x7 ---"); + safePrintRegister(args); + + console.log("\n--- 🧵 调用堆栈 ---"); + safePrintBacktrace(this.context); + + console.log("==============================================\n"); + }, + + onLeave(retval) { + // 如果需要打印返回值,可打开: + // console.log("返回值:", retval); + } + }); + + console.log(`✅ 已 Hook: ${funcName}`); + + } catch (e) { + console.error(`❌ Hook 失败 @ 0x${target} :${e}`); + } + }); +} + +// ====== 入口 ====== +setImmediate(() => { + hook_wechat_internal_functions(); +}); diff --git a/frida/idapro.js b/frida/idapro.js new file mode 100644 index 0000000..073aa8e --- /dev/null +++ b/frida/idapro.js @@ -0,0 +1,45 @@ +const mod = Process.getModuleByName("WeChat"); +const realAddr = ptr("0x1057ee3a8").sub("0x100000000").add(mod.base); + +console.log("[+] Real Function Address:", realAddr); + +Interceptor.attach(realAddr, { + onEnter(args) { + for (let i = 0; i < 10; i++) { + try { + if (args[i].isNull()) { + continue; + } + console.log(`\n[+] arg${i} ${args[i]}`); + + if (args[i].compare(ptr("0x600000000000")) >= 0 && args[i].compare(ptr("0x700000000000")) < 0 && args[i].and(0x7).isNull()) { + console.log(hexdump(args[i], { + offset: 0, + length: 128 + })); + } + } catch (e) { + console.log("Enter Error:", e); + } + } + + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress).join('\n')); + + }, + + onLeave(retval) { + console.log("===== sub_105808800 LEAVE ====="); + console.log("Return value:", retval); + try { + console.log("Return hexdump:"); + console.log(hexdump(retval, { + offset: 0, + length: 128 + })); + } catch (_) { + } + } +}); + diff --git a/frida/keydown.js b/frida/keydown.js new file mode 100644 index 0000000..ec29c91 --- /dev/null +++ b/frida/keydown.js @@ -0,0 +1,29 @@ +// 警告:仅为演示AppKit Hooking概念,实际类名和方法可能不同 +// 尝试 Hook NSResponder 的 keyDown: 方法,所有接收键盘事件的对象都会经过它 +var NSResponder = ObjC.classes.NSResponder; + +if (NSResponder) { + console.log("NSResponder class found."); + Interceptor.attach(NSResponder['- keyDown:'].implementation, { + onEnter: function(args) { + // args[2] 是 NSEvent* 键盘事件对象 + console.log("Hooked keyDown: 方法被调用"); + var event = new ObjC.Object(args[2]); + var type = event.type().toString(); + console.log("捕获到键盘事件,类型: " + type); + + // 检查是否为按键按下事件 (NSKeyDown = 10) + if (type === '10') { + var chars = event.charactersIgnoringModifiers().toString(); + // 检查按键是否为回车 (通常chars是"\r"或"\n") + if (chars === '\r' || chars === '\n') { + console.log('>>> 🌟 捕获到 AppKit 层的回车键事件!🌟 <<<'); + // 可以在这里执行您的自定义代码 + } + } + } + }); + console.log("AppKit NSResponder hook loaded."); +} else { + console.log("Failed to find NSResponder class."); +} \ No newline at end of file diff --git a/frida/keyword.js b/frida/keyword.js new file mode 100644 index 0000000..9ab940c --- /dev/null +++ b/frida/keyword.js @@ -0,0 +1,89 @@ +const keyword = "7.7"; +const addrs = ["6000033DDE48"] +console.log(keyword); +console.log(addrs); + +function memoGet(p) { + p = "0x" + p; + const idaAddr = ptr(p); + MemoryAccessMonitor.enable( + { + base: idaAddr, + size: 0x40 // buffer 大小 + }, + { + onAccess(details) { + console.log("Access by:", details.from); + attach(details.from) + console.log(hexdump(idaAddr, {length: 0x40})); + } + } + ); + +} + +function attach(from) { + const realAddr = ptr(from); + + console.log("[+] Real Function Address:", realAddr); + + Interceptor.attach(realAddr, { + onEnter(args) { + for (let i = 0; i < 10; i++) { + try { + if (args[i].isNull()) { + continue; + } + console.log(`\n[+] arg${i} ${args[i]}`); + + if (args[i].compare(ptr("0x600000000000")) >= 0 && args[i].compare(ptr("0x700000000000")) < 0 && args[i].and(0x7).isNull()) { + const buf = args[i].readByteArray(128) + if (!buf) { + continue; + } + let s = ""; + const u8 = new Uint8Array(buf); + for (let b of u8) { + if (b >= 0x20 && b <= 0x7E) { + s += String.fromCharCode(b); + } else { + s += "."; + } + } + + if (keyword === "" || s.includes(keyword)) { + console.log(`\n[+] arg${i} ${args[i]} ${s}`); + console.log(hexdump(args[i], {length: 128})); + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress).join('\n')); + return; + } + } + } catch (e) { + console.log("Enter Error:", e); + } + } + + }, + + onLeave(retval) { + console.log("===== sub_105808800 LEAVE ====="); + console.log("Return value:", retval); + try { + if (retval.compare(ptr("0x600000000000")) >= 0 && retval.compare(ptr("0x700000000000")) < 0 && retval.and(0x7).isNull()) { + console.log(hexdump(retval, { + offset: 0, + length: 40 + })); + } + } catch (_) { + } + } + }); +} + + +for (let addr of addrs) { + memoGet(addr); +} \ No newline at end of file diff --git a/frida/log.js b/frida/log.js new file mode 100644 index 0000000..130fe36 --- /dev/null +++ b/frida/log.js @@ -0,0 +1,64 @@ +const mod = Process.getModuleByName("WeChat"); +const realAddr = ptr("0x105efadc0").sub("0x100000000").add(mod.base); + +console.log("[+] Real Function Address:", realAddr); + +Interceptor.attach(realAddr, { + onEnter(args) { + for (let i = 0; i < 10; i++) { + try { + if (args[i].isNull()) { + continue; + } + + if (args[i].compare(ptr("0x600000000000")) >= 0 && args[i].compare(ptr("0x700000000000")) < 0 && args[i].and(0x7).isNull()) { + const buf = args[i].readByteArray(128) + if (!buf) { + continue; + } + let s = ""; + const u8 = new Uint8Array(buf); + for (let b of u8) { + if (b >= 0x20 && b <= 0x7E) { + s += String.fromCharCode(b); + } else { + s += "."; + } + } + + console.log(`\n[+] arg${i} ${args[i]} ${s}`); + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress).join('\n')); + + // if (s.includes(".cc")) { + // console.log(`\n[+] arg${i} ${args[i]} ${s}`); + // console.log(hexdump(args[i], { length: 128 })); + // console.log( + // Thread.backtrace(this.context, Backtracer.ACCURATE) + // .map(DebugSymbol.fromAddress).join('\n')); + // return; + // } + } + } catch (e) { + console.log("Enter Error:", e); + } + } + + + }, + + onLeave(retval) { + // console.log("===== sub_105808800 LEAVE ====="); + // console.log("Return value:", retval); + // try { + // console.log("Return hexdump:"); + // console.log(hexdump(retval, { + // offset: 0, + // length: 128 + // })); + // } catch (_) { + // } + } +}); + diff --git a/frida/log_memaddress.js b/frida/log_memaddress.js new file mode 100644 index 0000000..35a3b6c --- /dev/null +++ b/frida/log_memaddress.js @@ -0,0 +1,64 @@ +const mod = Process.getModuleByName("WeChat"); +const realAddr = ptr("0x10a1f083c"); + +console.log("[+] Real Function Address:", realAddr); + +Interceptor.attach(realAddr, { + onEnter(args) { + for (let i = 0; i < 10; i++) { + try { + if (args[i].isNull()) { + continue; + } + + if (args[i].compare(ptr("0x600000000000")) >= 0 && args[i].compare(ptr("0x700000000000")) < 0 && args[i].and(0x7).isNull()) { + const buf = args[i].readByteArray(128) + if (!buf) { + continue; + } + let s = ""; + const u8 = new Uint8Array(buf); + for (let b of u8) { + if (b >= 0x20 && b <= 0x7E) { + s += String.fromCharCode(b); + } else { + s += "."; + } + } + + console.log(`\n[+] arg${i} ${args[i]} ${s}`); + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress).join('\n')); + + // if (s.includes(".cc")) { + // console.log(`\n[+] arg${i} ${args[i]} ${s}`); + // console.log(hexdump(args[i], { length: 128 })); + // console.log( + // Thread.backtrace(this.context, Backtracer.ACCURATE) + // .map(DebugSymbol.fromAddress).join('\n')); + // return; + // } + } + } catch (e) { + console.log("Enter Error:", e); + } + } + + + }, + + onLeave(retval) { + // console.log("===== sub_105808800 LEAVE ====="); + // console.log("Return value:", retval); + // try { + // console.log("Return hexdump:"); + // console.log(hexdump(retval, { + // offset: 0, + // length: 128 + // })); + // } catch (_) { + // } + } +}); + diff --git a/frida/matchFun.js b/frida/matchFun.js new file mode 100644 index 0000000..55a61a9 --- /dev/null +++ b/frida/matchFun.js @@ -0,0 +1,36 @@ +[ + "sendmsg", + "newsendmsg", + "SendMsg", + "SendMsgFH" +].forEach(sig => { + let arr = DebugSymbol.findFunctionsMatching("*" + sig + "*"); + arr.forEach(target => { + console.log("Hooking:", target); + + Interceptor.attach(ptr(target), { + onEnter(args) { + console.log("🚀 Called:", target); + + // 打印调用堆栈 + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress) + .join("\n") + ); + + // 打印第 1 个参数,一般就是 protobuf buffer + try { + console.log("arg0:", args[0]); + console.log(hexdump(args[0], { length: 256 })); + } catch(e){} + + // 打印第 2 个参数(通常是长度) + console.log("arg1:", args[1]); + }, + onLeave(retval) { + console.log("⬅️ return:", retval); + } + }); + }); +}); diff --git a/frida/memcpy.js b/frida/memcpy.js new file mode 100644 index 0000000..dc4a768 --- /dev/null +++ b/frida/memcpy.js @@ -0,0 +1,43 @@ +const libc = Process.getModuleByName("libSystem.B.dylib"); + +// 2. 拦截 memcpy +const memcpy_ptr = libc.findExportByName("memcpy"); + +if (memcpy_ptr) { + console.log("[+] Hooking memcpy."); + Interceptor.attach(memcpy_ptr, { + onEnter(args) { + // args[0] = destination (目标缓冲区) + // args[1] = source (源数据) + // args[2] = length + this.src = args[1]; + this.len = args[2].toInt32(); + }, + onLeave(retval) { + // 只检查长度适中的数据块 (防止日志爆炸) + if (this.len > 5 && this.len < 500) { + try { + // 尝试将源数据读取为 C 字符串 + const message = this.src.readCString(); + + if (message && message.length > 1) { + console.log(`\n======================================================`); + console.log(`[+] ⚠️ 明文捕获于 memcpy!`); + console.log(`[+] 长度: ${this.len} 字节`); + console.log(`[+] 消息内容 (ASCII): ${message}`); + + // 打印 Hexdump 验证 + console.log(`--- Hexdump 验证 ---`); + console.log(hexdump(this.src, { length: this.len > 128 ? 128 : this.len })); + + console.log(`======================================================`); + } + } catch (e) { + // 忽略读取错误 + } + } + } + }); +} else { + console.log("[!] memcpy symbol not found."); +} \ No newline at end of file diff --git a/frida/memo_check.js b/frida/memo_check.js new file mode 100644 index 0000000..de04e16 --- /dev/null +++ b/frida/memo_check.js @@ -0,0 +1,13 @@ +MemoryAccessMonitor.enable( + { + base: ptr("0x6000034c1000"), + size: 0x40 // buffer 大小 + }, + { + onAccess(details) { + console.log("Access by:", details.from); + console.log("Operation:", details.operation); + console.log(hexdump(idaAddr, { length: 0x40 })); + } + } +); diff --git a/frida/other_memo_check.js b/frida/other_memo_check.js new file mode 100644 index 0000000..cac1b82 --- /dev/null +++ b/frida/other_memo_check.js @@ -0,0 +1,17 @@ +const idaAddr = ptr("0x6000025A96DA"); +console.log("start monitor"); + +MemoryAccessMonitor.enable( + { + base: idaAddr, + size: 0x40 // buffer 大小 + }, + { + onAccess(details) { + console.log("0x6000029C6DF0 Details:", JSON.stringify(details)); + // console.log("0x6000029C6DF0 Access by:", DebugSymbol.fromAddress(details.from)); + console.log(hexdump(idaAddr, { length: 0x40 })); + } + } +); + diff --git a/frida/script.js b/frida/script.js new file mode 100644 index 0000000..e5d3915 --- /dev/null +++ b/frida/script.js @@ -0,0 +1,63 @@ +const mod = Process.getModuleByName("WeChat"); +const realAddr = ptr("0x1057ee3a8").sub("0x100000000").add(mod.base); + +console.log("[+] Real Function Address:", realAddr); + +Interceptor.attach(realAddr, { + onEnter(args) { + for (let i = 0; i < 10; i++) { + try { + if (args[i].isNull()) { + continue; + } + + // console.log(`\n[+] arg${i} ${args[i]}`); + if (args[i].compare(ptr("0x600000000000")) >= 0 && args[i].compare(ptr("0x700000000000")) < 0 && args[i].and(0x7).isNull()) { + const buf = args[i].readByteArray(128) + if (!buf) { + continue; + } + let s = ""; + const u8 = new Uint8Array(buf); + for (let b of u8) { + if (b >= 0x20 && b <= 0x7E) { + s += String.fromCharCode(b); + } else { + s += "."; + } + } + + + if (s.includes("3.3.3.3")) { + console.log(`\n[+] arg${i} ${args[i]}`); + console.log(hexdump(args[i], { length: 64 })); + // args[i].add(0x18).writeUtf16String("5555"); + // console.log(hexdump(args[i], { length: 64 })); + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress).join('\n')); + return; + } + } + } catch (e) { + console.log("Enter Error:", e); + } + } + + + }, + + onLeave(retval) { + // console.log("===== sub_105808800 LEAVE ====="); + // console.log("Return value:", retval); + // try { + // console.log("Return hexdump:"); + // console.log(hexdump(retval, { + // offset: 0, + // length: 128 + // })); + // } catch (_) { + // } + } +}); + diff --git a/frida/tracelog.js b/frida/tracelog.js new file mode 100644 index 0000000..0ee41c7 --- /dev/null +++ b/frida/tracelog.js @@ -0,0 +1,21 @@ +defineHandler({ + onEnter(log, args, state) { + log('ccaes_cbc_encrypt_mode() [libcorecrypto.dylib]'); + + try { + const bt = Thread.backtrace( + this.context, + Backtracer.ACCURATE + ) + .map(DebugSymbol.fromAddress) + .join('\n'); + + log('--- Call Stack ---\n' + bt + '\n-------------------'); + } catch (e) { + log('Error printing backtrace: ' + e); + } + }, + + onLeave(log, retval, state) { + } +}); diff --git a/frida/writedata.js b/frida/writedata.js new file mode 100644 index 0000000..d89a762 --- /dev/null +++ b/frida/writedata.js @@ -0,0 +1,63 @@ +const mod = Process.getModuleByName("WeChat"); +const realAddr = ptr("0x1057ee3a8").sub("0x100000000").add(mod.base); + +console.log("[+] Real Function Address:", realAddr); + +Interceptor.attach(realAddr, { + onEnter(args) { + for (let i = 0; i < 10; i++) { + try { + if (args[i].isNull()) { + continue; + } + + // console.log(`\n[+] arg${i} ${args[i]}`); + if (args[i].compare(ptr("0x600000000000")) >= 0 && args[i].compare(ptr("0x700000000000")) < 0 && args[i].and(0x7).isNull()) { + const buf = args[i].readByteArray(128) + if (!buf) { + continue; + } + let s = ""; + const u8 = new Uint8Array(buf); + for (let b of u8) { + if (b >= 0x20 && b <= 0x7E) { + s += String.fromCharCode(b); + } else { + s += "."; + } + } + + + if (s.includes("3.3.3.3")) { + console.log(`\n[+] arg${i} ${args[i]}`); + console.log(hexdump(args[i], { length: 64 })); + args[i].add(0x18).writeUtf16String("5555"); + console.log(hexdump(args[i], { length: 64 })); + console.log( + Thread.backtrace(this.context, Backtracer.ACCURATE) + .map(DebugSymbol.fromAddress).join('\n')); + return; + } + } + } catch (e) { + console.log("Enter Error:", e); + } + } + + + }, + + onLeave(retval) { + // console.log("===== sub_105808800 LEAVE ====="); + // console.log("Return value:", retval); + // try { + // console.log("Return hexdump:"); + // console.log(hexdump(retval, { + // offset: 0, + // length: 128 + // })); + // } catch (_) { + // } + } +}); +