iOS 逆向开发小试-钉钉篇

| categories: iOS | tags: iOS

一直以来对逆向开发蛮感兴趣,从去年虾神的 Pokemon Go 解除锁区教程开始,逐渐学习了一些逆向相关的知识。于是最近尝试着对钉钉做了一些逆向的工作,主要是针对打卡功能,原因就算我不说相信你也一定知道(嘿嘿)。本文非常基础,都是 Hook 一些函数来完成功能,没有涉及到二进制反汇编。

开发环境


  • 越狱 iOS 机器
  • Thoes

关于环境搭建不多说,网上可以找到很多教程。

目前有一个需要注意的地方,就是通过 brew 安装的 dpkg 工具的最新版本,会导致 Thoes 打包失败,解决办法就是使用老版本的 dpkg。执行如下命令可以安装老版本的 dpkg, 并使用 brew 的 pin 功能,在以后的 brew upgrade 时不会升级 dpkg,除非执行 unpin。

$ brew remove dpkg  # remove latest dpkg
$ brew install --force-bottle https://raw.githubusercontent.com/Homebrew/homebrew-core/7a4dabfc1a2acd9f01a1670fde4f0094c4fb6ffa/Formula/dpkg.rb  # install dpkg as a bottle from the old commit
$ brew pin dpkg  # block homebrew from updating dpkg till you `brew unpin dpkg`

目标分析与 tweak 实现


由于是要完成破解打卡的功能,那么 GPS 定位和 Wi-Fi 信息就是要 hook,然后模拟的目标。如果公司并未开启 Wi-Fi 验证,那就更简单了,只 hook 地理位置信息即可。

GPS 定位非常容易 Hook,使用虾神的那篇文章里介绍的方式就行,这个方式的原理就是 Hook 系统的 CLLocation 类的 coordinate。Logos 语法代码如下,直接修改 CLLocationCoordinate2DMake 里的经纬度为实际需要的值。

%hook CLLocation

- (CLLocationCoordinate2D) coordinate {
    return CLLocationCoordinate2DMake(0.0, 0.0);
}

%end

Wi-Fi 信息包括 ssid 和 bssid,ssid 就是 Wi-Fi 的名字,bssid 可以简单理解为路由器网关的 MAC 地址。在对钉钉这个 App 砸壳并 dump 出头文件后,在头文件所在的文件夹中执行如下命令:

grep -rn ssid *

逐一查看并验证之后,发现钉钉使用的是高德 API 提供的 Wifi 信息获取功能。于是 hook 相关函数。直接返回需要的信息。由于我验证的并不是很充分,那么便在我认为可能的地方都做了 Hook。

主要集中在下面两个类的相关函数:

LWPUtil 类:

+ (id)SSID

AMapStatistics 类:

- (id)fetchSSIDInfo
- (NSString *)wifiname
- (NSString *)wifi

安装 Tweak 到非越狱设备


实现了上面的 Hook 之后,一个 tweak 就完成了。但是目前面临这一个问题,就是 tweak 只能是用在越狱设备上。而我自己的手机并没有越狱,为了打卡也不方便再携带一个越狱设备。那么解析来就是开始研究如何将 tweak 工程生成的目标,安装到非越狱手机上。

非越狱手机安装 App 的原理是通过 dylib 注入来实现的。那么要接下来的问题就是如何将 tweak 生成的 dylib 注入到 App 中。需要以下步骤:

  1. 准备需要注入的 dylib 文件,并对其签名
  2. 对目标 App 的可执行文件增加 Load Commnads,加载上一步的 dylib 文件
  3. 拷贝 dylib 文件到 App 中
  4. 对处理好的 App 做重签名

其实,tweak 工程在编译完成后,会在工程根路径下的 .theos/obj/debug/ 文件夹里生成一个 dylib 动态链接库。那么首先需要解决一个问题,就是这个动态库的越狱环境依赖。直接说解决办法好了,在工程的 Makefile 文件中的 TWEAK_NAME 后面,添加上如下内容

SUBSTRATE ?= yes
instance_USE_SUBSTRATE = $(SUBSTRATE)

把上面的 instance 替换成自己的 TweakName。然后执行如下命令,就可以编译出不依赖越狱环境的 dylib 了

make SUBSTRATE=no

对 dylib 签名很简单,直接执行命令:

codesign -f -s "iPhone Developer: XXXXX (XXXXX)" XXXXX.dylib

将 XXXXX 替换为自己的内容。

接下来是给可执行文件添加 Load Commnads。可以选用的工具有 yololibinsert_dylib。记得选择 insert_dylib,这里有一个坑,就是如果使用 yololib 来添加 Load Commnads,那么默认给 dylib 文件填写的最低支持版本号是 1.0.0,而由于我们是从 tweak 里拿出的 dylib,它的默认版本号是 0.0.0,而且没找到办法怎么去修改这个版本号,所以还是用 insert_dylib 来完成这件事情。使用方式如下:

insert_dylib --all-yes @executable_path/XXXXX.dylib Payload/DingTalk.app/DingTalk

XXXXX 是 dylib 文件的名字。

拷贝 dylib 和重签名的步骤就不多说了。说一下最后撞到的一个坑,由于我 dump App 的时候,使用的是一台 iOS 9.3 的越狱 iPhone 6s,CPU 架构是 arm 64,而 iOS 9 的系统的 App Slicing 机制会使得下载到系统里 App 的二进制文件只包含 arm 64 架构,不过现在基本也没有非 arm 64 的 iPhone 设备了。但是当我对这个 dump 的 App 做了以上整个破解步骤之后,安装到我的 iPhone 6s Plus 的设备时,报了一个 App 不支持当前设备的错误。最后查看 dump 出来的 App 的 Info.plist 文件时,发现在支持的设备列表里没有包含 Plus 类型的设备。于是,修改 Info.plist 文件,添加上相应的设备支持,重签名 App,再次尝试安装,搞定。

总结


这篇文章写的很笼统,没有详细代码。一来是因为自己也是刚刚入门越狱开发,二来是目前这个 tweak 的功能非常原始,只是完成了最基本的 hook,涉及的功能代码也都是硬编码,所以也就没有把源码完全放出来。但我觉得已经将关键的地方也说清楚了,只要稍微有点越狱开发经验,应该能很快做出来。最后补一句,我真的很讨厌钉钉!!

接下来准备去学习一下二进制逆向相关的知识了。话说 IDA 真的好贵啊~~

参考资料





Previous     Next

Published under (CC) BY-NC-SA