mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
clear script
This commit is contained in:
@@ -1,53 +0,0 @@
|
||||
const mod = Process.getModuleByName("WeChat");
|
||||
const realAddr = ptr("0x102BAA1E0").sub("0x100000000").add(mod.base);
|
||||
|
||||
console.log("[+] Real Function Address:", realAddr);
|
||||
|
||||
Interceptor.attach(realAddr, {
|
||||
onEnter(args) {
|
||||
for (let i = 0; i < 20; 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 += ".";
|
||||
}
|
||||
}
|
||||
|
||||
console.log(s);
|
||||
}
|
||||
} 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 (_) {
|
||||
// }
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/**
|
||||
* _method_finder.js
|
||||
* 目标: 批量挂钩微信主程序 (WeChat.app) 中所有与消息/加密相关的 Objective-C 方法。
|
||||
* 作用: 找到微信内部封装的消息发送、接收、加解密逻辑的“入口”类和方法。
|
||||
*/
|
||||
|
||||
// 定义您认为可能包含消息处理或加解密逻辑的类名关键词
|
||||
const TARGET_KEYWORDS = [
|
||||
"Message", "Data", "Encry", "Crypt",
|
||||
"Send", "Recv", "Net", "Session",
|
||||
"Pack", "Unpack", "PB" // Protobuf相关的类
|
||||
];
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// 核心挂钩逻辑
|
||||
// -------------------------------------------------------------------
|
||||
|
||||
function hookWeChatMethods() {
|
||||
if (!ObjC.available) {
|
||||
console.error("[-] Objective-C 运行时不可用,无法进行 ObjC 方法挂钩。");
|
||||
return;
|
||||
}
|
||||
|
||||
let hooksCount = 0;
|
||||
const targetModule = Process.findModuleByName("WeChat"); // 仅关注主二进制文件
|
||||
|
||||
if (!targetModule) {
|
||||
console.error("[-] 微信主模块 'WeChat' 未找到。");
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`[+] 目标模块: ${targetModule.name} (${targetModule.base})`);
|
||||
console.log(`[+] 正在筛选包含关键词的 Objective-C 类: ${TARGET_KEYWORDS.join(', ')}...`);
|
||||
|
||||
// 遍历所有已加载的 Objective-C 类
|
||||
Object.keys(ObjC.classes).forEach(className => {
|
||||
// 确保类位于 'WeChat' 主模块内 (避免挂钩系统库)
|
||||
const classPtr = ObjC.classes[className].handle;
|
||||
if (!targetModule.base.le(classPtr) || !targetModule.base.add(targetModule.size).gt(classPtr)) {
|
||||
return; // 跳过不在 WeChat 模块内的类
|
||||
}
|
||||
|
||||
// 筛选包含关键词的类
|
||||
const matchesKeyword = TARGET_KEYWORDS.some(keyword => className.includes(keyword));
|
||||
if (matchesKeyword) {
|
||||
|
||||
const targetClass = ObjC.classes[className];
|
||||
console.log(`\n[*** FOUND CLASS ***] ${className}`);
|
||||
|
||||
// 遍历并挂钩该类的所有方法 (包括实例方法和类方法)
|
||||
[...targetClass.$methods].forEach(methodName => {
|
||||
|
||||
try {
|
||||
const method = targetClass[methodName];
|
||||
const methodSignature = (methodName.startsWith('+')) ? `[Class] ${methodName}` : `[Instance] ${methodName}`;
|
||||
|
||||
Interceptor.attach(method.implementation, {
|
||||
|
||||
onEnter: function (args) {
|
||||
// 使用 this.className 和 this.methodName 存储信息以便 onLeave 使用
|
||||
this.className = className;
|
||||
this.methodName = methodName;
|
||||
|
||||
console.log(`\n${"~".repeat(80)}`);
|
||||
console.log(`[CALL] Class: **${this.className}**`);
|
||||
console.log(`[CALL] Method: **${methodSignature}**`);
|
||||
|
||||
// 打印回溯,这正是找到函数入口的关键
|
||||
console.log("[ENTRY POINT] Call Stack (寻找更上层的业务逻辑入口):");
|
||||
console.log(
|
||||
Thread.backtrace(this.context, Backtracer.ACCURATE)
|
||||
.map(DebugSymbol.fromAddress).join('\n')
|
||||
);
|
||||
// 打印参数 (由于参数类型未知,我们只打印前几个指针)
|
||||
// 注意:args[0] = self (this), args[1] = _cmd (selector)
|
||||
console.log(`[ARGS] Argument 3 (args[2]): ${args[2]}`);
|
||||
if (args.length > 3) {
|
||||
console.log(`[ARGS] Argument 4 (args[3]): ${args[3]}`);
|
||||
}
|
||||
},
|
||||
|
||||
onLeave: function (retval) {
|
||||
console.log(`[EXIT POINT] ${methodSignature} Returned: ${retval}`);
|
||||
console.log("~".repeat(80));
|
||||
}
|
||||
});
|
||||
|
||||
hooksCount++;
|
||||
|
||||
} catch (e) {
|
||||
// console.error(`Error hooking ${className}.${methodName}: ${e.message}`);
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`[+] 总共挂钩了 ${hooksCount} 个方法。开始在微信中发送/接收消息。`);
|
||||
}
|
||||
|
||||
// 启动挂钩
|
||||
hookWeChatMethods();
|
||||
@@ -1,108 +0,0 @@
|
||||
const mod = Process.getModuleByName("WeChat");
|
||||
|
||||
|
||||
function memoGet(p) {
|
||||
p = "0x" + p;
|
||||
const idaAddr = ptr(p);
|
||||
MemoryAccessMonitor.enable(
|
||||
{
|
||||
base: idaAddr,
|
||||
size: 0x10 // buffer 大小
|
||||
},
|
||||
{
|
||||
onAccess(details) {
|
||||
console.log("Access by:", details.from);
|
||||
if (details.from.compare(mod.base) > 0 && details.from.compare(mod.base.add(mod.size)) < 0) {
|
||||
console.log("dump idaAddr", 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 < 30; i++) {
|
||||
try {
|
||||
if (args[i].isNull()) {
|
||||
continue;
|
||||
}
|
||||
// console.log(`\n[+] arg${i} ${args[i]}`);
|
||||
|
||||
if (checkValid(args[i])) {
|
||||
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 (checkValid(retval)) {
|
||||
console.log(hexdump(retval, {
|
||||
offset: 0,
|
||||
length: 40
|
||||
}));
|
||||
}
|
||||
} catch (_) {
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function checkValid(p) {
|
||||
if (p.isNull()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!p.and(0x7).isNull()) {
|
||||
return false;
|
||||
}
|
||||
if (p.compare(ptr("0x600000000000")) >= 0 && p.compare(ptr("0x700000000000")) < 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
const keyword = "mmmmm";
|
||||
|
||||
const addrs = ["600001EF17DA"]
|
||||
for (let addr of addrs) {
|
||||
memoGet(addr);
|
||||
}
|
||||
|
||||
console.log(keyword);
|
||||
console.log(addrs);
|
||||
@@ -1,21 +0,0 @@
|
||||
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) {
|
||||
}
|
||||
});
|
||||
@@ -1,63 +0,0 @@
|
||||
const mod = Process.getModuleByName("WeChat");
|
||||
const realAddr = ptr("0x105835e84").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