使用纯 python 实现 Instruments 协议,跨平台 (win,mac,linux) 获取 iOS 性能数据

原文由YueChen发表于TesterHome社区网站,点击原文链接可与YueChen交流。
前言
获取 iOS 性能数据,一直都是比较麻烦的事情,之前在构建测试框架&平台的时候,获取 iOS 性能也是没有什么好的办法,也只能使用比较原始的方式,获取非越狱 iOS 性能数据,例如 xcode 调试可以获取,Instruments 获取数据,用起来也是极为不便。
到现在能做到跨平台,对非越狱 iOS 机器进行监控数据的貌似只有腾讯一家 PerfDog,确实非常优秀,但是腾讯对于 PerfDog 的技术还是比较保密的,GitHub 上比较有名的关于 iOS 设备控制仓库上例如 facebook idb,libimobiledevice 等,也都没有获取性能数据相关内容。
目前已经实现
使用纯 Python 代码跨平台(win,mac,linux) 获取 iOS 部分性能数据&其他数据,10.3 < iOS version < 14.2 虽然可以获取绝大部分 iOS 设备性能数据,当然也有部分设备没有兼容,也希望有兴趣的同学可以一起探讨共同开发。最终开源项目地址会在文章末尾开放
基本工作原理介绍
  • Usbmux
  • Lcokdown
  • LaunchDaemon
  • Instruments 通道
  • Framework
    • DeveloperDiskImage.dmg
    • MobileDevice.framework
  • DTXMessage 流
Usbmux usbmuxd 的主要作用就是,通过 usb 来构建一条 socket 通道来实现 Mac OS 与 iOS 之间的通讯
windows 上则是 C:\Program Files\Common Files\Apple\Mobile Device Support\AppleMobileDeviceService.exe 驱动来监听 27105 端口与 iOS 之间进行通讯
【使用纯 python 实现 Instruments 协议,跨平台 (win,mac,linux) 获取 iOS 性能数据】想做相关工具开发,获取数据显然必不可少,下面监听 usbmuxd
### 转移 usbmuxd sudomv /var/run/usbmuxd /var/run/usbmuxx ### 监听 usbmuxd sudo socat -t100 -x -v UNIX-LISTEN:/var/run/usbmuxd,mode=777,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxx ### socat 工具是以文本来展示的,看起来相当费劲, ### 通过管道转到 wiershark 上面,wireshark 查看 usbmuxd sudo socat -d -d -lf /dev/stdout -x -v 2>&1UNIX-LISTEN:/var/run/usbmuxd,mode=777,reuseaddr,fork UNIX-CONNECT:/var/run/usbmuxx | awk '/^[<>]/{a=0; $1 == "<" ? "I" : "0"; next}{$0 = substr($0, 1, 48); printf "%.4x %s\n",a,$0; a+=NF}' | text2pcap- -| wireshark-ki -### 很重要 !!!用完之后必须要复位,不然你的电脑之后就找不到手机了,必须重启电脑才行 sudomv /var/run/usbmuxx /var/run/usbmuxd

LaunchDaemon & Lcokdown
用于与设备配对并启动其他服务。
成功配对后才能访问其他服务。成功配对需要解锁设备,并且用户单击手机屏幕上的“信任此设备”。后面主要都是与 Lcokdown 服务进行交互通讯
主要交互方式通过 plist 格式文件进行交互来启动相关服务,这里咱们使用 python plistlib 来进行 byte 流转换
例如启动 com.apple.syslog_relay 服务
2020-12-15 14:04:53,987 - plist_service.py[line:88] - DEBUG: 发送 Plist: {'Request': 'StartService', 'Label': 'pyMobileDevice', 'Service': 'com.apple.syslog_relay'} 2020-12-15 14:04:53,987 - plist_service.py[line:90] - DEBUG: 发送 Plist byte: b'\n\n\n\n\tLabel\n\tpyMobileDevice\n\tRequest\n\tStartService\n\tService\n\tcom.apple.syslog_relay\n\n\n'

Instruments 服务
想要与 Instruments 服务进行通讯,第一个我们需要找到入口,第二个我们需要知道交换 DTXMessage 数据流格式,并对其进行编解码
这里如何开启通道,以及数据解析,就要看向Troy Bowman 大佬在逆向工程大会上发布的演讲。
大佬的两个项目连接共大家参考
https://github.com/troybowman...
https://github.com/troybowman...
好了知道相关流程了,开始抄作业吧
DTXMessage Header 头解析
https://github.com/troybowman...
https://github.com/facebook/i... IDB 仓库也有大量不同协议头,有兴趣的可自行查看,使用 python 构造 DTXMessage 头解析协议头示例
class DTXMessageHeader(Structure): _fields_ = [ ('magic', c_uint32), ('cb', c_uint32), ('fragmentId', c_uint16), ('fragmentCount', c_uint16), ('length', c_uint32), ('identifier', c_uint32), ('conversationIndex', c_uint32), ('channelCode', c_uint32), ('expectsReply', c_uint32) ]class DTXMessagePayloadHeader(Structure): _fields_ = [ ('flags', c_uint32), ('auxiliaryLength', c_uint32), ('totalLength', c_uint64) ]

如何拿到 dtx 流数据可以参考项目:
https://github.com/danielpaul...
该项目可以直接获取和模拟器进行交互时的 dtx ,可以用来测试数据解析是否正常。
sysmontap.py 示例效果展示
[ { "PerCPUUsage": [ { "CPU_NiceLoad": 0.0, "CPU_SystemLoad": -1.0, "CPU_TotalLoad": 11.881188118811878, "CPU_UserLoad": -1.0 }, { "CPU_NiceLoad": 0.0, "CPU_SystemLoad": -1.0, "CPU_TotalLoad": 17.0, "CPU_UserLoad": -1.0 } ], "EndMachAbsTime": 656566442146, "CPUCount": 2, "EnabledCPUs": 2, "SystemCPUUsage": { "CPU_NiceLoad": 0.0, "CPU_SystemLoad": -1.0, "CPU_TotalLoad": 28.881188118811878, "CPU_UserLoad": -1.0 }, "Type": 33, "StartMachAbsTime": 656542341717 }, { "Processes": { "351": [ 351,// pid 417710325760,// memVirtualSize 770048,// memResidentSize 0.0,// cpuUsage 528, -82, 934232,// physFootprint 819200,// memAnon 0.0,// powerScore 708608// diskBytesRead ], "519": [ 519, 418581921792, 46628864, 13.8574323237612, 30281, 6465, 61965152, 20381696, 14.082756426586586, 57790464 ], "311": [ 311, 417748434944, 6635520, 0.0, 10189, 43, 1671552, 1540096, 0.0, 22274048 ], "271": [ 271, 417744961536, 4718592, 0.0, 8188, 473, 2130344, 1998848, 0.0, 36442112 ] }, "Type": 5, "EndMachAbsTime": 656567535862, "StartMachAbsTime": 656542716738 } ]

使用时注意事项及需求:
  • 电脑需要有 iOS 驱动 iTunes,Linux 安装 usbmuxd 驱动自行百度
  • 如果是 mac 可能没有 lockdown 权限,需要 sudo chmod 777 /var/db/lockdown/
  • 如果抛出 StartServiceError 异常,需要使用 xcode 激活一下设备,激活方式打开 xcode ,插上手机点击“信任”,即可拔掉数据线。(理论上这一步也可以用脚本进行激活,暂未实现)
本项目源码地址: https://github.com/YueChen-C/...
既然看完了,要是能点个 star 就最好啦
本项目基于
https://github.com/iOSForensi... 因为项目比较久,在项目基础上进行优化和修改并增加了 instruments 协议
参考项目:
https://github.com/troybowman...
https://github.com/troybowman...
https://github.com/danielpaul...
https://github.com/libimobile...
https://github.com/facebook/idb
原文由YueChen发表于TesterHome社区网站,点击原文链接可与YueChen交流。
使用纯 python 实现 Instruments 协议,跨平台 (win,mac,linux) 获取 iOS 性能数据
文章图片

今日份的知识已摄入~
  • 想了解更多前沿测试开发技术,结识行业大牛:欢迎关注「第十届MTSC大会·上海」
  • 1个主会场+12大专场,大咖云集精英齐聚
  • 12个专场包括:
    知乎、物流、开源、游戏、酷家乐、音视频、客户端
    服务端、数字经济、效能提升、质量保障、智能化测试
使用纯 python 实现 Instruments 协议,跨平台 (win,mac,linux) 获取 iOS 性能数据
文章图片

    推荐阅读