前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >iOS 崩溃排查技巧:如何获取系统库源码

iOS 崩溃排查技巧:如何获取系统库源码

作者头像
酷酷的哀殿
发布于 2021-01-04 02:10:46
发布于 2021-01-04 02:10:46
1.4K00
代码可运行
举报
文章被收录于专栏:酷酷的哀殿酷酷的哀殿
运行总次数:0
代码可运行

作者:酷酷的哀殿

APP 崩溃会导致用户体验下降,严重时甚至会导致用户卸载 APP。我希望从实际问题中去分享一些我日常工作上的小技巧,希望可以帮助到大家。

今天要分享的是「如何获取系统库源码」,问题源自于一位朋友遇到了一个系统库相关的 crash,一直无法定位到具体原因,所以想了解一下「如何根据 iOS 崩溃日志获取对应系统库源码」,正好我之前也遇到过类似的问题,所以和大家分享一下我的一些办法。

基础术语对齐

按照惯例,为了方便提高效率,避免歧义,第一部分是基础术语对齐。

如下,我们从官方文档 Examining the Fields in a Crash Report 的截取部分标准的崩溃日志进行讲解。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Incident Identifier: 6156848E-344E-4D9E-84E0-87AFD0D0AE7B
CrashReporter Key:   76f2fb60060d6a7f814973377cbdc866fffd521f
Hardware Model:      iPhone8,1
Process:             TouchCanvas [1052]
Path:                /private/var/containers/Bundle/Application/51346174-37EF-4F60-B72D-8DE5F01035F5/TouchCanvas.app/TouchCanvas
Identifier:          com.example.apple-samplecode.TouchCanvas
Version:             1 (3.0)
Code Type:           ARM-64 (Native)
Role:                Foreground
Parent Process:      launchd [1]
Coalition:           com.example.apple-samplecode.TouchCanvas [1806]

Date/Time:           2020-03-27 18:06:51.4969 -0700
Launch Time:         2020-03-27 18:06:31.7593 -0700
OS Version:          iPhone OS 13.3.1 (17D50)


22  libdyld.dylib                     0x00000001b6728360 start + 4

  • OS Version:系统版本号,13.3.1
  • OS Build Version:系统编译版本号,17D50
  • 二进制文件:二进制文件名,libdyld.dylib

为了方便方便区分 13.3.1 与 17D50,本文的概念与官方概念存在略微差异,敬请理解。

另外,我们下面还会用以下术语:

  • PROJECT_NAME:项目名,比如 dyld
  • PRODUCT_NAME,构建产物名称,通常与 PROJECT_NAME一致
    • 比如 libdyld.dylib就是由 lib + dyld + .dylib 组合而成,dyld 就是 PRODUCT_NAME
  • CURRENT_PROJECT_VERSION:项目版本号

根据OS Version定位源码

操作步骤:

  1. 结合 Xcode 发布文档,我们推测 iPhone OS 13.3.1 对应的 macOS 版本可能10.15.2
  2. 在 https://opensource.apple.com/ 找到对应的版本链接:
    • iOS 13.3.1
    • macOS 10.15.2
  3. 根据二进制文件名libdyld.dylib 猜测对应的PROJECT_NAMEdyld
  4. 对照 macOS 10.15.2 ,可以猜测CURRENT_PROJECT_VERSION733.8
  5. 点击dyld-733.8右侧的 ⬇️ 按钮进行下载
  6. 如果没有找到对应的源码文件,则尝试查找上一个系统版本,比如
    • [macOS 10.15.1] (https://opensource.apple.com/release/macos-10151.html)、
    • [macOS 10.15] (https://opensource.apple.com/release/macos-1015.html)

经过实际测试,大部分情况都可以根据二进制文件都能够找到对应的源码。

但是仍然会遇到以下两类问题:

1.CURRENT_PROJECT_VERSION 不够精确。

对于 iPhone OS 13.3.1,我们无法准确得知对应的macOS 系统版本号

2.部分情况无法根据二进制文件反推出对应的 PROJECT_NAME

比如,我们无法根据libsystem_asl.dylib找到与 system_asl 相关的源码

优化一

根据OS Build Version 获取 PROJECT_VERSION

操作步骤:

1、在 ~/Library/Developer/Xcode/iOS\ DeviceSupport目录下查找到对应的二进制文件

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
cd ~/Library/Developer/Xcode/iOS\ DeviceSupport 
find . -name libdyld.dylib

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./14.0 (18A373) arm64e/Symbols/usr/lib/system/libdyld.dylib

2、根据第1步的结果,我们发现本机只有14.0 (18A373) arm64e版本,与我们需要查找的 13.3.1 (17D50)不符。所以,尝试通过搜索引擎查找。

  • 比如 iOS-System-Symbols 就维护了超过100个系统符号文件目录的压缩版本。

3、通过 llvm-objdump 命令打印该二进制文件相关的二进制库信息

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
llvm-objdump -m --dylibs-used ./Symbols/usr/lib/system/libdyld.dylib

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./Symbols/usr/lib/system/libdyld.dylib:
 /usr/lib/system/libdyld.dylib (compatibility version 1.0.0, current version 828.4.0)
 /usr/lib/system/libsystem_platform.dylib (compatibility version 1.0.0, current version 254.0.0, upward)
 /usr/lib/system/libsystem_malloc.dylib (compatibility version 1.0.0, current version 317.0.1, upward)
 /usr/lib/system/libsystem_c.dylib (compatibility version 1.0.0, current version 1439.0.3, upward)
 /usr/lib/system/libsystem_pthread.dylib (compatibility version 1.0.0, current version 454.0.0, upward)
 /usr/lib/system/libxpc.dylib (compatibility version 1.0.0, current version 2038.0.15, upward)
 /usr/lib/system/libsystem_blocks.dylib (compatibility version 1.0.0, current version 78.0.0, upward)
 /usr/lib/system/libsystem_kernel.dylib (compatibility version 1.0.0, current version 7195.0.43, upward)
 /usr/lib/system/libsystem_sandbox.dylib (compatibility version 1.0.0, current version 1441.0.4, upward)
 /usr/lib/system/libdispatch.dylib (compatibility version 1.0.0, current version 1271.0.4, upward)
 /usr/lib/system/libcorecrypto.dylib (compatibility version 1.0.0, current version 1000.0.5, upward)
 /usr/lib/system/libcompiler_rt.dylib (compatibility version 1.0.0, current version 102.3.0, upward)

从输出的第2行,可以发现 libdyld.dylib对应的CURRENT_PROJECT_VERSION828.4.0

优化二

根据 OS Build Version 获取 PROJECT_NAME

操作步骤:

1、以 libsystem_asl.dylib为例,先通过find命令定位二进制文件的位置

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
find . -name libsystem_asl.dylib

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
./Symbols/usr/lib/system/libsystem_asl.dylib

2、通过 llvm-objdump -s 对整个二进制文件进行 dump 操作,并通过 grep 命令筛选 section __const的内容

考虑到下载系统符号文件会占用较大的空间,作者没有下载17D50对应的符号文件,而是以 18A373 为例进行说明

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
llvm-objdump -s ./Symbols/usr/lib/system/libsystem_asl.dylib | grep "Contents of section __const" -A 3

输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Contents of section __const:
 19a1c19f0 40282329 50524f47 52414d3a 61736c20  @(#)PROGRAM:asl
 19a1c1a00 2050524f 4a454354 3a737973 6c6f672d   PROJECT:syslog-
 19a1c1a10 3338350a 00000000 00000000 00107840  385...........x@
--
Contents of section __const:
 1d1641d18 00000000 00000000 20000000 00000000  ........ .......
 1d1641d28 821b1c9a 01001000 00000000 00000000  ................
 1d1641d38 ba1c1c9a 01000800 6c1c1c9a 01000800  ........l.......
--
Contents of section __const:
 1db1b7de8 00000000 00000000 00d91a1a 00005880  ..............X.
 1db1b7df8 00000000 00000000 00000000 00000000  ................
 1db1b7e08 00000000 00000000 00000000 00000000  ................

我们很容易发现以下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@(#)PROGRAM:asl PROJECT:syslog-385

实际上,根据 Xcode提供的Build System资料,我们可以得到以下信息:

  • PRODUCT_NAME: asl
  • PROJECT_NAMEsyslog
  • PROJECT_VERSION385

3、根据上一步的结果结果,直接打开 https://opensource.apple.com/tarballs/syslog 目录并选择对应的版本。

在作者写本文时14.0 (18A373) arm64e 对应的 syslog-385 还未开源。所以,我们只能下载到 syslog-377.40.1.tar.gz

总结

本文分享了两种特殊的技巧定位崩溃日志对应的源码。

如果有读者发现了其它方案,欢迎加入我们的微信群,一起参与讨论。

优点

缺点

系统版本号

简单,无需对应的符号文件

* 无法无法准确定位对应源码工程名问题* 存在无法准确定位源码版本问题

系统编译版本号

* 无法无法准确定位对应源码工程名问题* 存在无法准确定位源码版本问题

需要下载对应的符号文件(通常在1G以上)

关注我们

我们是「老司机技术周报」,每周会发布一份关于 iOS 的周报,也会定期分享一些和 iOS 相关的技术。欢迎关注。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2020-12-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 酷酷的哀殿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
深入浅出MachO
之前写了一篇深入浅出ELF,作为姊妹篇这次就来聊聊MacOS的可执行文件格式MachO。
evilpan
2023/02/12
9630
深入浅出MachO
[译] 苹果在 iOS 10.1 和 macOS 10.12 中使用了 Swift
Swift 是在 WWDC 2014 上发布的。Apple 的大部分示例代码项目现在都是用 Swift 编写的。但是 Apple 在 iOS 10.1 和 macOS 10.12.1 中使用 Swift 吗?
韦弦zhy
2021/12/24
1.6K0
[译] 苹果在 iOS 10.1 和 macOS 10.12 中使用了 Swift
iOS小技能:分析dyld的信息
name /usr/lib/libSystem.B.dylib (offset 24)
公众号iOS逆向
2022/08/22
5700
iOS小技能:分析dyld的信息
macOS 开发中动态库问题剖析
当我们的开发过程中使用到动态库,dyld: Library not loaded: 可能出现在开发的过程中(引入一个动态库)也有可能是开发过程中正常,发布安装包之后,在其它的机器上才出现;这个问题的原因很简单,就是image not found,那么如何解决呢?接下来就介绍一下如何游刃有余地处理这个错误。
ethanlin
2022/07/19
3.4K0
mac 使用Clang(Next-gen compiler infrastructure)配置VS Code C/C++环境
如果想使用 gcc 指令来编译执行 C++ 程序,需要在使用 gcc 指令时,手动为其添加
早起的鸟儿有虫吃
2025/01/12
4251
mac 使用Clang(Next-gen compiler infrastructure)配置VS Code C/C++环境
iOS_Crash报告的组成结构
操作系统有时会包含额外的诊断信息,这些信息使用多种格式,具体取决于崩溃的原因,并不是每个崩溃报告都包含。如:
mikimo
2023/10/18
4160
iOS_Crash报告的组成结构
iOS 程序 main函数之前发生什么
一个iOS App 的 main函数位于main.m中,这是我们熟知的程序入口。但对objc了解更多之后发现,程序在进入我们的main函数前已经执行了很多代码,比如熟知的+load方法等。
且行且珍惜_iOS
2022/05/13
8850
iOS 程序 main函数之前发生什么
【深度学习系列】关于PaddlePaddle的一些避“坑”技巧
最近除了工作以外,业余在参加Paddle的AI比赛,在用Paddle训练的过程中遇到了一些问题,并找到了解决方法,跟大家分享一下: ---- PaddlePaddle的Anaconda的兼容问题   之前我是在服务器上安装的PaddlePaddle的gpu版本,我想把BROAD数据拷贝到服务器上面,结果发现我们服务器的22端口没开,不能用scp传上去,非常郁闷,只能在本地训练。本机mac的显卡是A卡,所以只能装cpu版本的,安装完以后,我发现运行一下程序的时候报错了: 1 import paddle.v2
Charlotte77
2018/03/19
1.1K0
InlineHook新秀Dobby框架
由于最近研究InlineHook(内联钩子),发现了一个不错的框架,Dobby(原名:HOOKZz)。这家伙是一个全平台的inlineHook框架,它用起来就和fishhook一样,我们先看一下如何使用。
CC老师
2021/01/20
7.9K1
InlineHook新秀Dobby框架
【IOS开发高级系列】dyld专题
        在iOS系统中,几乎所有的程序都会用到动态库,而动态库在加载的时候都需要用dyld(位于/usr/lib/dyld)程序进行链接。很多系统库几乎都是每个程序都要用到的,与其在每个程序运行的时候一个一个将这些动态库都加载进来,还不如先把它们打包好,一次加载进来来的快。
江中散人_Jun
2023/10/16
8590
【IOS开发高级系列】dyld专题
一个静态注入动态库的工具: luject
luject是一个静态注入动态库的工具,它可以实现对mac, ios, linux, windows的可执行程序,动态库程序进行修改,来插入指定动态库实现注入和加载。
ruki
2020/05/11
1.5K0
iOS逆向工程工具集
本篇文章是我在学习逆向工程时整理的逆向工程工具集 只作为记录使用 并不是详细的教程 阅读本篇教程需要你有一定逆向工程知识
100001509164
2022/01/20
1K0
应用程序的加载——dyld动态链接器的工作流程
每一个应用程序都会依赖很多底层库、第三方库、自己的组件库、模块库等,这些库本质上是可执行的二进制文件,而这些二进制文件是可以被操作系统写入到内存的,我们日常所说的加载库就是指的将库写入到内存中。
拉维
2021/03/10
2K0
应用程序的加载——dyld动态链接器的工作流程
免越狱调试与分析黑盒iOS应用
上篇文章我们从开发者的角度介绍了如何建立iOS项目并且在真机上运行, 上上篇文章则介绍了Objective-C的基本概念和用法。而这一切,都是为了这次的铺垫。 今天,我们就要从攻击者的角度,尝试对黑盒iOS应用进行调试与动态跟踪(instrument)。
evilpan
2023/02/12
2K0
深入解构iOS系统下的全局对象和初始化函数
事件源于接入了一个第三方库导致应用出现了大量的crash记录,很奇怪的是这么多的crash居然没有收到用户的反馈信息! 在这个过程中每个崩溃栈的信息都明确的指向了是那个第三方库的某个工作线程产生的崩溃。这个问题第三方提供者一直无法复现,而且我们的RD、PM、QA同学在调试和测试过程中都没有出现过这个问题。后来再经过仔细检查分析,发现每次崩溃时的各线程的调用栈都大概是如下的情况:
欧阳大哥2013
2018/08/22
4.2K0
深入解构iOS系统下的全局对象和初始化函数
(5)初识Mach-O
APP从开发到安装到手机的过程1 MJRefreshExample.app中的MJRefreshExample文件是iOS中的可执行文件,文件格式是Mach-O APP从开发到安装到手机的过程2 逆向
czjwarrior
2018/05/28
1.2K0
Apple 操作系统可执行文件 Mach-O
Mach-O 的全称是 Mach Object File Format。可以是可执行文件,目标代码或共享库,动态库。Mach 内核的操作系统比如 macOS,iPadOS 和 iOS 都是用的 Mach-O。Mach-O 包含程序的核心逻辑,以及入口点主要功能。
用户7451029
2020/06/16
3K0
其他工程引用monkey dev的动态库dylib用法
monkey dev工程本身包含一个编译target app的工程和一个编译动态库的工程,我们可以选中编译动态库的target,使用release编译出一个双架构包。
fanspring
2019/04/24
2.3K0
其他工程引用monkey dev的动态库dylib用法
iOS逆向之Mach-O文件
阅读笔者的其他文章,我们了解了编译过程中的预处理、词法分析、语法分析、编译、链接等步骤。经常和编译型语言打交道的开发者对于可执行文件的编译过程肯定不陌生。我们用 Xcode 构建一个程序的过程中,会把源文件 (.m 和 .h) 文件转换为一个可执行文件。这个可执行文件中包含的字节码将会被 CPU (iOS 设备中的 ARM 处理器或 Mac 上的 Intel 处理器) 执行。
VV木公子
2021/03/07
11.1K0
iOS逆向之Mach-O文件
[译]从 iPhone OS 1.0 到 iOS 14 编程语言的演变
在我之前关于苹果在 iOS 14 中使用了 Swift 和 SwiftUI 的文章中,我统计了 iOS 中使用 Swift 和 SwiftUI 的内置应用程序的数量。一些读者问我是否可以提供一个百分比而不是一个绝对数字。
韦弦zhy
2021/12/24
2.1K0
[译]从 iPhone OS 1.0 到 iOS 14 编程语言的演变
相关推荐
深入浅出MachO
更多 >
领券
💥开发者 MCP广场重磅上线!
精选全网热门MCP server,让你的AI更好用 🚀
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验