逆向WeChat(四)
本篇在博客园地址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(四)的更多相关文章
- Python逆向(四)—— Python内置模块dis.py源码详解
一.前言 上一节我们对Python编译及反汇编做了讲解,大家知道dis模块可以将编译好的pyc文件中提取出来的PyCodeObject反汇编为可以阅读字节码形式.本节我们对dis模块中的源码进行详细的 ...
- 南邮攻防训练平台逆向第四题WxyVM
下载文件elf文件,运行输入flag,用ida打开逆向算法: 不是很复杂,可以看出flag长度需要24,最终会和已给出dword_601060进行比较,一致则成功,那么现在只需要看上面的sub_400 ...
- iOS逆向(五)-ipa包重签名
为什么要重签名? 1.在没有源代码的情况下,你已经对某个应用进行了资源修改(比如修改了启动图或图标等).修改完成以后,如果想要让APP可以正常使用,该APP一定要重新签名然后压缩成IPA文件. 2.如 ...
- Python逆向(一)—— 前言及Python运行原理
一.前言 最近在学习Python逆向相关,涉及到python字节码的阅读,编译及反汇编一些问题.经过长时间的学习有了一些眉目,为了方便大家交流,特地将学习过程整理,形成了这篇专题.专题对python逆 ...
- 【二进制】【WP】MOCTF逆向题解
moctf 逆向第一题:SOEASY 这个是个 64 位的软件,OD 打不开,只能用 IDA64 打开,直接搜字符串(shift+F12)就可以看到 moctf 逆向第二题:跳跳跳 这个题当初给了初学 ...
- 逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式
逆向知识第十四讲,(C语言完结)结构体在汇编中的表现形式 一丶了解什么是结构体,以及计算结构体成员的对其值以及总大小(类也是这样算) 结构体的特性 1.结构体(struct)是由一系列具有相同类型或不 ...
- PC逆向之代码还原技术,第四讲汇编中减法的代码还原
目录 PC逆向之代码还原技术,第四讲汇编中减法的代码还原 一丶汇编简介 二丶高级代码对应汇编观看. 1.代码还原解析: 三丶根据高级代码IDA反汇编的完整代码 四丶知识总结 PC逆向之代码还原技术,第 ...
- 逆向libbaiduprotect(四)
百度加固libbaiduprotect.so自身对只读字符串进行了加密保护,防止成为破解和逆向的切入口.一般地认为,只要找出这个解密算法就可以对.rodata段的只读字符串进行破解,从而窥探程序的意图 ...
- IntelliJ IDEA 学习(四)Idea逆向生成数据库实体类
第一步配置 数据库 第二步 配置hibernate,如果没有cfg.xml文件,点击ok后会自动生成 第三步 选择hibernate配置文件生成实体 第四步 设置完点击,选中要生成的实体的表 注意: ...
- hibernate(四)__由表逆向创建Domain对象和对象关系映射文件
之前我们是手写Domain对象和对象关系映射文件->然后生成数据库中的Table. 现在我们反过来先在数据库中建好Table->然后用工具生成Domain对象和对象关系映射文件. 步骤: ...
随机推荐
- Python3中pip3命令的用法介绍及安装配置
第一节:pip3是什么?有啥用? pip3:(Python3 Install Package ),这个英文全称是我为了更好的理解这个命令这么叫的,官方没有这对个命令的全称的解释:) python 支持 ...
- Mac 修改版本号
修改版本号 在安装某些软件(XCode)的过程中, 系统会提示版本低,需要升级到高版本, 而很多人不想升级而需要安装这些软件, 此时只需将版本号修改成软件安装要求的版本号就可以了. 由于SystemV ...
- This beta version of Typora is expired, please download and install a newer version. 实测最简单有效的方案
This beta version of Typora is expired, please download and install a newer version. 实测最简单有效的方案 一.问题 ...
- State 和 Props的理解以及区别
一.state 一个组件的显示形态可以由数据状态和外部参数所决定,而数据状态就是state,一般在 constructor 中初始化 当需要修改里面的值的状态需要通过调用setState来改变,从而达 ...
- ClkLog自定义事件分析登场
ClkLog的自定义事件分析功能在大家满满的期待下终于发布了. 这次更新我们添加了[用户关联].[事件采集].[事件分析]三大块功能点. 本次上线的自定义事件分析可以让用户根据自身业务场景创建不同维 ...
- 力扣400(java)-第N位数字(中等)
题目: 给你一个整数 n ,请你在无限的整数序列 [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, ...] 中找出并返回第 n 位上的数字. 示例 1: 输入:n = 3输出: ...
- 加入自定义块对fashion_mnist数据集进行softmax分类
在之前,我们实现了使用torch自带的层对fashion_mnist数据集进行分类.这次,我们加入一个自己实现的block,实现一个四层的多层感知机进行softmax分类,作为对"自定义块& ...
- 为了让你在“口袋奇兵”聊遍全球,Serverless 做了什么?
简介: 江娱互动是一家新兴的游戏企业,自 2018 年成立伊始,江娱互动就面向广阔的全球游戏市场,通过创造有趣的游戏体验,在竞争激烈的游戏市场占得一席之地.仅仅 2 年的时间,江娱互动就凭借 Topw ...
- 深度解析PolarDB数据库并行查询技术
简介: 随着数据规模的不断扩大,用户SQL的执行时间越来越长,这不仅对数据库的优化能力提出更高的要求,并且对数据库的执行模式也提出了新的挑战.本文将介绍基于代价进行并行优化.并行执行的云数据库的并行查 ...
- 如何开发 Node.js Native Add-on?
简介: 来一起为 Node.js 的 add-on 生态做贡献吧~ 作者 | 吴成忠(昭朗) 这篇文章是由 Chengzhong Wu (@legendecas),Gabriel Schulhof ( ...