Mac微信双开

macOS 微信 4.x 双开实战:从踩坑到成功

最近想在 Mac 上同时登两个微信号,发现网上大部分教程已经失效了。微信 4.0 之后引入了更严格的签名校验,老的 open -n 命令、简单的 cp + codesign 三连击都会直接 crash。折腾了一晚上终于跑通,把完整的踩坑过程和最终方案记录下来。

背景:为什么老方法都不灵了

早期 Mac 微信双开非常简单,终端里一句话就能搞定:

1
open -n /Applications/WeChat.app

或者更早期甚至可以直接 & 后台启动两次。但从微信 4.x 开始,官方做了两件事:

一是 open -n 多实例启动被拦截,第二次启动会被原进程检测到并直接激活已有窗口;二是 App 启动时会做代码签名自检,发现签名身份和原版不一致就主动 abort()

所以现在主流的”复制 App + 改 Bundle ID + 重新签名”方案,如果签名步骤处理不当,就会得到下面这个经典报错:

1
[1]  5308 trace trap  /Applications/WeChat2.app/Contents/MacOS/WeChat

trace trap 就是 SIGTRAP,几乎可以 100% 锁定为签名校验失败导致的主动 abort。

失败的尝试

最开始我用的是网上最常见的三板斧:

1
2
3
sudo cp -R /Applications/WeChat.app /Applications/WeChat2.app
sudo /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.tencent.xinWeChat.dual" /Applications/WeChat2.app/Contents/Info.plist
sudo codesign --force --deep --sign - /Applications/WeChat2.app

双击启动,系统弹窗:”WeChat2”意外退出。终端里直接跑可执行文件,trace trap,没有任何其他输出。

排查了一圈,问题出在两个地方。一是 cp -R 在 macOS 上会丢扩展属性和某些符号链接,应该用 ditto。二是更关键的——副本里还残留着原版的 hardened runtime 标志和 Team ID 相关信息,但用 adhoc 签名(--sign -)签上去之后,运行时一校验就崩。

成功的方案

核心思路是:推倒重做,彻底清除旧签名残留,然后对所有内嵌动态库逐个 adhoc 重签,最后整体再签一遍

完整流程如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# 1. 推倒重做:删掉之前的副本,用 ditto 重新拷贝(保留扩展属性)
sudo rm -rf /Applications/WeChat2.app
sudo ditto /Applications/WeChat.app /Applications/WeChat2.app

# 2. 修改 Bundle Identifier,让系统识别为另一个 App
sudo /usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier com.tencent.xinWeChat.dual1" /Applications/WeChat2.app/Contents/Info.plist

# 3. 清掉所有旧签名和隔离属性
sudo rm -rf /Applications/WeChat2.app/Contents/_CodeSignature
sudo find /Applications/WeChat2.app -name "_CodeSignature" -exec rm -rf {} + 2>/dev/null
sudo xattr -cr /Applications/WeChat2.app

# 4. 关键步骤:先移除主签名,再对所有 dylib 和 framework 逐个 adhoc 签名
sudo codesign --remove-signature /Applications/WeChat2.app 2>/dev/null
sudo find /Applications/WeChat2.app -type f \( -name "*.dylib" -o -name "*.framework" \) -exec codesign --force --sign - {} \; 2>/dev/null

# 5. 最后对整个 App 做 deep adhoc 签名
sudo codesign --force --deep --sign - /Applications/WeChat2.app

执行完之后直接双击启动:

1
open /Applications/WeChat2.app

干净起来,可以登录第二个账号了。

断网切换保持 PC 端双登

只有一部 iPhone 手机,但想在 PC 上同时登两个微信号 。原理是利用断网状态下的切换时机,让手机和 PC 的登录状态出现短暂的「脱钩」。操作步骤:

  1. 手机和 PC 先正常登录 A 号,确认 PC 端 A 号在线
  2. 手机断网(开飞行模式或关 Wi-Fi 和数据),然后在微信里点「设置 → 切换账号」,点击 B 号
  3. 因为断网,B 号会一直转圈loading,不要管它,等到弹出「网络异常」的提示
  4. 这时候恢复网络,再点一次 B 号,可能还会提示一次网络异常,再点一次
  5. 手机成功登录 B 号后,去 PC 上检查——A 号还在线没掉
  6. 用手机 B 号扫码登录第二个 PC 微信(Mac 上就是前面双开出来的 WeChat2)

关键点解析

**为什么不能用 cp -R**:macOS 的应用 bundle 里有扩展属性和软链接,cp -R 会处理得不干净。ditto 是苹果推荐的 bundle 拷贝工具,元数据保留完整。

为什么要先 remove-signature 再逐个签codesign --deep 看起来一步到位,但实际上它对深层嵌套的 framework 处理有时会跳过或失败,导致整体签名”看起来 OK”但运行时校验某个 dylib 还是挂的。手动逐个签可以确保每个二进制文件都用同一个 adhoc 身份。

**为什么要 xattr -cr**:清除 com.apple.quarantine 等隔离属性,否则 Gatekeeper 会拦截,弹”已损坏”。

Bundle ID 必须唯一com.tencent.xinWeChat.dual1 这个名字可以随意改,但不能和原版一样,否则系统还是会认为是同一个 App,无法多实例。

想开更多账号怎么办

把上面的脚本里 WeChat2dual1 改成 WeChat3dual2,再跑一遍就行。每多一个号就重复一次,本质上是在 /Applications/ 下生成多个独立 Bundle ID 的副本。

注意事项

第一,关掉自动更新。微信一更新就会覆盖 /Applications/WeChat.app,但副本不会跟着更新,而且因为版本和共享资源对不上,副本大概率直接挂掉。在两个微信的「设置 → 通用」里都取消勾选”自动升级”。

第二,官方更新后需要重新生成副本。手动升级原版微信之后,把副本删了重跑一遍脚本就行。可以把上面的命令存成 .sh 脚本,更新后一键执行。

第三,这是非官方做法,理论上存在被风控的可能。

第四,adhoc 签名不能上 iCloud Keychain 同步等需要 Apple ID 关联的功能,但微信本身的聊天、文件传输、视频通话都不受影响。

小结

Mac 上的微信双开本质上就是「让 macOS 把同一个 App 当成两个不同的 App」。微信 4.x 加了签名自检之后,关键不在于改 Bundle ID(这一步从来都简单),而在于签名链条要完整且一致。把所有内嵌动态库都用同一个 adhoc 身份逐个签一遍,是绕过 SIGTRAP 自检的关键。

如果你也遇到 trace trap,按这套流程做一遍基本能解决。万一还是不行,可以试试社区的成熟项目比如 nullbyte-lab/wechat-multi-open,或者降级到微信 3.8.x 老版本——那个时代的微信对双开宽容得多。