利用后摄像头获取视频流
实现微信聊天界面的背景透视
1. 概述
前两天逆向了微信实现伪装定位,想着想再实现一个好玩的 trick 作为巩固,然后向下一个阶段推进。自动抢红包,不太感兴趣,并且已经有人实现了;文章阅读界面的的新消息预览,这个倒是我的刚需,不过也有人实现了,留着过段时间自己也实践一遍。最后想来想去,干脆就做一个之前手Q曾经有过的功能吧 —— 聊天页面背景透视,走路聊天防摔。
流程还是那样:砸壳 -> class-dump -> Hopper 反编译 -> 定位想要 hook 住的类以及函数 -> 编写 tweak。砸壳跟 class-dump 之前已经实践过了,这里就不再废话,直接从定位 hook 点开始。
2. hook 点定位
这里有个小建议,可以将系统的语言改成英文,程序员都知道,功能的英文名称一般跟工程中的类名相近,这样可以帮助我们更加快速地定位到相对应的类。例如微信中附近的人对应的英文名称为 People Nearby,而实际上源文件名称也包含了这个关键字。
2.1 Reveal 分析
对于聊天详情页面,没有地方可以看到对应的“功能英文名”,于是我们借助利器“Reveal”,注入 Reveal 之后(注入的方法在上一篇伪装微信定位的文章有提到),来分析一下微信的界面,这个过程如褪去少女轻薄衣裳般让我兴奋:
进入聊天详情页,在视图层级中选中 controller 对应的 view,然后右侧的 Identify Inspector 中可以看到它对应的 controller:
一下子就定位到了我们需要 hook 的类了。
2.2 hook 方法猜想
先大致分析一下我们需要实现的功能:
- 聊天详情页背景替换成后置摄像头的实时图像
- NavigationBar 右方增加一个按钮控制透视的开关
易证,我们需要在下面这些函数里面做 hook:
- viewWillAppear: 添加控制按钮,在 viewDidLoad 中第二次进入时会失效,原因暂时未想明白
- viewDidAppear: 一个小优化:让进入详情页时透视的开启状况与上一次一致
- viewWillDisappear: 如果是要退出详情页,就把透视关闭,同时释放相关的资源
- willRotateToInterfaceOrientation: 页面旋转会导致 previewer 布局异常,因此当页面即将旋转时需要停止 previewer,旋转完成之后再次开启。这里微信仍然使用的是 desperated 的旧方法,并没有使用苹果的建议,这点可以通过 class-dump 出的头文件或者 hopper 反编译可以知道
- didRotateFromInterfaceOrientation: 同上
代码就不贴了,没什么意思,要看源码可以到 Github 上查看
3. Theos
Theos 的工程中我使用了一个 Manager 来为我管理 AVFoundation 相关的操作,需要在 Makefile 中为它指定 arc 特性(更详细的 logos 语法可以在 wiki 中找到):1
AVManager.m_CFLAGS = -fobjc-arc
完整的 Makefile 文件贴一下:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15THEOS_DEVICE_IP = 192.168.0.137
ARCH = arm64
TARGET = iphone:9.3
include $(THEOS)/makefiles/common.mk
TWEAK_NAME = WeTransparentChat
WeTransparentChat_FILES = Tweak.xm AVManager.m
WeTransparentChat_FRAMEWORKS = UIKit AVFoundation
AVManager.m_CFLAGS = -fobjc-arc
include $(THEOS_MAKE_PATH)/tweak.mk
after-install::
install.exec "killall -9 WeChat"
另外有一点也需要注意下,看了很多文章,对 %log 的使用都是直接抄的原书中的描述,不知道是否因为系统差异,原书中提到的 /var/logs/syslog
默认并不存在,需要自己做一些配置,或者直接用另一种的方法来实时获取 syslog。
先到 cydia 中搜索安装 socat 这个插件,socat 也是 linux 上的一个强大的利器,算是 netcat 的替代产品或者加强版,可以在两个流之间机那里一个双向的通道。用下面命令实时获取 syslog:1
socat - UNIX-CONNECT:/var/run/lockdown/syslog.sock
1 | > watch |
然后会输出一堆有的没的信息,我们的 %log 数据也会包含在里面,不过目标进程幸好输出的信息在 iTerm 中会高亮。另外我暂时没有找到能够过滤输出的方法,用 * 过滤获取到的貌似是历史数组,并非实时。
最后剩下的事情就是 make package install 的往复循环测试了。
完