[v9] 上传 wechat_send_hook.js
This commit is contained in:
135
sdk/agent/hook/wechat_send_hook.js
Normal file
135
sdk/agent/hook/wechat_send_hook.js
Normal file
@@ -0,0 +1,135 @@
|
||||
// 微信8.0.56 消息真实发送Hook脚本
|
||||
// 策略:Hook OkHttp网络层,捕获微信发送消息的真实HTTP请求,然后重放
|
||||
|
||||
'use strict';
|
||||
|
||||
var capturedSendRequests = [];
|
||||
var sendClassFound = null;
|
||||
var sendMethodFound = null;
|
||||
var isReady = false;
|
||||
|
||||
// 等待微信完全初始化
|
||||
Java.perform(function() {
|
||||
|
||||
// 1. Hook OkHttp3 - 捕获所有网络请求
|
||||
try {
|
||||
var OkHttpClient = Java.use('okhttp3.OkHttpClient');
|
||||
var Request = Java.use('okhttp3.Request');
|
||||
var RequestBody = Java.use('okhttp3.RequestBody');
|
||||
|
||||
// Hook newCall
|
||||
OkHttpClient.newCall.implementation = function(request) {
|
||||
var url = request.url().toString();
|
||||
if (url.indexOf('weixin') > -1 || url.indexOf('tencent') > -1 || url.indexOf('wx') > -1) {
|
||||
var method = request.method();
|
||||
var body = '';
|
||||
try {
|
||||
var rb = request.body();
|
||||
if (rb != null) {
|
||||
var buf = Java.use('okio.Buffer').$new();
|
||||
rb.writeTo(buf);
|
||||
body = buf.readUtf8();
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
capturedSendRequests.push({
|
||||
url: url,
|
||||
method: method,
|
||||
body: body.substring(0, 500),
|
||||
time: Date.now()
|
||||
});
|
||||
|
||||
if (capturedSendRequests.length > 50) {
|
||||
capturedSendRequests.shift();
|
||||
}
|
||||
}
|
||||
return this.newCall(request);
|
||||
};
|
||||
send({type: 'log', data: '[OK] OkHttp3 hooked'});
|
||||
} catch(e) {
|
||||
send({type: 'log', data: '[SKIP] OkHttp3: ' + e.message});
|
||||
}
|
||||
|
||||
// 2. Hook 微信MMServiceManager - 找到消息发送服务
|
||||
try {
|
||||
var MMServiceManager = Java.use('com.tencent.mm.sdk.platformtools.MMServiceManager');
|
||||
send({type: 'log', data: '[OK] MMServiceManager found'});
|
||||
} catch(e) {
|
||||
send({type: 'log', data: '[SKIP] MMServiceManager: ' + e.message});
|
||||
}
|
||||
|
||||
// 3. Hook XMPP/MMProtocol - 微信自定义协议
|
||||
var xmppClasses = [
|
||||
'com.tencent.mm.protocal.MMProtocal',
|
||||
'com.tencent.mm.protocal.b',
|
||||
'com.tencent.mm.network.MMNetworkService',
|
||||
'com.tencent.mm.network.b',
|
||||
'com.tencent.mm.xmpp.XMPPService',
|
||||
];
|
||||
|
||||
xmppClasses.forEach(function(cls) {
|
||||
try {
|
||||
Java.use(cls);
|
||||
send({type: 'log', data: '[FOUND] ' + cls});
|
||||
} catch(e) {}
|
||||
});
|
||||
|
||||
// 4. 扫描所有已加载的类,找到包含"sendMsg"或"sendMessage"的类
|
||||
// 使用精准枚举而不是全量扫描
|
||||
var targetPatterns = [
|
||||
'com.tencent.mm.model',
|
||||
'com.tencent.mm.messenger',
|
||||
'com.tencent.mm.modelmulti',
|
||||
];
|
||||
|
||||
// 5. Hook SQLiteDatabase.execSQL - 捕获消息写入时的调用栈
|
||||
try {
|
||||
var WCDB = Java.use('com.tencent.wcdb.database.SQLiteDatabase');
|
||||
|
||||
WCDB.execSQL.overload('java.lang.String').implementation = function(sql) {
|
||||
if (sql && sql.indexOf('message') > -1 && sql.indexOf('INSERT') > -1) {
|
||||
var stack = Java.use('android.util.Log').getStackTraceString(
|
||||
Java.use('java.lang.Exception').$new('STACK')
|
||||
);
|
||||
send({type: 'msg_insert_stack', data: {sql: sql.substring(0, 200), stack: stack.substring(0, 2000)}});
|
||||
}
|
||||
return this.execSQL(sql);
|
||||
};
|
||||
send({type: 'log', data: '[OK] WCDB.execSQL hooked'});
|
||||
} catch(e) {
|
||||
send({type: 'log', data: '[SKIP] WCDB.execSQL: ' + e.message});
|
||||
}
|
||||
|
||||
// 6. Hook insert方法
|
||||
try {
|
||||
var WCDB2 = Java.use('com.tencent.wcdb.database.SQLiteDatabase');
|
||||
WCDB2.insert.overload('java.lang.String', 'java.lang.String', 'android.content.ContentValues').implementation = function(table, nullColumnHack, values) {
|
||||
if (table && table.indexOf('message') > -1) {
|
||||
var stack = Java.use('android.util.Log').getStackTraceString(
|
||||
Java.use('java.lang.Exception').$new('STACK')
|
||||
);
|
||||
send({type: 'msg_insert_stack', data: {table: table, stack: stack.substring(0, 3000)}});
|
||||
}
|
||||
return this.insert(table, nullColumnHack, values);
|
||||
};
|
||||
send({type: 'log', data: '[OK] WCDB.insert hooked'});
|
||||
} catch(e) {
|
||||
send({type: 'log', data: '[SKIP] WCDB.insert: ' + e.message});
|
||||
}
|
||||
|
||||
isReady = true;
|
||||
send({type: 'ready', data: 'Hook脚本已就绪,请在手机上发送一条微信消息'});
|
||||
});
|
||||
|
||||
rpc.exports = {
|
||||
getCapturedRequests: function() {
|
||||
return capturedSendRequests;
|
||||
},
|
||||
isReady: function() {
|
||||
return isReady;
|
||||
},
|
||||
clearRequests: function() {
|
||||
capturedSendRequests = [];
|
||||
return true;
|
||||
}
|
||||
};
|
||||
Reference in New Issue
Block a user