本篇在博客园地址https://www.cnblogs.com/bbqzsl/p/18209439

mars

先回顾一下,在上两篇我对wechat如何使用chrome::base框架的分析中存有错漏。首先要指出,逆向分析是一个过程。需要经过不断假设,推断,求证,验证。花费时间一步一步将结果改进完善的循序渐进的过程。当前的内容只代表当前分析的过程跟结果,当前的分析是以当前局限的结果作为前提的。还在逆向分析初期,我只运行少量功能场景,忽略了TaskScheduler除了Pump外。还有就是wechat在初始化时,已经将主线程的TaskRunner保存到了全局变量,用作主线程的dispatch_main_queue,供全局使用。但是EventCenter仍然是中心。

回到本篇内容,mars。

在逆向分析,我发现了StartTask的实际代码,将stn::Task进行了十次copy构造。一个320字节的结构,有10多个string,几个vector<string>,一个map<string,string>。佐证在本篇后面。

作为network模块,先来看SocketSelect。windows基于WASSelect,macos基于kevent,linux android它也看作unix,这个有点偷懒。对于看热闹的人来说linux是类unix系统,但是对于unix系统使用者就不买这个帐,unix跟linux就是两个东西。macos是基于freebsd,是unix分支,内核用kqueue,macos的MachPort就是基于kqueue。linux有它独用的epoll,好像也始于2.6内核的时代,内核并没kqueue。mars在非macos的系统中通通由poll来解决。这不是问题的关键。因为每一个tcp连接开一个线程,没有事件分离器复用。我也是惊了个呆。难怪低配置的安卓手机直接用不起,记得N年前28nm的晓龙425还可以运行微信6,微信7后因为旧版登陆接口不支持,强制升级微信后只能卡死在登陆进行转进入主界面。一个28nm的4cores1.4g的旧cpu且只带2GB运存的破手机,在2024年还可以运行最新版淘宝,大部分功能。不知道这东西,是不是如项目描述那样,在它自家的产品中跨平台使用了。freebsd,darwin-xnu,linux-kernel在github都有源代码。

window需要vc2015,那么姑且需要c++14,clang3.4于2013年就支持了,xcode跟ndk同样适用。c++14已经有不少boost库的东西,而且lambda也很成熟了。用boost::bind看着真的头晕。年轻时我也曾非boost不够cool。boost::bind(method, this, _1, _2, _3, _4, _5, _6),用python言语就是lambda a,b,c,d,e,f: this.method(a, b, c, d, e, f),用c++11的lambda就是[=](auto& a, auto& b, auto& c, auto& d, auto& e, auto& f) { return this->method(a, b, c, d, e, f); },以及std::function<auto(, , , , , , )>。boost::bind也就等同lambda的一种实现方式。调试有boost的项目时有个无尽长的名字我却不知道你是什么的恶梦。

在mars的设计中,mars既是namespace也是目录,mars下一级就是子模块,同样既是namespace也是目录,如mars::comm,mars::sdt,mars::stn。这里不能不说是在参考了java的包层级。

stn,我认为就是简单的首字命名,Strategy,Task,Network。重点就是network,这是一个network模块。至于Strategy就简单理解成ShortLink,LongLink。Task,原本咋一看还以为comm::mq分派Task,这个stn是一个分派中心,包括Task还有socket操作,Strategy类似于scheduler。实质却不是这样。Task就是在一个ShortLink或LongLink上完成一轮Request-Response。这个Task的设计就类似于js的XMLHttpRequest。js中,xhr = new XMLHttpRequest; xhr.onreadystatechange= function() {} ; xhr.open(); xhr.send(request_packet)。再来看mars,tsk = new Task(request_packet); tsk.OnEndTask = lambda; mars::stn::StartTask(tsk); 同一配方。所以我认为stn就是mars核心的network模块。

至于comm目录下的东西。socket跟network子目录只是些底层socket相关的api跟数据结构的封装,Facade模式。thread子目录转到平台对应的子目录。也是同步,TSS等相关的Facade封装。messagequeue子目录,我原来以为会是mars的重要的东西,跟它的线程模型会的密切关联。这个messagequeue的设计,就是在模仿Java的RunLoop。概念是一个线程对应一个messagequeue,线程id作为队列id。由绑定的MessageHandler处理message,只能用MessageHandler投递消息。在java中,handler = new Handler(Loop()); handler.SendMessage();handler.post();。回到mars上。messagequeue必须加上一个RunLoop构成一个Pump在线程中pump。MessageQueueCreater是一个自带线程以及Pump的类,它存在于stn::NetCore,comm::GetDefMessageQueue,还有comm::GetDefTaskQueue。如果你没有InstanllAsyncHandler去安装一个MessageHandler专门将message作为runnable处理,就是有Pump在线程运行也不分派runnable。几乎stn内每个功能类都有一个默认到comm::GetDefMessageQueue的MessageHandler,用来进行AsyncInvoke,但又似乎stn都基本上没有怎么用。(分别只这几处使用:Alarm.cc, BroadcastMessage。signalling_keeper.cc, AsyncInvokeAfter。zombi_task_manager.cc SingletonMessage。netsource_timechecker.cc, AsyncInvokePeriod。ActiveLogic::OnForeground,  AsyncInvoke。)。并非,comm::mq::Callback,是可以绑定MessageHandler,用来Handler2Queue投递AsyncInvoke。还有SYNC2ASYNC宏,所以shortlink跟longlink的OnResponse是AsyncInvoke进行的。还有ASYNC_BLOCK_START宏,StartTask也是AsyncInvoke进行的。整个设计有一个核心关键字,就是RunLoop,所有东西都要绕进来,什么类几乎都有一个RunLoop函数。还有就是Breadker,它为Condition又起了一个名。所以有这么一个函数BreakMessageQueueRunloop,从字面上还以为要中断一个线程的RunLoop,但实质是在做相反的事,breaker->notify(),快唤醒那个线程。这个RunLoop跟CFRunLoop,CFSocket的编程好像一个性子。

还有就是,所有线程跟messagequeue共用一个mutex。

* 两个线程的runloop居然还要竞争一个锁,然后才能处理自己的mq。
* mqA的runloop居然还要跟mqB的postmessage竞争一个锁。
* mqA的postmessage居然还要跟mqB的postmessage竞争一个锁。

既然mars是重度使用boost的,不如直接用asio。查看它的boost版本原来是1.60,boost在1.66才将asio重构成我们今天熟悉的executor。我写过一下关于1.66的boost.asio框架设计

逆向,我扯远了。我只关心应用层的接口就好了。

下面就是应用层的主要接口,还有交互流程。

现在逆向看看闭源的部分有哪些

先来解读一下目录结构

目录参考了java包目录结构。

mars是一级包名。下面的子包app,cdn,magicbox,mmdns,sdt,smc,stn。

每个子包,有一个同名的头文件,定义类结构。有一个同名的logic头文件,导出子包的接口,包括模块生命周期hooking (onCreate,onDestroy),logic.cc初始模块。子包里的功能单元称为Manager。所有功能的实现体单元在子包的src子目录。

       
目录 mars stn src
namespace mars:: mars::stn          
  StnManager ShortLink LongLink ShortLinkManager LongLinkManager  
文件   stn.h, stn_logic.h, stn_maanger.h ShortLink.cc LongLink.cc ShortLinkManager.cc LongLinkManager.cc  

再整理一下模块的设计思想,logic是包的接口层,manager是承接层,core是服务层。应用层通过logic调用包的服务,经过manager下达core。包内服务通过core调用应用层的服务,经由manager的callback集回调应用层安置的服务。实现过程是否严格贯彻是另一回事。应用层跟包内都有直接使用manager。

我在逆向分析StartTask时,发现了一个问题,mars::stn::Task总计做了10次copy构造,WTF。

在NetCore::StartTask入口准备AsyncInvoke时,一次

在Message构建过程,总计八次,其中有一个any_cast出来的AysncInvovkeFunction赋值函数无意思地进行了七次。typedef boost::function<void()> AsyncInvokeFunction;

在执行体里面,再一次,就是第十次。

你没有逆向过,也不知道原来这么funny。他们到底有没有跟踪过自己的代码,问号?似乎单靠xlog发现不了问题。没经过逆向分析谁也不清楚any或boost会编译出来什么,也不会在意这些小事的。传参用引用也不是万事大吉的。

本期先到这里,下期再见。

逆向WeChat(四)的更多相关文章

  1. Python逆向(四)—— Python内置模块dis.py源码详解

    一.前言 上一节我们对Python编译及反汇编做了讲解,大家知道dis模块可以将编译好的pyc文件中提取出来的PyCodeObject反汇编为可以阅读字节码形式.本节我们对dis模块中的源码进行详细的 ...

  2. 南邮攻防训练平台逆向第四题WxyVM

    下载文件elf文件,运行输入flag,用ida打开逆向算法: 不是很复杂,可以看出flag长度需要24,最终会和已给出dword_601060进行比较,一致则成功,那么现在只需要看上面的sub_400 ...

  3. iOS逆向(五)-ipa包重签名

    为什么要重签名? 1.在没有源代码的情况下,你已经对某个应用进行了资源修改(比如修改了启动图或图标等).修改完成以后,如果想要让APP可以正常使用,该APP一定要重新签名然后压缩成IPA文件. 2.如 ...

  4. Python逆向(一)—— 前言及Python运行原理

    一.前言 最近在学习Python逆向相关,涉及到python字节码的阅读,编译及反汇编一些问题.经过长时间的学习有了一些眉目,为了方便大家交流,特地将学习过程整理,形成了这篇专题.专题对python逆 ...

  5. 【二进制】【WP】MOCTF逆向题解

    moctf 逆向第一题:SOEASY 这个是个 64 位的软件,OD 打不开,只能用 IDA64 打开,直接搜字符串(shift+F12)就可以看到 moctf 逆向第二题:跳跳跳 这个题当初给了初学 ...

  6. 逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式

    逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式 一丶了解什么是结构体,以及计算结构体成员的对其值以及总大小(类也是这样算) 结构体的特性 1.结构体(struct)是由一系列具有相同类型或不 ...

  7. PC逆向之代码还原技术,第四讲汇编中减法的代码还原

    目录 PC逆向之代码还原技术,第四讲汇编中减法的代码还原 一丶汇编简介 二丶高级代码对应汇编观看. 1.代码还原解析: 三丶根据高级代码IDA反汇编的完整代码 四丶知识总结 PC逆向之代码还原技术,第 ...

  8. 逆向libbaiduprotect(四)

    百度加固libbaiduprotect.so自身对只读字符串进行了加密保护,防止成为破解和逆向的切入口.一般地认为,只要找出这个解密算法就可以对.rodata段的只读字符串进行破解,从而窥探程序的意图 ...

  9. IntelliJ IDEA 学习(四)Idea逆向生成数据库实体类

    第一步配置 数据库 第二步  配置hibernate,如果没有cfg.xml文件,点击ok后会自动生成 第三步 选择hibernate配置文件生成实体 第四步 设置完点击,选中要生成的实体的表 注意: ...

  10. hibernate(四)__由表逆向创建Domain对象和对象关系映射文件

    之前我们是手写Domain对象和对象关系映射文件->然后生成数据库中的Table. 现在我们反过来先在数据库中建好Table->然后用工具生成Domain对象和对象关系映射文件. 步骤: ...

随机推荐

  1. DevEco Studio新特性分享-跨语言调试,让调试更便捷高效

     原文:https://mp.weixin.qq.com/s/JKVLQXu1z1zAoF5q49YEGg,点击链接查看更多技术内容.   HUAWEI DevEco Studio是开发Harmony ...

  2. Spring6

    0x00 环境配置 环境: IDEA >= 2022.1.4 JDK 17 Maven 3.8.6 Spring 6.0.0 JUnit 4.13.2 Log4j2 新建模块 spring001 ...

  3. 重新整理数据结构与算法(c#)—— 平衡二叉树[二十三]

    前言 因为有些树是这样子的: 这样子的树有个坏处就是查询效率低,因为左边只有一层,而右边有3层,这就说明如果查找一个数字大于根元素的数字,那么查询判断就更多. 解决方法就是降低两边的层数差距: 变成这 ...

  4. mysql5.7.20靠谱安装步骤

    首先,我看过网上的其他教程. 其次,很多教程都过时了,或者按照步骤失败,反正我一次也没成功. 开始正题:首先,以管理员身份运行cmd 总共就两个命令: 1.mysqld --initialize-in ...

  5. WIN11 安装 SQL Server 2019,SQLSERVER2022, MYSQL 8.0 ,Docker,Mongodb失败故障分析

    最近研究数据库性能调优遇到各种数据库各种装不上,不知道熬了多少根软白沙,熬了多少颗张三疯,问了多少AI,查了多少网页,熬了两天,终于搞明白了一件事:那就是WIN11 ON ARM (因为拿的是MAC ...

  6. Linux基础——shell

    shell ############# shell是什么 -Bash Shell是一个命令解释器(python解释器),它在操作系统的最外层,负责用户程序与内核进行交互操作的一种接口,将用户输入的命令 ...

  7. JavaScript中数值小知识

    1. 数值10.0 这种类似的会被去掉数值后的0 之所以这样是因为,整数的存储空间占用比浮点数小,当一个数值不是真浮点数(即10.0这种格式),会被转换为整数10,如果业务中有一些需求需要进行数值位数 ...

  8. win10更新后使用ie浏览器自动跳转edge的解决方法

    win10更新后使用ie浏览器自动跳转edge的解决方法 ①在系统的搜索框中搜索internet选项 ②打开界面中,选择高级的栏位 ③然后在红框的地方找到启用第三方浏览器扩展,去掉勾选 ④应用,确定, ...

  9. oracle SQL 进行时间冲突判断

    oracle SQL 进行时间冲突判断 背景:写一个预约模块,主要的限制就是时间限制,有冲突的时间段就不能进行预约 设数据库中的时间为A开始,A结束 设要判断的时间为B开始,B结束 则判断有在B开始时 ...

  10. KubeVela 成为 CNCF 沙箱项目,让云端应用交付更加简单

    简介: KubeVela 就是这样一个面向用户的上层平台项目.对于业务开发者来说,KubeVela 简单.易用,它可以让开发者以极低的心智负担和上手成本在 Kubernetes 上定义与部署应用... ...