本篇在博客园地址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 3.1差异化构建打包,提升多版本应用开发效率

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

  2. 填报表中也可以添加 html 事件

    在实际的项目开发中,填报表的应用十分广泛. 多数情况下,填报表会作为整个项目的一部分配合需求灵活使用,但有时也会受大项目环境的影响,产生一些特别的要求.比如,通常报表单元格的数据类型大多是文本,有时却 ...

  3. 力扣596(MySQL)-超过5名学生的课(简单)

    题目: 表: Courses 编写一个SQL查询来报告 至少有5个学生 的所有班级. 以 任意顺序 返回结果表. 查询结果格式如下所示 示例1:  解题思路: 使用group by按 班级 进行分组后 ...

  4. Flink SQL 1.11 on Zeppelin 平台化实践

    简介: 鉴于有很多企业都无法配备专门的团队来解决 Flink SQL 平台化的问题,那么到底有没有一个开源的.开箱即用的.功能相对完善的组件呢?答案就是本文的主角--Apache Zeppelin. ...

  5. Hexo博客框架—轻量、一令部署

    ​简介:Hexo 是一个快速.简洁且高效的博客框架.Hexo 使用 Markdown(或其他渲染引擎)解析文章,在几秒内,即可利用靓丽的主题生成静态网页.Hexo支持Github Flavored M ...

  6. 3月2日,阿里云开源 PolarDB 企业级架构将迎来重磅发布

    简介:2022年3月2日,开源 PolarDB 企业级架构将迎来重磅发布!本次发布会将首次公开开源 PolarDB 的总体结构设计和企业级特性,对 PolarDB for PostgreSQL 的存储 ...

  7. 编译优化 | LLVM代码生成技术详解及在数据库中的应用

    简介: 作者:长别 1. 前言 随着IT基础设施的发展,现代的数据处理系统需要处理更多的数据.支持更为复杂的算法.数据量的增长和算法的复杂化,为数据分析系统带来了严峻的性能挑战.近年来,我们可以在数据 ...

  8. [FAQ] 修改了Dockerfile 之后,运行 docker-compose up --force-recreate 时还是报之前构建时的错误?

      因为 Docker Compose 的 --force-recreate 选项只会强制重新创建容器,而不会重新构建镜像. 因此,如果你修改了Dockerfile,需要确保重新构建新的镜像. 你可以 ...

  9. [FAQ] Jetbrains 官网不能访问,获取 Goland 的下载地址

    2020.02 安装包下载 Link:https://www.cnblogs.com/farwish/p/14186441.html

  10. [FAQ] Beego2.0.2 bee 生成的 api 项目运行 404, http server Running on http://:8080

    Beego, bee version 2.0.2 https://github.com/beego/beego/issues/4363 Tool:AI 编程助手 Refer:Beego还流行吗 Lin ...