首页 文章 精选 留言 我的

精选列表

搜索[鸿蒙PC],共9141篇文章
优秀的个人博客,低调大师

微信PC端多开的秘密

微信电脑端也能多开 昨天,偶然从好朋友小林(微信公众号:小林Coding)处得知,他的电脑居然可以同时上两个微信号。 手机端多开微信我知道,像华为、小米等手机系统都对此做了支持,不过在运行Windows系统的电脑上怎么启动两个微信呢,这倒是一下引起了我的好奇。 小林告诉我他是这样做的,写了一个批处理: startD:\WeChat\WeChat.exestartD:\WeChat\WeChat.exe 然后直接双击批处理文件,就能启动两个微信进程。 我试了一下,果然如此! 随后我又加了一行,竟然还能启动3个: 接着我在网络上搜了一下,原来这一招早就被人用过了,看来是我火星了。不过到底为什么用这种方式就能多开,我倒是很想直到这个迷底。 TIPS:如果对技术分析部分不感兴趣,可以跳过直接来到后面的真相部分。 微信的单例模式 正常情况下,直接手动双击微信图标启动,后面启动的进程会进行全局单例模式检查,如果发现已经存在微信进程,就会直接把对应进程的微信窗口激活,定位到桌面最前面,随后自己退出。 但为什么用上面的方式就能启动俩呢?我们来一探究竟。 首先,分析一下上面描述的微信单个实例是如何实现的。 做过Windows平台应用程序开发的朋友可能对此比较熟悉,一般是进程启动后创建一个全局唯一名字的互斥体,创建成功则正常启动,创建失败则判断一下是否这个互斥体已经存在。如果已经存在则说明已经有对应程序之前启动。 带着这种猜想,用工具procexp查看一下微信进程打开的所有内核对象,并找到互斥体部分: 果然,这其中有一个名字叫_WeChat_App_Instance_Identity_Mutex_Name的互斥体,从这个名字可以猜出,这个跟微信的单例模式绝对有关系。 接着,启动神器APIMonitor,它可以帮你监控指定进程的API调用情况,勾选上CreateMutex和GetLastError这两个Windows API函数。在已经有微信在运行的情况下,用这个工具再启动一个微信进程,看一下函数调用情况: 可以看到,创建这个名字的互斥体后,随后又调用了GetLastError函数,并返回了0x000000b7,查看手册,其含义: 表示已经存在。 来看一下,这个CreateMutex调用的堆栈,看看是哪个地方的代码在创建这个全局互斥体: 从堆栈看出,调用来自于微信目录下的一个动态库WeChatWin.dll。具体位置在偏移0x8e271b处的前一条指令。 接下来就要祭出神器中的神器,大名鼎鼎的反汇编软件IDA,这家伙支持x86、x64、ARM、MIPS等多种处理器架构和Windows、Linux、Android、MacOS、JVM等多种系统平台的程序分析。 用IDA打开这个WeChatWin.dll文件,并定位到偏移0x8e271b处: 如上图所示,创建互斥体的动作,发生在函数sub_108e26d0。 上层是sub_108e2660函数在调用它: 上面这张图反映了创建互斥体后的判断逻辑: 如果sub_108e26d0的返回值为0,表示没有错误,当前函数也直接返回0。 如果sub_108e26d0的返回值不为0,表示出现了错误,则依次判断 WeChatMainWndForPC和 WeChatLoginWndForPC两个窗口是否存在,如果存在则使用 BringWindowToTop函数将其置顶弹出。这两个窗口分别代表的是微信的主界面窗口和登陆界面窗口,如果一个微信实例已经存在,则势必处于这两种状态之一。 问题就出在上面这个判断中,汇编代码看起来有点辣眼睛,咱们F5来还原一下C代码(还原效果只能凑合看,能看清楚逻辑就行): 上面图片的注解已经说明了,函数sub_108e2660的返回值将决定是否启动微信实例进程,还是直接退出。 真相只有一个 事情到这里就真相大白了,来总结一下。 微信判断是否启动的2个条件: 如果能成功创建互斥体对象,则启动微信 如果不能创建互斥体: 如果找到对应窗口,则置顶之,自己退出 如果没有找到,则启动微信 用伪代码来表示一下: if(CreateMutex()==SUCCESS){启动微信}else{if(FindWindow()==SUCCESS){将已有窗口置顶}else{启动微信}} 而直接使用脚本启动的多个进程,虽然操作系统内核层面保证了互斥体的唯一,但由于启动速度相差不大,相应的窗口还没有来得及创建出来,导致走入上面的第二个启动逻辑,从而可以启动多个实例。 小发现 在分析的过程中,发现了一个有趣的事情: 在WeChatWin.dll中,上面的创建互斥体再上一级函数名字叫StartWaChat,也是作为导出函数被该DLL导出: 这里不知道是故意还是不小心把微信的WeChat写成了WaChat,如果是笔误,这位程序员同学看到了赶紧偷偷去改一下吧。 往期TOP5文章 CPU明明8个核,网卡为啥拼命折腾一号核? 因为一个跨域请求,我差点丢了饭碗 完了!CPU一味求快出事儿了! 哈希表哪家强?几大编程语言吵起来了! 一个HTTP数据包的奇幻之旅 本文分享自微信公众号 - 编程技术宇宙(xuanyuancoding)。如有侵权,请联系 support@oschina.cn 删除。本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册