mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
update frida script
This commit is contained in:
@@ -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) {}
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -0,0 +1,127 @@
|
||||
// ======================
|
||||
// 安全参数打印
|
||||
// ======================
|
||||
function safePrintArg(ptr) {
|
||||
try {
|
||||
if (!ptr || ptr.isNull()) return "<null>";
|
||||
|
||||
// 如果能包装成 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) + "...<truncated>";
|
||||
return `[${cls}] ${desc}`;
|
||||
} catch (_) {
|
||||
console.log("raw:", args[0]);
|
||||
}
|
||||
} catch (_) {
|
||||
// 不能包装成 OC 对象,则返回 pointer 地址
|
||||
return ptr.toString();
|
||||
}
|
||||
|
||||
} catch (e) {
|
||||
return `<print-error: ${e}>`;
|
||||
}
|
||||
}
|
||||
|
||||
// ======================
|
||||
// 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}]: <error ${e}>`);
|
||||
}
|
||||
}
|
||||
},
|
||||
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);
|
||||
}
|
||||
@@ -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();
|
||||
});
|
||||
@@ -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 (_) {
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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.");
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 (_) {
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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 (_) {
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -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.");
|
||||
}
|
||||
@@ -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 }));
|
||||
}
|
||||
}
|
||||
);
|
||||
@@ -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 }));
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
@@ -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 (_) {
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -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) {
|
||||
}
|
||||
});
|
||||
@@ -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 (_) {
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user