mirror of
https://github.com/yincongcyincong/wechat_chatter.git
synced 2026-07-15 10:26:52 +08:00
update 4.1.7.55
This commit is contained in:
@@ -25,7 +25,7 @@ hook2是对Req2Buf这个函数进行消息体注入,因为hook1触发的时候
|
||||
|
||||
hook4是在Req2Buf,清除掉消息体的内容,因为后序在OnTaskEnd会回收内存,如果我这边消息体还在整个的指针上就会被清除,但是这个线程不认识这块内存,整个程序就会crash。
|
||||
|
||||
查看:./frida/succ.js
|
||||
根据release中对应的微信版本使用
|
||||
|
||||
## 图片消息
|
||||
```
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
触发 STNManager__MMStartTask
|
||||
图片hook: startUploadMedia, OnUploadCompleted
|
||||
触发 STNManager__MMStartTask (ida搜 MMStartTask)
|
||||
图片hook: startUploadMedia (ida搜), OnUploadCompleted (ce查)
|
||||
startUploadMedia 上传图片,OnUploadCompleted 上传图片完成后的回调
|
||||
|
||||
WeChatExt中会有导致idapro出问题的代码
|
||||
+28
-28
@@ -160,20 +160,20 @@ function generateBytes(n) {
|
||||
// 双方公共使用的地址
|
||||
var triggerX1Payload;
|
||||
var triggerX0;
|
||||
var req2bufEnterAddr = baseAddr.add(0x35CEDBC);
|
||||
var req2bufExitAddr = baseAddr.add(0x35CFF94);
|
||||
var sendFuncAddr = baseAddr.add(0x4A49BC4);
|
||||
var req2bufEnterAddr = baseAddr.add(0x36F1614);
|
||||
var req2bufExitAddr = baseAddr.add(0x36F27EC);
|
||||
var sendFuncAddr = baseAddr.add(0x47F1888);
|
||||
var insertMsgAddr = ptr(0);
|
||||
var sendMsgType = "";
|
||||
|
||||
// 图片消息全局变量
|
||||
var uploadImageAddr = baseAddr.add(0x47D5D64);
|
||||
var imgProtobufAddr = baseAddr.add(0x237DFE0);
|
||||
var patchImgProtobufFunc1 = baseAddr.add(0x237DF9C)
|
||||
var patchImgProtobufFunc2 = baseAddr.add(0x237DFBC);
|
||||
var imgProtobufDeleteAddr = baseAddr.add(0x237DFF8);
|
||||
var CndOnCompleteAddr = baseAddr.add(0x358D98C);
|
||||
var imgMessageCallbackFunc1 = baseAddr.add(0x865D680);
|
||||
var uploadImageAddr = baseAddr.add(0x4938E08);
|
||||
var imgProtobufAddr = baseAddr.add(0x2455574);
|
||||
var patchImgProtobufFunc1 = baseAddr.add(0x2455530)
|
||||
var patchImgProtobufFunc2 = baseAddr.add(0x2455550);
|
||||
var imgProtobufDeleteAddr = baseAddr.add(0x245558C);
|
||||
var CndOnCompleteAddr = baseAddr.add(0x36B03A0);
|
||||
var imgMessageCallbackFunc1 = baseAddr.add(0x8781AF8);
|
||||
|
||||
var uploadImageX1;
|
||||
var imgCgiAddr = ptr(0);
|
||||
@@ -182,9 +182,9 @@ var imgMessageAddr = ptr(0);
|
||||
var imgProtoX1PayloadAddr = ptr(0);
|
||||
var uploadGlobalX0 = ptr(0)
|
||||
var uploadFunc1Addr = ptr(0)
|
||||
var uploadFunc1 = baseAddr.add(0x086EEB8C8)
|
||||
var uploadFunc1 = ptr(0)
|
||||
var uploadFunc2Addr = ptr(0)
|
||||
var uploadFunc2 = baseAddr.add(0x086E32AB0)
|
||||
var uploadFunc2 = ptr(0)
|
||||
var imageIdAddr = ptr(0)
|
||||
var md5Addr = ptr(0)
|
||||
var uploadAesKeyAddr = ptr(0)
|
||||
@@ -732,7 +732,7 @@ function patchCdnOnComplete() {
|
||||
setImmediate(patchCdnOnComplete)
|
||||
|
||||
function attachGetCallbackFromWrapper() {
|
||||
Interceptor.attach(baseAddr.add(0x47A3828), {
|
||||
Interceptor.attach(baseAddr.add(0x49068CC), {
|
||||
onEnter: function (args) {
|
||||
const tmpFileId = this.context.x1.readPointer().readUtf8String();
|
||||
const fileId = imageIdAddr.readUtf8String();
|
||||
@@ -742,25 +742,25 @@ function attachGetCallbackFromWrapper() {
|
||||
}
|
||||
|
||||
console.log("[+] GetCallbackFromWrapper x8: " + this.context.x8);
|
||||
uploadCallback.add(0x10).writePointer(baseAddr.add(0x358D1A8));
|
||||
uploadCallback.add(0x10).writePointer(baseAddr.add(0x36AFFEC));
|
||||
this.context.x8 = uploadCallback;
|
||||
}
|
||||
})
|
||||
|
||||
Interceptor.attach(baseAddr.add(0x47A3E24), {
|
||||
onEnter: function (args) {
|
||||
const tmpFileId = this.context.x1.readPointer().readUtf8String();
|
||||
const fileId = imageIdAddr.readUtf8String();
|
||||
if (tmpFileId !== fileId) {
|
||||
console.log("[+] OnComplete tmpFileId: " + tmpFileId + " fileId: " + fileId);
|
||||
return
|
||||
}
|
||||
|
||||
console.log("[+] OnComplete x8: " + this.context.x8);
|
||||
uploadCallback.add(0x30).writePointer(baseAddr.add(0x358E398));
|
||||
this.context.x8 = uploadCallback;
|
||||
}
|
||||
})
|
||||
// Interceptor.attach(baseAddr.add(0x47A3E24), {
|
||||
// onEnter: function (args) {
|
||||
// const tmpFileId = this.context.x1.readPointer().readUtf8String();
|
||||
// const fileId = imageIdAddr.readUtf8String();
|
||||
// if (tmpFileId !== fileId) {
|
||||
// console.log("[+] OnComplete tmpFileId: " + tmpFileId + " fileId: " + fileId);
|
||||
// return
|
||||
// }
|
||||
//
|
||||
// console.log("[+] OnComplete x8: " + this.context.x8);
|
||||
// uploadCallback.add(0x30).writePointer(baseAddr.add(0x358E398));
|
||||
// this.context.x8 = uploadCallback;
|
||||
// }
|
||||
// })
|
||||
}
|
||||
|
||||
setImmediate(attachGetCallbackFromWrapper);
|
||||
|
||||
+1
-2
@@ -3,7 +3,7 @@ if (!baseAddr) {
|
||||
console.error("[!] 找不到 WeChat 模块基址,请检查进程名。");
|
||||
}
|
||||
|
||||
var buf2RespAddr = baseAddr.add(0x35F4B58)
|
||||
var buf2RespAddr = baseAddr.add(0x37173B0)
|
||||
|
||||
// -------------------------接收消息分区-------------------------
|
||||
function setReceiver() {
|
||||
@@ -11,7 +11,6 @@ function setReceiver() {
|
||||
// 3. 开始拦截
|
||||
Interceptor.attach(buf2RespAddr, {
|
||||
onEnter: function (args) {
|
||||
console.log("[*] 拦截到消息发送");
|
||||
const currentPtr = this.context.x1;
|
||||
let start = 0x1e;
|
||||
let senderLen = currentPtr.add(start).readU8();
|
||||
|
||||
+7
-7
@@ -78,23 +78,23 @@ function patchString(addr, plainStr) {
|
||||
// -------------------------全局变量分区-------------------------
|
||||
|
||||
// 文本消息全局变量
|
||||
var protobufAddr = baseAddr.add(0x2387280);
|
||||
var patchTextProtobufAddr = baseAddr.add(0x238725C);
|
||||
var PatchTextProtobufDeleteAddr = baseAddr.add(0x2387298);
|
||||
var protobufAddr = baseAddr.add(0x245E9B0);
|
||||
var patchTextProtobufAddr = baseAddr.add(0x245E98C);
|
||||
var PatchTextProtobufDeleteAddr = baseAddr.add(0x245E9C8);
|
||||
var textCgiAddr = ptr(0);
|
||||
var sendTextMessageAddr = ptr(0);
|
||||
var textMessageAddr = ptr(0);
|
||||
var textProtoX1PayloadAddr = ptr(0);
|
||||
var sendMessageCallbackFunc = ptr(0);
|
||||
var messageCallbackFunc1 = baseAddr.add(0x865DBB8);
|
||||
var messageCallbackFunc1 = baseAddr.add(0x8781010);
|
||||
|
||||
|
||||
// 双方公共使用的地址
|
||||
var triggerX1Payload;
|
||||
var triggerX0;
|
||||
var req2bufEnterAddr = baseAddr.add(0x35CEDBC);
|
||||
var req2bufExitAddr = baseAddr.add(0x35CFF94);
|
||||
var sendFuncAddr = baseAddr.add(0x4A49BC4);
|
||||
var req2bufEnterAddr = baseAddr.add(0x36F1614);
|
||||
var req2bufExitAddr = baseAddr.add(0x36F27EC);
|
||||
var sendFuncAddr = baseAddr.add(0x47F1888);
|
||||
var insertMsgAddr = ptr(0);
|
||||
var sendMsgType = "";
|
||||
|
||||
|
||||
@@ -1,47 +0,0 @@
|
||||
/**
|
||||
* 构造内存数据并调用 sub_10481C304
|
||||
*/
|
||||
function callTargetFunction() {
|
||||
// 1. 查找函数地址 (请确保模块名正确,这里假设是 WeChat)
|
||||
const moduleName = "WeChat";
|
||||
const sub_10481C304_addr = Module.findBaseAddress(moduleName).add(0x481C304);
|
||||
const sub_10481C304 = new NativeFunction(sub_10481C304_addr, 'void', ['pointer']);
|
||||
|
||||
// 2. 准备原始字节数据 (Hex 形式)
|
||||
// 注意:0x18 偏移处的 8 字节(原数据 60 E1 39 78 05 00 00 00)会被动态生成的指针覆盖
|
||||
const rawData = [
|
||||
0x00, 0x00, 0x00, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // 0x18 指针位置
|
||||
0x05, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x30, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x80, 0x00, 0x01, 0x11, 0x01, 0x00, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00,
|
||||
0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
|
||||
0x00, 0xAA, 0xAA, 0xAA, 0xFF, 0xFF, 0xFF, 0xFF, 0xAA, 0xAA, 0xAA, 0xAA, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x0A, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
|
||||
];
|
||||
|
||||
// 3. 申请结构体内存
|
||||
const structPtr = Memory.alloc(rawData.length);
|
||||
structPtr.writeByteArray(rawData);
|
||||
|
||||
// 4. 申请字符串内存并写入指针 (偏移 0x18)
|
||||
const cgiPath = "/cgi-bin/micromsg-bin/newsendmsg";
|
||||
const pathPtr = Memory.allocUtf8String(cgiPath);
|
||||
|
||||
// 将字符串地址写入结构体的 0x18 偏移处 (64位系统占8字节)
|
||||
structPtr.add(0x18).writePointer(pathPtr);
|
||||
|
||||
console.log("[+] 内存结构体已准备完毕: " + structPtr);
|
||||
console.log("[+] 字符串地址: " + pathPtr + " 内容: " + cgiPath);
|
||||
|
||||
// 5. 调用函数
|
||||
try {
|
||||
sub_10481C304(structPtr);
|
||||
console.log("[+] sub_10481C304 调用成功!");
|
||||
|
||||
console.log("[*] 结构体内存布局 (调用后):");
|
||||
console.log(hexdump(structPtr, { offset: 0, length: rawData.length, header: true, ansi: true }));
|
||||
|
||||
} catch (e) {
|
||||
console.log("[-] 调用出错: " + e);
|
||||
}
|
||||
}
|
||||
@@ -220,7 +220,6 @@ var sendTextMessageAddr = ptr(0);
|
||||
var textMessageAddr = ptr(0);
|
||||
var textProtoX1PayloadAddr = ptr(0);
|
||||
var sendMessageCallbackFunc = baseAddr.add({{.sendMessageCallbackFunc}});
|
||||
var messageCallbackFunc1 = ptr(0);
|
||||
|
||||
|
||||
// 双方公共使用的地址
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
{
|
||||
"protobufAddr": "",
|
||||
"patchTextProtobufAddr": "",
|
||||
"PatchTextProtobufDeleteAddr": "",
|
||||
"sendMessageCallbackFunc": "",
|
||||
"sendFuncAddr": "",
|
||||
"req2bufEnterAddr": "",
|
||||
"req2bufExitAddr": "",
|
||||
"protobufAddr": "0x245E9B0",
|
||||
"patchTextProtobufAddr": "0x245E98C",
|
||||
"PatchTextProtobufDeleteAddr": "0x245E9C8",
|
||||
"sendMessageCallbackFunc": "0x8781010",
|
||||
"sendFuncAddr": "0x47F1888",
|
||||
"req2bufEnterAddr": "0x36F1614",
|
||||
"req2bufExitAddr": "0x36F27EC",
|
||||
"imgProtobufAddr": "",
|
||||
"patchImgProtobufFunc1": "",
|
||||
"patchImgProtobufFunc2": " ",
|
||||
"patchImgProtobufFunc2": "",
|
||||
"imgProtobufDeleteAddr": "",
|
||||
"imgMessageCallbackFunc1": "",
|
||||
"uploadImageAddr": "",
|
||||
"CndOnCompleteAddr": "",
|
||||
"sendImgMessageCallbackFunc": "",
|
||||
"buf2RespAddr": "",
|
||||
"imgMessageCallbackFunc1": "",
|
||||
"buf2RespAddr": "0x37173B0",
|
||||
"uploadGetCallbackWrapperAddr": "",
|
||||
"uploadGetCallbackWrapperFuncAddr": "",
|
||||
"uploadOnCompleteAddr": "",
|
||||
|
||||
Reference in New Issue
Block a user