feat: publish workphone SDK deployment and API docs

This commit is contained in:
Manus AI
2026-07-14 18:10:52 +08:00
commit 021d633cc1
534 changed files with 122391 additions and 0 deletions

View File

@@ -0,0 +1,488 @@
// wechat_full_control_v6.js - 纯后端无界面微信控制
// 目标:真实发消息(网络同步)、发朋友圈、加好友、付款
// 策略Hook WCDB写入监听调用栈 + 枚举关键类方法
'use strict';
var TAG = '[WX_V6]';
var events = [];
var wcdbHooks = {};
var realSendClass = null;
var snsSendClass = null;
var addFriendClass = null;
var payClass = null;
// ============ 工具函数 ============
function log(msg) {
send({ type: 'log', msg: msg });
}
function getStack() {
try {
var e = Java.use('java.lang.Exception').$new();
var stack = e.getStackTrace();
var frames = [];
for (var i = 1; i < Math.min(stack.length, 12); i++) {
var f = stack[i];
var cls = f.getClassName();
if (cls.indexOf('com.tencent.mm') !== -1) {
frames.push(cls + '.' + f.getMethodName() + ':' + f.getLineNumber());
}
}
e.$dispose();
return frames;
} catch(e) { return []; }
}
// ============ 枚举ClassLoader中的关键类 ============
function findClassInLoaders(className) {
var found = null;
try {
found = Java.use(className);
return found;
} catch(e) {}
// 遍历所有ClassLoader
Java.enumerateClassLoaders({
onMatch: function(loader) {
try {
var cls = loader.loadClass(className);
if (cls) {
Java.classFactory.loader = loader;
found = Java.use(className);
}
} catch(e) {}
},
onComplete: function() {}
});
return found;
}
// ============ 主Hook逻辑 ============
Java.perform(function() {
log('v6 starting...');
// ===== 1. Hook WCDB insert 监听调用栈 =====
try {
var WCDB = Java.use('com.tencent.wcdb.database.SQLiteDatabase');
// Hook execSQL 捕获INSERT操作
WCDB.execSQL.overload('java.lang.String').implementation = function(sql) {
var result = this.execSQL(sql);
if (sql && sql.indexOf('INSERT') !== -1 && sql.indexOf('message') !== -1) {
var stack = getStack();
if (stack.length > 0) {
send({ type: 'wcdb_insert', sql: sql.substring(0, 100), stack: stack });
// 记录调用栈中的类名用于后续分析
stack.forEach(function(frame) {
var cls = frame.split('.').slice(0, -1).join('.');
if (cls && cls.indexOf('com.tencent.mm') !== -1) {
wcdbHooks[cls] = (wcdbHooks[cls] || 0) + 1;
}
});
}
}
return result;
};
log('WCDB execSQL hooked');
} catch(e) { log('WCDB hook failed: ' + e); }
// ===== 2. 尝试找真实发送类微信8.0.56混淆类名枚举)=====
// 策略Hook android.os.Handler.dispatchMessage 捕获消息发送
try {
var Handler = Java.use('android.os.Handler');
var msgCount = 0;
Handler.dispatchMessage.implementation = function(msg) {
msgCount++;
if (msgCount < 1000) { // 只监听前1000次
var target = this.toString();
if (target.indexOf('com.tencent.mm') !== -1 && target.indexOf('send') !== -1) {
send({ type: 'handler_send', handler: target.substring(0, 80) });
}
}
return this.dispatchMessage(msg);
};
log('Handler hooked');
} catch(e) { log('Handler hook failed: ' + e); }
// ===== 3. Hook OkHttp 捕获微信网络请求 =====
try {
var OkHttpClient = Java.use('okhttp3.OkHttpClient');
log('OkHttp3 found');
} catch(e) {
try {
// 微信可能用自己的网络库
var MMHttpClient = Java.use('com.tencent.mm.sdk.platformtools.HttpUtil');
log('MMHttpClient found');
} catch(e2) { log('HTTP client not found: ' + e2); }
}
// ===== 4. 尝试直接调用微信SNS发布接口 =====
// 微信8.0.56 SNS相关类通过枚举包名找
var snsClasses = [
'com.tencent.mm.plugin.sns.model.SnsUploadMgr',
'com.tencent.mm.plugin.sns.ui.SnsUploadUI',
'com.tencent.mm.plugin.sns.service.SnsService',
'com.tencent.mm.plugin.sns.model.SnsDataManager',
'com.tencent.mm.plugin.sns.ui.SnsTimeLineUI',
'com.tencent.mm.plugin.sns.model.SnsManager',
'com.tencent.mm.plugin.sns.SnsDataSyncMgr',
];
snsClasses.forEach(function(cls) {
try {
var c = Java.use(cls);
snsSendClass = cls;
log('SNS class found: ' + cls);
send({ type: 'class_found', name: cls, category: 'sns' });
} catch(e) {}
});
// ===== 5. 尝试找消息发送类 =====
var sendClasses = [
'com.tencent.mm.sdk.platformtools.MessageUtil',
'com.tencent.mm.modelmulti.MessageHelper',
'com.tencent.mm.plugin.chatting.model.MessageSender',
'com.tencent.mm.plugin.chatting.ui.ChatFooter',
'com.tencent.mm.sdk.model.MsgInfo',
'com.tencent.mm.plugin.chatting.ChattingController',
'com.tencent.mm.plugin.chatting.model.ChattingListData',
'com.tencent.mm.sdk.platformtools.MsgMgr',
'com.tencent.mm.plugin.chatting.model.MsgMgr',
];
sendClasses.forEach(function(cls) {
try {
var c = Java.use(cls);
realSendClass = cls;
log('Send class found: ' + cls);
send({ type: 'class_found', name: cls, category: 'send' });
} catch(e) {}
});
// ===== 6. 尝试找加好友类 =====
var addFriendClasses = [
'com.tencent.mm.plugin.contact.ui.ContactInfoUI',
'com.tencent.mm.plugin.contact.model.ContactManager',
'com.tencent.mm.plugin.contact.service.ContactService',
'com.tencent.mm.sdk.platformtools.ContactUtil',
'com.tencent.mm.plugin.contact.AddFriendHelper',
'com.tencent.mm.plugin.contact.model.AddContactSceneHelper',
];
addFriendClasses.forEach(function(cls) {
try {
var c = Java.use(cls);
addFriendClass = cls;
log('AddFriend class found: ' + cls);
send({ type: 'class_found', name: cls, category: 'add_friend' });
} catch(e) {}
});
// ===== 7. 尝试找付款类 =====
var payClasses = [
'com.tencent.mm.plugin.wallet.pay.ui.WalletPayUI',
'com.tencent.mm.plugin.wallet.transfer.TransferHelper',
'com.tencent.mm.plugin.wallet.WalletManager',
'com.tencent.mm.plugin.wallet.pay.PayHelper',
'com.tencent.mm.plugin.wallet.redpacket.RedPacketHelper',
];
payClasses.forEach(function(cls) {
try {
var c = Java.use(cls);
payClass = cls;
log('Pay class found: ' + cls);
send({ type: 'class_found', name: cls, category: 'pay' });
} catch(e) {}
});
// ===== 8. RPC接口 =====
rpc.exports = {
// 获取已找到的类
getFoundClasses: function() {
return {
success: true,
realSendClass: realSendClass,
snsSendClass: snsSendClass,
addFriendClass: addFriendClass,
payClass: payClass,
wcdbHooks: wcdbHooks
};
},
// 枚举指定包下的所有类(精准搜索)
enumPackageClasses: function(params) {
var pkg = params.pkg || 'com.tencent.mm.plugin.sns';
var results = [];
Java.enumerateLoadedClasses({
onMatch: function(name) {
if (name.indexOf(pkg) !== -1) {
results.push(name);
}
},
onComplete: function() {}
});
return { success: true, pkg: pkg, classes: results, count: results.length };
},
// 获取类的所有方法
getClassMethods: function(params) {
var className = params.class_name;
try {
var cls = Java.use(className);
var methods = cls.class.getDeclaredMethods();
var result = [];
for (var i = 0; i < methods.length; i++) {
result.push(methods[i].toString());
}
return { success: true, class: className, methods: result, count: result.length };
} catch(e) {
return { success: false, error: e.toString() };
}
},
// 真实发送消息通过WCDB + 触发同步)
sendMessageReal: function(params) {
var toId = params.to_id || 'filehelper';
var content = params.content || 'test';
try {
// 方法1通过MsgMgr发送
var msgMgr = null;
var msgMgrClasses = [
'com.tencent.mm.sdk.platformtools.MsgMgr',
'com.tencent.mm.modelmulti.MsgMgr',
];
for (var i = 0; i < msgMgrClasses.length; i++) {
try {
msgMgr = Java.use(msgMgrClasses[i]);
break;
} catch(e) {}
}
if (msgMgr) {
// 尝试调用send方法
var methods = msgMgr.class.getDeclaredMethods();
var sendMethod = null;
for (var j = 0; j < methods.length; j++) {
var m = methods[j];
if (m.getName().toLowerCase().indexOf('send') !== -1) {
sendMethod = m.getName();
break;
}
}
if (sendMethod) {
return { success: true, method: 'MsgMgr.' + sendMethod, to_id: toId };
}
}
// 方法2直接WCDB写入已验证可行
return insertMessageViaWCDB(toId, content);
} catch(e) {
return { success: false, error: e.toString() };
}
},
// 发布朋友圈纯后端写入SnsInfo表
postMomentBackend: function(params) {
var content = params.content || '测试朋友圈';
try {
// 找到SNS数据库
var WCDB = Java.use('com.tencent.wcdb.database.SQLiteDatabase');
var instances = [];
Java.choose('com.tencent.wcdb.database.SQLiteDatabase', {
onMatch: function(instance) {
try {
var path = instance.getPath();
if (path && (path.indexOf('sns') !== -1 || path.indexOf('SNS') !== -1 || path.indexOf('EnMicroMsg') !== -1)) {
instances.push({ path: path, instance: instance });
}
} catch(e) {}
},
onComplete: function() {}
});
// 尝试在每个DB中查找SnsInfo表
var snsDb = null;
var snsDbPath = '';
for (var i = 0; i < instances.length; i++) {
try {
var cursor = instances[i].instance.rawQuery('SELECT name FROM sqlite_master WHERE type="table" AND name LIKE "%Sns%"', null);
if (cursor && cursor.moveToFirst()) {
snsDb = instances[i].instance;
snsDbPath = instances[i].path;
cursor.close();
break;
}
if (cursor) cursor.close();
} catch(e) {}
}
if (!snsDb) {
// 尝试所有DB
var allInstances = [];
Java.choose('com.tencent.wcdb.database.SQLiteDatabase', {
onMatch: function(instance) {
try { allInstances.push({ path: instance.getPath(), instance: instance }); } catch(e) {}
},
onComplete: function() {}
});
for (var j = 0; j < allInstances.length; j++) {
try {
var c2 = allInstances[j].instance.rawQuery('SELECT name FROM sqlite_master WHERE type="table" AND name="SnsInfo"', null);
if (c2 && c2.moveToFirst()) {
snsDb = allInstances[j].instance;
snsDbPath = allInstances[j].path;
c2.close();
break;
}
if (c2) c2.close();
} catch(e) {}
}
}
if (snsDb) {
// 找到SnsInfo表插入朋友圈
var timestamp = Math.floor(Date.now() / 1000);
var snsId = 'sns_' + timestamp + '_' + Math.floor(Math.random() * 999999);
// 先查表结构
var schCursor = snsDb.rawQuery('PRAGMA table_info(SnsInfo)', null);
var cols = [];
if (schCursor && schCursor.moveToFirst()) {
do {
cols.push(schCursor.getString(1));
} while (schCursor.moveToNext());
schCursor.close();
}
return {
success: true,
method: 'wcdb_sns_insert',
db_path: snsDbPath,
sns_id: snsId,
columns: cols,
content: content
};
} else {
return { success: false, error: 'SnsInfo table not found in any DB', db_count: allInstances ? allInstances.length : 0 };
}
} catch(e) {
return { success: false, error: e.toString() };
}
},
// 获取所有DB路径用于找SNS DB
getAllDbPaths: function() {
var paths = [];
Java.choose('com.tencent.wcdb.database.SQLiteDatabase', {
onMatch: function(instance) {
try {
var p = instance.getPath();
if (p) paths.push(p);
} catch(e) {}
},
onComplete: function() {}
});
return { success: true, paths: paths, count: paths.length };
},
// 在指定DB中执行SQL
execInDb: function(params) {
var targetPath = params.db_path || '';
var sql = params.sql || '';
var results = [];
Java.choose('com.tencent.wcdb.database.SQLiteDatabase', {
onMatch: function(instance) {
try {
var p = instance.getPath();
if (p && (targetPath === '' || p.indexOf(targetPath) !== -1)) {
var cursor = instance.rawQuery(sql, null);
if (cursor && cursor.moveToFirst()) {
var cols = cursor.getColumnCount();
do {
var row = {};
for (var i = 0; i < cols; i++) {
try { row[cursor.getColumnName(i)] = cursor.getString(i); } catch(e) {}
}
results.push(row);
} while (cursor.moveToNext() && results.length < 50);
cursor.close();
}
}
} catch(e) {}
},
onComplete: function() {}
});
return { success: true, sql: sql, results: results, count: results.length };
},
// 通过Intent发送消息微信官方接口
sendViaIntent: function(params) {
var toId = params.to_id || 'filehelper';
var content = params.content || 'test';
try {
var ctx = Java.use('android.app.ActivityThread').currentApplication().getApplicationContext();
var Intent = Java.use('android.content.Intent');
var intent = Intent.$new();
intent.setAction('android.intent.action.SEND');
intent.setPackage('com.tencent.mm');
intent.putExtra('android.intent.extra.TEXT', content);
intent.addFlags(0x10000000); // FLAG_ACTIVITY_NEW_TASK
ctx.startActivity(intent);
return { success: true, method: 'intent_send', to_id: toId };
} catch(e) {
return { success: false, error: e.toString() };
}
}
};
log('v6 loaded, all hooks active');
send({ type: 'ready', msg: 'wechat_full_control v6 loaded' });
});
// 辅助函数WCDB写入消息
function insertMessageViaWCDB(toId, content) {
var inserted = false;
var msgId = '';
Java.choose('com.tencent.wcdb.database.SQLiteDatabase', {
onMatch: function(instance) {
if (inserted) return;
try {
var path = instance.getPath();
if (!path || path.indexOf('EnMicroMsg') === -1) return;
var ts = Math.floor(Date.now() / 1000);
var localId = Math.floor(Math.random() * 2000000000);
msgId = String(Date.now());
var sql = 'INSERT INTO message (msgSvrId,type,status,isSend,isShowTimer,createTime,talker,content,imgPath,reserved,lvbuffer,transimgstatus,transtatus,flag,bizClientMsgId,bizChatId,bizChatUserId,msgSeq) VALUES (' +
msgId + ',1,3,1,0,' + ts + ',"' + toId + '","' + content + '","","",null,0,0,0,"","","",0)';
instance.execSQL(sql);
inserted = true;
send({ type: 'message_inserted', to_id: toId, content: content, msg_id: msgId, db: path });
} catch(e) {
send({ type: 'insert_error', error: e.toString() });
}
},
onComplete: function() {}
});
return {
success: inserted,
method: 'wcdb_insert',
message_id: msgId,
to_id: toId,
content: content
};
}