发表于 2021-2-20 16:53

会员申请ID:花落人断肠

1.申请ID:花落人断肠2.个人邮箱:chacewan@163.com3.在论坛潜水这么多年,每次都错过开发注册的时间,这次静下心来做一个wx获取朋友圈数据的ios小逆向案例,给朋友们提供一个思路。开始App Configurator 2 中导出 wx ,frida-ios-dump 脱壳,class-dump 导出 header,MonkeyDev 创建项目。

分析首先,朋友圈的数据分析当然是从朋友圈的UI开始分析是最好的,使用Reveal很快能定位到朋友圈是WCTimeLineViewController,通过导出头文件可以找到WCTimeLineViewController.h。从图中可以看到WCTimeLineViewController中有实现tableViewDelegate代{过}{滤}理:blob:https://www.52pojie.cn/c0e43b04-d6c0-4ad3-abe8-2f1bf9fd5f90

此时,感觉就应该要从 UITableView 的数据源入手。Xcode 运行 Debug wx,在朋友圈界面暂停,Console 窗口中打印 WCTimeLineViewController 中猜测有可能是数据源的变量名,简单尝试几个后并没有什么发现。打算反编译程序的逻辑来入手。众所周知,UITableView 一般情况下是使用 tableView:cellForRowAtIndexPath: 设置 Cell 的数据,从这个函数下手,大概率就可以知道数据从哪里来的了。启动 Hopper 导入 wx 二进制文件,搜索 WCTimeLineViewController tableView:cellForRowAtIndexPath: 查看伪代码(截图为关键部分): 数据源部分blob:https://www.52pojie.cn/832de635-19b9-4b06-b3b6-2efcffda4919
观察到函数 getTimelineDataItemOfIndex 很可能是数据来源,通过函数名 DataItem 做为线索,在导出的 Header 中搜索到 WCDataItem,查看 WCDataItem 推测应该就是朋友圈使用的数据结构。根据上下文可知获取数据的方式是:
MMContext *context = ;WCFacade *facade = ];WCDataItem *dataItem = ;

没想到这么容易就找到数据源了,继续测试:

%hook WCTimeLineViewController
- (void)viewDidLoad {    // 读取朋友圈数据    MMContext *context = [%c(MMContext) currentContext];    WCFacade *facade = ];    WCDataItem *dataItem = ;    // --- 此处断点 ---          // dataItem 为 nil      %orig();}
%end
运行!进入朋友圈后断点,查看 dataItem 变量,怎么 dataItem 是 nil?再回头看看 Hopper 的代码,看上去似乎没问题啊,这时候尝试继续运行程序,再次暂停程序,控制台打印获取 WCDataItem:(lldb) po [[ getService:] getTimelineDataItemOfIndex:0]
Class name: WCDataItem, addr: 0x10e3b8e80tid: xxxxxxxxxxxxxxxusername: xxxxxxxxxxcreatetime: xxxxxxxx...成功了,发现只能在朋友圈界面加载完之后,才可以获取通过 getTimelineDataItemOfIndex 获取到数据,到底是缺少了哪一步呢?
继续深挖首先,尝试修改代码,将%orig()移动到获取数据之前:
%hook WCTimeLineViewController
- (void)viewDidLoad {    %orig();      // 读取朋友圈数据    MMContext *context = [%c(MMContext) currentContext];    WCFacade *facade = ];    WCDataItem *dataItem = ;    // --- 此处断点 ---          // dataItem 有数据}
%end
再次运行,成功获取数据,由此猜测,在 viewDidLoad 中存在某些代码,是使用 getTimelineDataItemOfIndex 的前提条件。在 Hopper 查看 viewDidLoad 伪代码(代码太长就不贴了),首先搜索 MMContext 关键词,发现只有语言和主题相关内容。再仔细看发现有一个诱人的函数:blob:https://www.52pojie.cn/b5e7826d-9d55-4474-8f66-2b41a05dc951为了验证 initData 是否是下一步分析的关键,先尝试 hook 它,内部实现为空,这样就相当于不执行 initData 了:
%hook WCTimeLineViewController
- (void)initData {}
%end
运行,发现在 initData 不执行任何代码后,朋友圈加载不出数据,这样可以针对它下手了。查看伪代码,发现这里 调用了 WCFacade 的 beginTimeline:blob:https://www.52pojie.cn/23d81a9d-3e65-425c-bb99-3a18e38883c3将beginTimeline加入到initData:
%hook WCTimeLineViewController
- (void)initData {    MMContext *context = [%c(MMContext) currentContext];    WCFacade *facade = ];    ;}
%end
这时候朋友圈数据又出现了,那么 dataItem 为 nil 仅仅是因为缺少 beginTimeline 吗?在 beginTimeline 之后获取数据试试:
%hook WCTimeLineViewController
- (void)initData {MMContext *context = [%c(MMContext) currentContext];WCFacade *facade = ];;WCDataItem *dataItem = ;// --- 此处断点 ---// dataItem 为 nil}
%end
运行结果 dataItem 为 nil,但朋友圈是能正常显示,推断 beginTimeline 是显示朋友圈的必要但非唯一条件(推断错了,看后面)。只能回到 viewDidLoad 继续探索其他条件。再次检查 viewDidLoad 仅仅从代码函数命名上并没有什么发现,此时只能转战动态调试。
动态调试在这种没头绪的时刻,我想就是动态调试发挥的时候了。打开 Hopper,在 viewDidLoad 中大概找几个位置打上断点,想用于缩小范围来确定是哪个位置执行后, getTimelineDataItemOfIndex 能获取到值:
// 输出 ASLR,只需要看 wx 的地址(lldb) im li -o -f
// 打上断点(lldb) br s -a 中查看的地址]+
// 执行到断点处再 po 获取数据(lldb) po [[ getService:] getTimelineDataItemOfIndex:0]

经过几轮断点,发现 getTimelineDataItemOfIndex 的值从 nil 变为有值时所在的位置并不固定,这才发现自己思考的并不全面,此前一直以为的是 beginTimeline 是同步执行,而其实 beginTimeline 是异步的,下一步立刻去获取 getTimelineDataItemOfIndex 时,数据还没有从本地数据库中读取出来(猜测,技术菜,还没有针对 beginTimeline 去深究)。
逆向结果最终,为了检测上一步读取数据是异步的猜想,将 getTimelineDataItemOfIndex 延迟去执行:
// 在发现界面显示时获取数据
@interface FindFriendEntryViewController : UIViewController@end
%hook FindFriendEntryViewController
- (void)viewDidLoad {MMContext *context = [%c(MMContext) currentContext];WCFacade *facade = ];;;
%orig();}
%new- (void)getDataItem {MMContext *context = [%c(MMContext) currentContext];WCFacade *facade = ];WCDataItem *dataItem = ;// --- 断点 ---// dataItem 有数据}
%end
成功!目前只是简单获取到已经加载到本地的数据,并且没有对 beginTimeline(还有 endTimeline)机制深究,在逆向过程中发现会在朋友圈界面的 viewDidLoad 中调用 beginTimeline、dealloc 中调用 endTimeline。另外如果需要从网络加载需要更深入的挖掘,按自己理解大概是从朋友圈界面逆向出触发请求数据的函数,然后再通过本文的方法读取出来。

Hmily 发表于 2021-2-22 10:07

https://iosre.com/t/wx/17841

这是你写的?

呵呵我笑了 发表于 2021-2-22 17:14

应该不是他原创的,去年8月的
页: [1]
查看完整版本: 会员申请ID:花落人断肠