finish 8.28

This commit is contained in:
yincong
2026-03-20 09:29:54 +08:00
parent cc48892f62
commit 2f263f4ef6
11 changed files with 130 additions and 288 deletions
+28 -28
View File
@@ -26,16 +26,16 @@ func main() {
initFrida()
}
go SendWorker()
http.HandleFunc("/send_private_msg", sendHandler)
http.HandleFunc("/send_group_msg", sendHandler)
http.HandleFunc("/ws", handleWebSocket)
http.HandleFunc("/test_ws", testWebSocket)
stop := make(chan os.Signal, 1)
signal.Notify(stop, os.Interrupt, syscall.SIGTERM)
go func() {
<-stop
fridaScript.Clean()
@@ -43,13 +43,13 @@ func main() {
device.Clean()
Fatal("正在释放 Frida 资源并退出...")
}()
// 3. 启动服务
Info("HTTP 服务启动在", "host", config.ReceiveHost)
if err := http.ListenAndServe(config.ReceiveHost, nil); err != nil {
Error("服务启动失败", "err", err)
}
}
func initFlag() {
@@ -59,13 +59,13 @@ func initFlag() {
flag.StringVar(&config.FridaGadgetAddr, "gadget_addr", "127.0.0.1:27042", "Gadget 地址: 127.0.0.1:27042 仅当 type 为 gadget 时有效")
flag.StringVar(&config.OnebotToken, "token", "MuseBot", "OneBot Token: MuseBot")
flag.StringVar(&config.ImagePath, "image_path", "", "图片路径: /Users/xxx/Library/Containers/com.tencent.xinWeChat/Data/Documents/xwechat_files/xxx/temp/xxx/2026-01/Img/")
flag.StringVar(&config.WechatConf, "wechat_conf", "../wechat_version/4_1_7_57_mac.json", "微信配置文件路径: ../wechat_version/4_1_6_12_mac.json")
flag.StringVar(&config.WechatConf, "wechat_conf", "../wechat_version/4_1_8_28_mac.json", "微信配置文件路径: ../wechat_version/4_1_6_12_mac.json")
flag.StringVar(&config.ConnType, "conn_type", "http", "连接类型: http | websocket")
flag.IntVar(&config.SendInterval, "send_interval", 1000, "发送间隔: ms")
flag.StringVar(&logLevel, "log_level", "info", "log level")
flag.Parse()
fmt.Println("FridaType", config.FridaType)
fmt.Println("SendURL", config.SendURL)
fmt.Println("ReceiveHost", config.ReceiveHost)
@@ -86,39 +86,39 @@ func initFridaGadget() {
if err != nil {
Fatal("❌ 无法连接 Gadget", err)
}
session, err = device.Attach("Gadget", nil)
if err != nil {
Fatal("❌ 附加失败", err)
}
loadJs()
}
func initFrida() {
var err error
// 1. 获取本地设备管理器
mgr := frida.NewDeviceManager()
// 2. 枚举并获取本地设备 (TypeLocal)
device, err = mgr.DeviceByType(frida.DeviceTypeLocal)
if err != nil {
Fatal("无法获取本地设备", "err", err)
}
pid, err := GetWeChatPID()
if err != nil {
Fatal("未发现正在运行的微信进程")
}
Info("微信进程 PID", "PID", pid)
MonitorProcessExit(pid)
session, err = device.Attach(pid, nil)
if err != nil {
Fatal("Attach 失败 (请检查 SIP 状态或权限)", "err", err)
}
loadJs()
}
@@ -127,35 +127,35 @@ func loadJs() {
if err != nil {
Fatal("读取文件失败", "err", err)
}
// 2. 将 JSON 解析为 Map
var wechatHookConf map[string]interface{}
if err = json.Unmarshal(jsonData, &wechatHookConf); err != nil {
Fatal("解析 JSON 失败", "err", err)
}
codeTemplate, err := os.ReadFile("./script.js")
if err != nil {
Fatal("读取脚本失败", "err", err)
}
tmpl, err := template.New("fridaScript").Parse(string(codeTemplate))
if err != nil {
Fatal("解析模板失败", "err", err)
return
}
var buf bytes.Buffer
err = tmpl.Execute(&buf, wechatHookConf)
if err != nil {
Fatal("执行模板失败", "err", err)
}
script, err := session.CreateScript(buf.String())
if err != nil {
Fatal("创建脚本失败", "err", err)
}
// 打印 JS 里的 console.log
script.On("message", func(rawMsg string) {
defer func() {
@@ -163,16 +163,16 @@ func loadJs() {
Error("message panic", "err", r, "stack", string(debug.Stack()))
}
}()
var msg map[string]interface{}
err = json.Unmarshal([]byte(rawMsg), &msg)
if err != nil {
Error("JSON解析失败", "err", err)
return
}
msgType := msg["type"].(string)
switch msgType {
case "send":
if p, ok := msg["payload"]; ok {
@@ -224,7 +224,7 @@ func loadJs() {
Error("下载失败", "err", err)
}
}
}
}
}
@@ -234,11 +234,11 @@ func loadJs() {
Error("[JS日志报错]", "err", msg["description"], "stack", msg["stack"])
}
})
if err := script.Load(); err != nil {
Fatal("❌ 加载脚本失败", err)
}
fridaScript = script
Info("✅ Frida 已就绪,微信控制通道已打通")
}
+15 -15
View File
@@ -1,5 +1,5 @@
// 1. 获取微信主模块的基地址
var baseAddr = Process.getModuleByName("WeChat").base;
var moduleName = "wechat.dylib";
var baseAddr = Process.findModuleByName(moduleName).base;
if (!baseAddr) {
console.error("[!] 找不到 WeChat 模块基址,请检查进程名。");
}
@@ -260,7 +260,7 @@ function generateBytes(n) {
// 文本消息全局变量
// 文本消息全局变量
var textCallbackFuncAddr = baseAddr.add({{.textCallbackFuncAddr}});
var protobufAddr = textCallbackFuncAddr.add(0x44);
var protobufAddr = textCallbackFuncAddr.add(0x40);
var patchTextProtobufAddr = textCallbackFuncAddr.add(0x20);
var patchTextProtobufByte
var patchTextProtobufDeleteAddr = textCallbackFuncAddr.add(0x5C);
@@ -284,7 +284,7 @@ var buf2RespAddr = baseAddr.add({{.buf2RespAddr}});
// 图片消息全局变量
var imageCallbackFuncAddr = baseAddr.add({{.imageCallbackFuncAddr}});
var imgProtobufAddr = imageCallbackFuncAddr.add(0x54);
var imgProtobufAddr = imageCallbackFuncAddr.add(0x50);
var patchImgProtobufFunc1 = imageCallbackFuncAddr.add(0x10);
var patchImgProtobufFunc1Byte;
var patchImgProtobufFunc2 = imageCallbackFuncAddr.add(0x30);
@@ -294,7 +294,7 @@ var imgProtobufDeleteAddrByte;
// 视频消息全局变量
var videoCallbackFuncAddr = baseAddr.add({{.videoCallbackFuncAddr}});
var videoProtobufAddr = videoCallbackFuncAddr.add(0x54);
var videoProtobufAddr = videoCallbackFuncAddr.add(0x50);
var patchVideoProtobufFunc1 = videoCallbackFuncAddr.add(0x10);
var patchVideoProtobufFunc1Byte;
var patchVideoProtobufFunc2 = videoCallbackFuncAddr.add(0x30);
@@ -577,8 +577,8 @@ function triggerSendTextMessage(taskId, receiver, content, atUser) {
}
}
function AttachSendTextProto() {
Interceptor.attach(sendFuncAddr, {
function AttachSendFunc() {
Interceptor.attach(sendFuncAddr.add(0x10), {
onEnter: function (args) {
if (triggerX1Payload) {
@@ -592,7 +592,7 @@ function AttachSendTextProto() {
})
}
setImmediate(AttachSendTextProto);
setImmediate(AttachSendFunc);
// 拦截 SendTextProto 编码逻辑,注入自定义 Payload
function attachSendTextProto() {
@@ -1707,12 +1707,12 @@ setImmediate(setupDownloadFileDynamic)
function setReceiver() {
Interceptor.attach(buf2RespAddr, {
onEnter: function (args) {
const currentPtr = this.context.x1;
const currentPtr = this.context.x20;
if (currentPtr.add(0).readU8() !== 0x08) {
return
}
const x2 = this.context.x2.toInt32();
const x2 = this.context.x0.toInt32();
// console.log(" [+] currentPtr: ", hexdump(currentPtr, {
// offset: 0,
// length: x2,
@@ -1820,8 +1820,8 @@ function setReceiver() {
Interceptor.attach(downloadFileAddr, {
onEnter: function (args) {
var dataPtr = this.context.x1;
var dataLen = this.context.x2.toInt32();
var dataPtr = this.context.x22;
var dataLen = this.context.x20.toInt32();
var fileId = this.context.sp.add(0x30).readPointer().readUtf8String();
var cdnUrl = this.context.x19.add(0x2F8).readPointer().readUtf8String();
@@ -1841,7 +1841,7 @@ function setReceiver() {
Interceptor.attach(downloadImagAddr, {
onEnter: function (args) {
var dataPtr = this.context.x1;
var dataPtr = this.context.x22;
var dataLen = this.context.x2.toInt32();
var fileId = this.context.x19.add(0x2E0).readPointer().readUtf8String();
var cdnUrl = this.context.x19.add(0x2F8).readPointer().readUtf8String();
@@ -1863,7 +1863,7 @@ function setReceiver() {
Interceptor.attach(downloadVideoAddr, {
onEnter: function (args) {
var dataPtr = this.context.x1;
var dataLen = this.context.x2.toInt32();
var dataLen = this.context.x24.toInt32();
var fileId = this.context.x22.add(0x40).readPointer().readUtf8String();
var cdnUrl = this.context.x22.add(0x58).readPointer().readUtf8String();
@@ -2107,4 +2107,4 @@ function getMessages(content, sender, mediaContent) {
return messages;
}
// -------------------------接收消息分区-------------------------
// -------------------------接收消息分区-------------------------