第一印象是影响消费者转化的主要因素,而启动时间通常反映了整个应用程序的质量。另外,还有一些公司发现,延迟的增加等同于销售量的下降。 在 DoorDash ,我们对应用程序的启动速度给予了很大的关注。...我们努力优化消费者的体验,并持续改善。 本文将探讨三个独立的优化,将我们的 iOS 消费者应用程序启动时间减少 60%。...其中一个最直接的亮点是我们在 Swift 协议一致性检查(检查一个类型是否符合协议)上花费的时间,但为什么呢? 架构原则,如单一责任原则、关注点分离等,是我们在 DoorDash 编写代码的关键。...在我们的例子中,我们只是在流程的后期调用或引用框架中的类,但框架仍然阻塞我们的启动时间;为什么? 当应用程序启动并加载到内存中时,动态链接器(dyld)负责让它准备好。...所讨论的第三方框架总共有九个模块初始化器,由于 dyld,所有这些初始化器都被授权在我们的应用程序运行 main() 之前运行。这九个初始化器归因于延迟我们应用程序启动的总成本。
在正式开启对fishhook的讲解之前,我先对之前的dyld的内容(应用程序的加载——dyld动态链接器的工作流程)做个回顾。 ?...Hook概述 Hook,中文译为“挂钩”或者“钩子”,在iOS的逆向中是指改变程序运行流程的一种技术。...我回顾的dyld的加载流程中,在dyld::_main函数中做的第二步就是加载共享缓存库。共享缓存库是什么呢?...这些动态库不会像静态库那样在编译的时候就加载进应用程序的内存,而是在应用程序启动的时候去动态链接。这些动态库就是放在共享缓存中的。...经过上面的fishhook原理分析,我们再回到文章一开始的第二个例子,为什么我自己定义的testFunc函数不能被Hook到呢? ?
之前曾在iOS 优化-瘦身文章中提到过 iOS 优化将会是一个专题,今天就带来 iOS 优化系列的第二篇,主要介绍一下启动优化,即如何减少应用的启动时间。...: 冷启动:设备重启或者 App 很长时间未启动时会发生;这个过程需要建立进程并且启动支持 App 的系统端服务;温启动:这个过程相对冷启动而言不会再重新建立系统端服务;恢复:严格意义上,这不是启动,只是一个从后台到前台状态的改变...为什么 App 很久未启动也会发生冷启动:在 iOS 上,处于后台的应用程序会逐渐从内存移除从而为前台应用程序提供更多的内存,所以当用户正在使用内存密集型的游戏应用,然后重新进入你的 App 程序,这时你的应用程序依赖于启动的框架和守护程序也可能需要重新启动并从磁盘调入...加入DYLD_PRINT_STATISTICS_DETAILS后 DYLD_PRINT_STATISTICS_DETAILS 在使用这种方式时,需要注意两个地方: iOS 15 以上的真机不再支持打印相关耗时数据...扩展 在 iOS 15 及更高版本中,系统可能会根据设备条件预热您的应用程序 — 启动未运行的应用程序进程以减少用户在应用程序可用之前等待的时间。
三、从DYLD源码的角度看APP启动流程 1、在main函数中断点查看 首先思考,在main函数中挂断点能不能查看到APP启动对应的堆栈?...可以看到在main函数断点并不能看到启动的对应堆栈,说明main函数也是被别人调用的,而不是处于app启动的堆栈中。 既然main查不到启动堆栈,那么比app更早执行的load方式是否可以找得到呢?...2、加载共享缓存库 在iOS系统中,每个程序依赖的动态库都需要通过dyld(位于/usr/lib/dyld)一个一个加载到内存,然而如果在每个程序运行的时候都重复的去加载一次,势必造成运行缓慢,为了优化启动速度和提高程序性能...在源码中可以看到在我们iOS系统中,共享缓存库被明确一定会被加载。 因为这种机制的存在,使得iOS在的对这些基础库的加载的时候时间和内存都得到节约!...系列干货持续更新中(记得关注我哦): iOS逆向(1)-密码学(RSA) iOS逆向(2)-密码学(Hash&对称加密) iOS逆向(3)-APP重签名 iOS逆向(4)-代码注入,非越狱窃取微信密码
一、启动过程 iOS开发中,main函数是我们熟知的程序启动入口,但实际上并非真正意义上的入口,因为在我们运行程序,再到main方法被调用之间,程序已经做了许许多多的事情,比如我们熟知的runtime的初始化就发生在...二、main函数启动之前 Mach-O可执行文件 Mach-O文件格式是 OS X 与 iOS 系统上的可执行文件格式,像我们编译过程产生的.O文件,以及程序的可执行文件,动态库等都是Mach-O文件。...上面提到库在使用的时候需要 Link,Link 的方式有两种,静态和动态,于是便产生了静态库和动态库。...如果环境缺少动态库或者库的版本不正确,就会导致程序无法运行(Linux 下喜闻乐见的 lib not found 错误)。...为什么 iOS 8 要添加动态库的支持?唯一的理由大概就是 Extension 的出现。
在实际 app 中,这个耗时会占用启动时间的一半左右。...现在在 iOS 16、tvOS 16或 watchOS 9上运行的现有应用程序,也会启用此功能。只要升级系统就能享受该功能。 那为什么能节省启动时间呢?我们来看下 dyld 的启动流程。...苹果现在使用的 dyld 版本是 dyld3 架构。dyld3 中的 dyld closure 发生在 out-of-process 中,也就是应用安装到启动之间的过程。...dyld2 执行过程是 in-process,也就是在程序进程内执行的,也就是说只有当应用程序被启动的时候,dyld2 才能开始执行任务; dyld3 则是部分 out-of-process,部分 in-process...这正是协议检查优化为什么让启动加快的原因。而且在纯 Swift 项目中,协议无处不在,这种优化相对更明显。
实际上,苹果是禁止我们开发人员在开发过程中使用自定义的动态库的,不然的话我们iOS的热修复也不会这么复杂,直接使用动态库就可以做到随时修改应用程序的内容了。...在iOS/Mac操作系统当中,只有很少量的进程只需要内核就能完成加载,基本上所有的进程都是动态链接的,所以Mach-O镜像文件中会有很多对外部的库和符号的引用,但是这些引用并不能直接使用,在启动的时候还必须要通过这些引用进行内容的填补...在程序依赖的系统动态库很多的时候,这种做法能够大大改善应用程序的启动性能。...而应用程序的main函数是应用程序的入口函数,也就是说,+load方法会在应用程序执行之前被调用,而应用程序执行之前的最后一步就是动态链接,因此我在+load方法里面打的断点实际上就是定位到了动态链接的阶段...经过搜索,我发现它是在_dyld_objc_notify_register中调用的。
在 iOS 15 公开推出后, 我们开始从用户端收到反馈报告:在打开我们的应用程序(Cookpad) 时他们被莫名其妙的反复退出到登录页。...即使我能够重现这个问题,我也100%确定我的手机在我点击应用图标的时候是解锁的,所以我不明白为什么会出现这个Keychain错误。...: 1、启动应用程序 2、简单使用 3、强制退出应用 4、锁定我的设备并将其放置约 30 分钟 5、解锁设备 6、再次启动应用 每当我在第 6 步中再次启动应用程序时,我 100% 确定设备已解锁...Duet 现在试图先发制人地 "预热" 第三方应用程序,在你点击一个应用程序图标前几分钟,通过dyld和预主静态初始化器运行它们。然后,该应用程序被暂停,随后的 "启动"似乎更快。...我们最初没有测试到它,因为我们很可能没有给 iOS 15 beta 版足够的时间来 "学习" 我们的使用习惯,所以这个问题只在现实世界的场景中再现,即设备认为我很快就要启动应用程序。
一、App产生 在探究iOS系统如何处理App启动之前,我们需要先了解下一个App是如何产生的: 1、编译:我们打开一个xcode工程,会看到若干个.h/.m组成;当我们进行编译时,编译器会分别对每个...二、iOS如何启动App WWDC视频中对启动过程做了一些介绍,先看iOS 13以前用dyld2是如何启动App: ?...iOS 13之后,系统提供的dyld3将启动过程的解析Mach-O文件的头部、解析动态库的依赖、符号查找定位的结果做了一个缓存,写到是disk中。...在启动时候,就直接读取缓存并校验是否有效,再进行后续的动态库加载、符号绑定和重定向以及静态初始化。 ...三、开发时如何对这些时间进行分析 开发阶段,可以在环境变量中设置DYLD_PRINT_STATISTICS值为1; ? 启动的时候,就可以看到控制台打出了具体的时间。
比如防止静态分析的,代码混淆,逻辑混淆;防止重签名的,应用ID检测,甚至是代码的HASH检测等等那么这篇文章我想聊聊关于代码的注入检测,因为发现随着iOS的系统的更新,我们防护的手段发生了一些变化。...利用yololib修改男子气概的文件,添加库路径。在应用启动时,使dyld会加载并执行。...我们使用MachOView分析如下: 当MachO文件中拥有这个字段,那么我们通过越狱环境插入动态库的方式就会失效。起到防护的作用。其原理在dyld的源码中可以分析到。...从iOS10开始,这种防护手段已失效 DYLD_INSERT_LIBRARIES检测 那么既然dyld的加载过程不再检测__restrict了段就我们的手动检测DYLD_INSERT_LIBRARIES...所以我们可以检索一下自己的应用程序所加载的动态库是否是我们源程序所有 其中libraries的英文变量白名单。
在 iOS 15 公开推出后, 我们开始从用户端收到反馈报告:在打开我们的应用程序(Cookpad) 时他们被莫名其妙的反复退出到登录页。...即使我能够重现这个问题,我也100%确定我的手机在我点击应用图标的时候是解锁的,所以我不明白为什么会出现这个Keychain错误。...: 1、启动应用程序 2、简单使用 3、强制退出应用 4、锁定我的设备并将其放置约 30 分钟 5、解锁设备 6、再次启动应用 每当我在第 6 步中再次启动应用程序时,我 100% 确定设备已解锁,因此我坚信我应该能够从...Duet 现在试图先发制人地 "预热" 第三方应用程序,在你点击一个应用程序图标前几分钟,通过dyld和预主静态初始化器运行它们。然后,该应用程序被暂停,随后的 "启动"似乎更快。...我们最初没有测试到它,因为我们很可能没有给 iOS 15 beta 版足够的时间来 "学习" 我们的使用习惯,所以这个问题只在现实世界的场景中再现,即设备认为我很快就要启动应用程序。
主要参考: iOS程序启动->dyld加载->runtime初始化 过程 iOS 程序 main 函数之前发生了什么 image.png 一个iOS App 的 main函数位于main.m...从dyld开始 Mach-O文件 Mach-O文件格式是OS X与iOS系统上的可执行文件格式,像我们编译过程产生的.O文件,以及程序的可执行文件,动态库等都是Mach-O文件,它的结构如下: image.png...-LoadCommands: 可以理解为加载命令,在加载Mach-O文件时会使用这里的数据来确定内存的分布以及相关的加载命令。...动态链接库 iOS 中用到的所有系统framework都是动态链接的,类比成插头和插排,静态链接的代码在编译后的静态链接过程就将插头和插排一个个插好,运行时直接执行二进制文件;而动态链接需要在程序启动时有需要再去完成插好相关的插头和插排...这个是在Xcode中看到的Link列表: image.png 这些framework将会在动态连接过程中被加载,另外还有隐含link的framework,可以测试出来:先找到可执行文件,我这里叫TestMain
但若要了解 load 方法内部实现流程,还得从iOS程序启动流程开始说起。 ...,并开启 dyld 缓存策略(主要区分于App的冷启动与热启动),从可执行文件的依赖顺序开始,递归加载所有依赖的动态链接库,所有依赖库通过 dyld 内部实现将 Mach-O 文件实例化为 image...但为什么该函数在 runtime 中被注释为:快速扫描不带锁的 load 方法。对于非懒加载类的 load 方法在 runtime 中被定义为不带锁的 load 方法?到现在还一直有这个疑问。 ...在整理写作过程中,我自己也发现了有很多还需要待完善的知识点,比如:每个类、分类 load 方法是何时、如何加载进可加载 load 列表中,dyld 动态链接库对 image 镜像文件的操作流程。...后续会不断补充,若是文章中出现不准确的地方还请多多指点。 ---- 该文章首次发表在 简书:我只不过是出来写写代码 博客,并自动同步至 腾讯云:我只不过是出来写写iOS 博客
1.2 静态库 使用静态链接:链接时会被完整的复制到可执行文件中去,所以如果两个进程(程序)都使用了某个静态库,则这两个进程中都需要包含这份静态库的代码。...动态库 1.4 dyld动态链接器 dyld(the dynamic link editor):【动态链接器】是苹果操作系统一个重要部分,在 iOS / macOS 系统中,仅有很少的进程只需内核就可以完成加载...,基本上所有的进程都是动态链接的,所以 Mach-O 镜像文件中会有很多对外部的库和符号的引用,但是这些引用并不能直接用,在启动时还必须要通过这些引用进行内容填充,这个填充的工作就是由 dyld 来完成的...2、应用程序加载流程 库&静态库&动态库&dyld分别了解后,需要对整个流程有个认识。 ? 应用程序编译过程.png 3、APP启动加载流程 在任意+(void)load方法中打下断点。 ?...启动入口 根据堆栈信息得知:程序加载的第一步就是dyld的_dydl_start函数,通过下载dyld-源码来进一步探索。 3.1 _dyld_start函数 ?
比如防止静态分析的,代码混淆、逻辑混淆;防止重签名的,应用ID检测、甚至是代码的HASH检测等等。那么这篇文章我想聊聊关于代码的注入检测,因为发现随着iOS系统的更新,我们防护的手段发生了一些变化。...利用yololib修改MachO文件,添加库路径.在应用启动时,dyld会加载并执行....此操作的作用是在可执行文件中添加一个Section.我们使用MachOView分析如下: 当MachO文件中拥有这个字段,那么我们通过越狱环境插入动态库的方式就会失效.起到防护的作用.其原理在DYLD...但是新版的dyld源码中去掉了__RESTRICT检测.从iOS10开始,这种防护手段已失效 DYLD_INSERT_LIBRARIES 检测 那么既然dyld加载过程不再检测__RESTRICT段了我们就手动的检测.../MobileSubstrate.dylib 白名单检测 那么上面的检测只可以检测越狱环境中的代码注入,在非越狱环境中,逆向工程师可以利用yololib工具注入动态库.所以我们可以检索一下自己的应用程序所加载的动态库是否是我们源程序所有
比如防止静态分析的,代码混淆、逻辑混淆;防止重签名的,应用ID检测、甚至是代码的HASH检测等等。那么这篇文章我想聊聊关于代码的注入检测,因为发现随着iOS系统的更新,我们防护的手段发生了一些变化。...利用yololib修改MachO文件,添加库路径.在应用启动时,dyld会加载并执行.....其原理在DYLD源码中可以分析到. dyld源码分析 首先这里分析的DYLD源码版本是519.2.2版本....但是新版的dyld源码中去掉了__RESTRICT检测.从iOS10开始,这种防护手段已失效 DYLD_INSERT_LIBRARIES 检测 那么既然dyld加载过程不再检测__RESTRICT段了我们就手动的检测.../MobileSubstrate.dylib 白名单检测 那么上面的检测只可以检测越狱环境中的代码注入,在非越狱环境中,逆向工程师可以利用yololib工具注入动态库.所以我们可以检索一下自己的应用程序所加载的动态库是否是我们源程序所有
本篇文章是我在学习逆向工程时整理的逆向工程工具集 只作为记录使用 并不是详细的教程 阅读本篇教程需要你有一定逆向工程知识 一,Cycript 介绍 iOS运行时工具 可hook运行时进程 并提供了以下能力...1,开发者可以在应用运行时查看和修改应用 得到所有正在使用的类名或方法名 2,运行时修改实例变量的值 3,Method Swizzling,替换特定方法的实现 4,运行时调用任意代码 当然Cycript.../MobileSMS.app/MobileSMS(模块地址) 6, 启动lldb(Mac终端) 启动:lldb 连接接debug server : #lldb 执行lldb命令 #process...connect connect://iOSIP:端口(该端口需要和debug server指定的端口一致) 五,dyld_decache 提取iOS系统内的二进制文件 从iOS 3.1开始,包括frameworks...,dyld_shared_cache_armv7s,dyld_shared_cache_arm64),可使用dyld_decache将其中的二进制文件提取出来 1, 用iFunBox从手机中拷贝dyld_deache
在我之前关于苹果在 iOS 14 中使用了 Swift 和 SwiftUI 的文章中,我统计了 iOS 中使用 Swift 和 SwiftUI 的内置应用程序的数量。...最后,为了尽可能完整,我对所有主要的 iOS 版本进行了分析,从 iPhone OS 1.0 到 iOS 14。这将详细概述不同编程语言在十多年的 iOS 开发中的演变。...范围 在开始分析之前,让我澄清一下范围。首先我我只分析了通常意义上的 'iOS',即内核上方的所有内容。不包括 XNU 内核和低级固件(SecureROM、基带、...)。...另一方面,我计算了位于 dyld 共享缓存中的框架,这是 iPhone OS 3.1 中引入的缓存机制,并且仍在 iOS 14 中使用。 另一点是您可能会注意到没有 Objective-C++。...检测不同的编程语言 在我之前关于苹果在 iOS 14 中使用 Swift 和 SwiftUI 的文章中,我统计了使用 Swift 和 SwiftUI 的内置应用程序。
大家好,又见面了,我是你们的朋友全栈君。...; 在适用于 macOS 12 的应用程序中,您可以使用属性检查器中的 localize 属性在非系统 NSMenuItem 上配置本地化的等效键选项; 在 iOS 15 的应用程序中,可以使用属性检查器中的...十四、链接 dyld 共享缓存已拆分为多个文件; 使用 macOS 12 或 iOS 15 或更高版本的部署目标构建的所有程序和 dylib 现在都使用链式修复格式; 统一 dyld2 和 dyld3。...现在所有平台上只有一个 dyld; DriverKit 运行时现在有一个 dyld 共享缓存; 如果 DYLD_PRINT_SEARCHING 环境变量在启动时设置为 1,则 dyld 会打印出它搜索的所有位置的路径...默认情况下,这些资源使用内置的音量 envelope 进行播放,该 envelope 在开始时将信号慢慢提升并在结尾慢慢降低,以避免产生咔嗒声。
1 dyld 1.1 dyld简介 在iOS系统中,几乎所有的程序都会用到动态库,而动态库在加载的时候都需要用dyld(位于/usr/lib/dyld)程序进行链接。...相关文章:《iOSCornerstone工具操作方法详解》 2 IOS程序启动过程 系统先读取App的可执行文件(Mach-O文件),从里面获得dyld的路径,然后加载dyld,dyld...Mach-O文件格式是OS X与iOS系统上的可执行文件格式,像我们编译过程产生的.O文件,以及程序的可执行文件,动态库等都是Mach-O文件。...LoadCommands:可以理解为加载命令,在加载Mach-O文件时会使用这里的数据来确定内存的分布以及相关的加载命令。...4 参考链接 iOS程序启动->dyld加载->runtime初始化 过程 http://www.cocoachina.com/ios/20170811/20228.html iOS中的dyld缓存是什么
领取专属 10元无门槛券
手把手带您无忧上云