iOS应用逆向工程:分析与实战


信息安全技术丛书 iOS 应用逆向工程:分析与实战 沙梓社 吴 航 刘 瑾 著 图书在版编目(CIP)数据 iOS 应用逆向工程:分析与实战 / 沙梓社,吴航,刘瑾著 . —北京:机械工业出版社,2014.1 (信息安全技术丛书) ISBN 978-7-111-45072-6 Ⅰ. i… Ⅱ. ①沙… ②吴… ③刘… Ⅲ. 移动终端 – 应用程序 – 程序设计 Ⅳ. TN929.53 中国版本图书馆 CIP 数据核字(2013)第 295103 号 版权所有·侵权必究 封底无防伪标均为盗版 本书法律顾问 北京市展达律师事务所 本书是 iOS 应用逆向工程方面的权威著作,三位作者都是 iOS 领域内的专家,拥有扎实的理论知识和 丰富的实践经验。本书内容以工具 + 代码的形式全面、系统地展开知识点,由浅入深,图文并茂地带着读 者一步步探索常规 iOS App 之外的世界。 本书分为四大部分,分别是概念、工具、理论和实战。前三部分介绍 iOS 逆向分析领域的背景、知识 体系,以及相应的工具集、理论知识;第四部分则通过 4 个实际案例来将前面的知识以实战的方式展开。 第一部分为概念篇,简单介绍 iOS 逆向分析的概念以及 iOS 平台系统架构。第二部分为工具篇,介绍一 系列基于 Mac 和 iOS 平台的配套工具,并且重点讲解其中的 class-dump、Theos、Reveal、IDA、GDB 等 5 个工具的使用方法,前 3 个侧重于使用,后 2 个侧重于分析。第三部分为理论篇,主要讲述 iOS 逆向 / 越狱方向的进阶必备理论知识。第四部分为实战篇,通过对 3 个 App Store App 及 1 个系统 App 进行逆向 分析的实战操作,让读者能够了解并同步实践已掌握的知识。 机械工业出版社(北京市西城区百万庄大街 22 号  邮政编码 100037) 责任编辑:罗词亮 印刷 2014 年 1 月第 1 版第 1 次印刷 186mm×240mm s 18 印张 标准书号:ISBN 978-7-111-45072-6 定  价:69.00 元 凡购本书,如有缺页、倒页、脱页,由本社发行部调换 客服热线: (010) 88378991 88361066 投稿热线: (010) 88379604 购书热线: (010) 68326294 88379649 68995259 读者信箱:hzjsj@hzbook.com 推 荐 序 一 前一段时间跟吴航在微博上私信聊天,他说正在写一本 iOS 方面的书,我让他等书出来后送一 本给我。前两天他发私信告诉我书写完了,让我给写个序,我当即表示“压力山大”,但还是欣然 答应了。 我认识吴航是在 2011 年 9 月,当时安全管家在找 iOS 开发高手。吴航作为我们安全管家 iOS 开发组的第一个工程师进来了,从零开始搭建 iOS 团队,负责包括安全管家越狱方向在内的 iOS 开 发。到了 2012 年年中,我认识到 iOS 自身的安全性非常好,在非越狱的 iOS 上我们能做的关于安 全的事情并不多,而越狱行为本身就是一个最大的安全风险,是用户主动选择的结果,跟我们自身的 安全理念不符,因此无须投入太多关注,恰好吴航本人也想出去做自己的事情,就支持了他的决定。 在那大半年的接触中,我发现吴航是个难得的技术人才,在技术的专研上有股子狠劲,拥有丰 富的开发实战经验,又善于利用各种工具解决问题,因此在他带团队的时候,评估出来的开发进度 基本上都能达成。我印象深刻的有两件事,第一件是开发越狱版安全管家。这方面官方公开的资料 几乎没有,涉及很多系统底层,因此需要自己摸着石头过河并反复尝试。当时我们制定了一个比较 紧的开发周期,希望在较短的时间内开发出越狱版安全管家的原型。吴航的压力不小,他接连几个 月都在研究系统底层,向各路高人请教,通过 Google 找寻国外网站上的资料,没日没夜地想办法, 后来终于在既定的时间内完成,让我看到了吴航不惧困难、敢于负责任的劲头。另一件事是开发 iOS 版安全管家,有个版本在我的手机上在不同页面间快速切换时有极小的概率会导致安全管家崩 溃,我就反馈给吴航。虽然只是个小概率事件,但他亲自反复高强度测试,细致地排查代码,最终 揪出了导致这个问题的一个内存指针 bug,足见其严谨的技术态度和对质量高标准的追求。 我虽然不做开发很多年了,但是至今不忘年轻时作为一个工程师,非常渴望与更高水平的人交 流,希望聆听高手们的实战经验分享。吴航愿意把他的经验总结成书,是广大 iOS 开发者的福音, 这本书能够带给大家实实在在的干货,让大家都能在技术的道路上再攀高峰。 赵岗 安全管家创始人 推 荐 序 二 在生活中,我们经常会忽略许多习以为常的事物。事实上,那些我们每天都与之打交道的东 西,往往都蕴含了一种“复杂”的美感:它们由成百上千的微小组件构成,各个微小组件各司其职, 在各自的岗位上发挥着不可替代的关键作用。现代生活中,智能手机已经成了我们每天必不可少的 工具,通过硬件、软件和固件协同合作,它为我们带来了好玩的游戏、有趣的照片以及便利的沟通 渠道——电话和短信。 在一个巴掌大的手机里,各个组件之间的关系错综复杂,互相影响。硬件为固件的运行提供支 撑平台,固件掌管软件,而软件又回过头来调度硬件。如果你能控制它们之中的哪怕一个,不就可 以让手机听命于你了吗?但 App Store 的插手,给你对它们的控制加上了重重阻力。 本书从独特的角度剖析 iOS 应用,你会从比 App Store App 更低一级的深度去了解软件的各个 组件在构造整个软件时起到的作用。你会由此发现你手机的“里世界”,它的能力远不止 App Store 所许可的那样有限,确切地说,它是一台功能齐全的计算机,在它的“里世界”里,一切皆有可能。 少年,从这里开始打破 App Store 的限制,重新认识真正的 iPhone 吧! Dustin L. Howett iPhone tweak 开发者 In our lives, we pay very little attention to things that work. Everything we interact with hides a fractal of complexity—hundreds of smaller components, all of which serve a vital role, each disappearing into its destined form and function. Every day, millions of people take to the streets with phones in their hands, and every day hardware, firmware, and software blend into one contiguous mass of games, photographs, phone calls, and text messages. It holds, then, that each component retains leverage over the others. Hardware owns firmware, firmware loads and reins in software, and software in turn directs hardware. If you could take control of one of them, could you influence a device to enact your own desires? V iOS App Reverse Engineering: Analysis and Practice provides a unique view inside the software running on iOS ™ , the operating system that powers the Apple iPhone® and iPad®. Within, you will learn what makes up application code and how each component fits into the software ecosystem at large. You will explore the hidden second life your phone leads, wherein it is a full-fledged computer and software development platform and there is no practical limit to its functionality. So, young developer, break free of restricted software and find out exactly what makes your phone tick! Dustin L. Howett iPhone Tweak Developer 自  序 我是一个热爱自助旅游的人。在大学的每个寒暑假,我都会抽出 7 ~ 10 天的时间,挑选国内 的一个地方当一次背包客。因为是自助游,没有导游帮忙安排一切,所以在出行前,我和同伴需要 花费不少时间制定计划、确认路线、购买车票,考虑路上可能出现的状况,并思考对策。都说旅游 能够开阔眼界,尤其是自助游,对此我深有体会:在路上见到的人和事让我增长见识,更重要的是, 在开始这段旅程前,我就需要对这段旅程中的点点滴滴有所准备——当身体还站在起点时,我的头 脑就已经到达终点了。这种思维方式对全局观的培养是有利的,也让我在思考其他问题时养成了从 长计议的习惯。 在 2009 年攻读硕士研究生前,我就曾深入思考过自己想要从事的研究方向。我学习的是计算 机专业,而从本科开始,身边绝大部分同学的研究平台是 Windows。作为一名动手能力并不强的普 通学生,如果我继续从事 Windows 的研究,有两点好处: 这个方向有海量成熟资料,我的学习之路上不会缺少参照; O 研究人数众多,碰到问题可以请教讨论的人比比皆是。 O 但是,从另一个侧面来看,这两点“好处”也并非有百利而无一害: 参考的资料越多,意味着我会越多地重蹈前人的“覆辙”; O 研究人数越多,意味着竞争压力更大。 O 总的来说,如果我从事与 Windows 相关的工作,起步会很顺利,但后续难保不被淹没在人海 里;如果另寻他路,入门会很辛苦,但坚持下去或能独辟蹊径。 幸运的是,我的想法与导师的如出一辙。他推荐我选择当时国内“小荷才露尖尖角”的移动 开发方向,而我在这之前一直使用的是一款飞利浦蓝屏手机,对智能手机毫无概念,更别说在上 面开发软件了。但是,导师是我仔细分析所有硕士生导师特点、与数名学长交换意见之后谨慎挑选 的师从对象,他的判断本身就含有我的判断,因此,我相信这个判断,于是开始搜寻移动开发的相 关资料。仅仅是了解了一些移动互联网和智能手机的概念,我就隐隐发现,这个行业顺应了人们对 计算机和互联网更小、更快、与生活融合更紧的历史发展趋势,一定大有可为,遂将研究方向定为 iOS。 VII 万事开头难,iOS 与我熟悉的 Windows 有着太多太多的不同:类 UNIX、完整生态系统、全封 闭、Objective-C 语言,还有影响我最深的“越狱”,这一切的一切在当时几乎找不到完整的参考资 料,有半年多近一年的时间,我折腾黑苹果的时间要以星期为单位。我硬着头皮把《 Objective-C 基础教程》上宛如天书一般的 Objective-C 代码敲入 Xcode,然后运行模拟器看效果,但代码和画 面完全对不上号;对 iOS 上似 UNIX 非 UNIX 的东西(如后台运行)大肆在 Google 上搜索,屡败 屡战。当同学们都发表了第一篇小论文时,我甚至没明确自己这个月究竟在干什么,我缺乏太多的 基础知识;当同学们周末出去 K 歌、打牙祭时,我一个人闷在宿舍里对着电脑啃代码;当同学们躺 在床上睡懒觉时,我一个人一大早爬起来去实验室。一个人是孤独的,但这种孤独换来的是学识的 积累,从而转化成内心的笃定,到了最后,因为内在的充实,就不再感到外在的孤独了。男人因孤 独而优秀,付出一定会有回报。经过一年多的磨合,在 2011 年 3 月的一天,以前晦涩难懂的代码 突然变得平易近人了,每一句的含义、每一行的关系都变得清楚了,零散的知识点在我的脑袋里被 连成了线,整个体系的逻辑慢慢清晰了。于是我快马加鞭,在 2011 年 4 月初完成了毕业设计的程 序雏形,并得到了当时对此方向并不抱太大希望的导师的高度评价——“从以前自我感觉良好的优 越感变成了肚里有货后的真正自信”,这标志着我对 iOS 研究的正式入门。明白自己在做什么之后, 就能有的放矢,研究效率呈几何倍率提高。在这两年里,我知道了 Theos 从而“勾搭”上了作者 DHowett,向 Activator 的作者 rpetrich 讨教过问题,跟 TheBigBoss 的管理员 Optimo 发生过争执, 他们是我这一路走来帮我解决实际问题最多的朋友;在开发 SMSNinja 的过程中结识了本书另一作 者航哥,在不断深入研究的同时认识了一票做人低调、办事高调的高手,意识到自己并不孤单—— 我们孤胆,我们并肩。 在本书即将出版的时候回望这 4 年,我不禁庆幸自己当初的选择是正确的。在 iOS 方向 4 年的 积淀就足够出一本书,这在 Windows 方向是不可想象的,而 Apple、Google 和 Microsoft 三大巨头 的不断发力和市场反馈也直接证明了这个行业一定会是互联网下一个十年的绝对主角,能够亲眼见 证并参与其中,我三生有幸。人生苦短,必须果敢,所以,少年,不要犹豫了,快到碗里来吧! 在受到航哥的邀请写作本书时,我是有些犹豫的。中国人口众多,各行各业竞争都很激烈,自 己走了那么多弯路,碰了 N 鼻子灰才总结提炼出的这些知识,一股脑儿全都交代出去了,会不会有 意无意地培养出更多“竞争对手”?这么做是不是把自己的优势拱手相让了?但是纵观越狱 iOS 的 发展历史,从基本的 Cydia 和 MobileSubstrate 到 Theos 这样的开发利器,再到 Activator 这样的神 级插件,这些对我影响最为深远的软件无一不是开源的,正是因为这些大牛分享了自己的“优势”, 我才能博采众长、逐渐成长;rpetrich 牵头的 tweakweek 和 posixninja 牵头的 openjailbreak 也都把 宝贵的独门秘籍大白于天下,让更多的爱好者参与越狱 iOS 生态环境的建设。他们是这个圈子里的 一线开发者,他们的优势完全没有因为“分享”而减少。我是一个受益于这个分享链条的人,怎么 VIII 能在小有所成之后就过河拆桥、断掉我这一环节呢?况且,我是打算在这条路上继续求索的,如果 我不停下,我的优势就会一直保持——我的竞争对手只有我自己。相信我们的分享会帮到很多和当 年的我一样在门外苦苦徘徊的开发者,集大家的智慧创造出的作品能够更好地让科技服务于人,而 且我也能结交更多志同道合的朋友,精神生活得到更大满足。这也聊可算作是从长计议吧。 啰啰唆唆说了很多,有些严肃,但这也正是我对待科学技术的态度。本书的内容适合国内绝大 多数不满足于折腾 App Store 的 iOS 爱好者,通篇干货,童叟无欺,比我的硕士毕业论文要实在得 多。更多后续的内容还请关注本书的官方微博 @iOS 应用逆向工程。让我们一起提升中国 iOS 开发 者在国际上的地位! 在这里,我要感谢母亲对我事业的全力支持,使我在钻研学术之时能尽可能少地因琐事分心。 感谢我的爷爷为我的英语启蒙,良好的英语素养是跟国际同行交流的必要条件。感谢我的导师授我 以渔,让我在硕士 3 年经历脱胎换骨的成长。感谢 DHowett、rpetrich 和 Optimo 等大牛对我的无 私帮助和尖锐批评,让我在快速成长的同时认识到差距巨大,不敢懈怠。感谢 Daniel、gradetwo、 zhuliang、大老、Vincent 等前辈对本书的审核与建议,以及对我这个初学者的点拨。感谢我的家人 和朋友们,他们的支持与鼓励是我前进下去的不竭动力。还要感谢我未来的女朋友,你 26 年来的 缺席让我能一心一意地学习知识,本书稿费啊有我的一半也有你的一半。事业、亲情、友情、爱情 是我等凡人的毕生追求,但往往只能求二争三,不可四者兼得,因为这个原因而有意、无意冒犯、 伤害过的人,我欠你们一声“对不起”,感谢你们对我的成全。 最后跟大家分享一首我喜爱的诗,啊!人生多么奇妙。 未选之路 罗伯特·弗罗斯特 一 黄色的树林里分出两条路, 可惜我不能同时去涉足, 我在那路口久久伫立, 我向着一条路极目望去, 直到它消失在丛林深处。 但我却选了另外一条路, 它荒草萋萋,十分幽寂; 一  Robert Frost(1874—1963),20 世纪美国最受欢迎的诗人之一、四度普利策奖得主。本篇为其代表诗作,原 题为“The Road Not Taken”。——编辑注 IX 显得更诱人、更美丽, 虽然在这两条小路上, 都很少留下旅人的足迹。 那天清晨落叶满地, 两条路都未见脚印痕迹。 呵,留下一条路等改日再见! 但我知道路径延绵无尽头, 恐怕我难以再回返。 也许多少年后在某个地方, 我将轻声叹息把往事回顾: 一片树林里分出两条路, 而我选了人迹更少的一条, 从此决定了我一生的道路。 (谨以此书纪念我已仙逝的外祖父刘汉民、祖母吴朝玉) snakeninny 前  言 为什么要写这本书 两年前我正式从传统网络设备行业转行进入移动互联网行业,当时正是移动应用开发市场最火 爆的时候,创业公司如雨后春笋般成立,社交类 App 更是大受追捧,只要有一个不错的构想就可 能拿到千万级投资,高价挖人组队的信息更是让人眼花缭乱。那时我已经开发了几个颇具难度的企 业应用类 App,对于那些轻量级的普通社交 App 不是太看得上,想着要玩点比较酷的技术,机缘 巧合进入了安全管家(北京安管佳科技有限公司),从零开始组建 iOS 团队,负责包括越狱方向在 内的 iOS 开发。 其实 iOS 越狱开发就是基于 iOS 的逆向分析工程,那个时候我并没有这方面的经验,面向的 是一个完全未知的领域,不过好在有 Google,国内国外的信息多少还是能够搜到点,而且对于 iOS 开发者,越狱开发 / 逆向分析并不是一个完全隔离的世界,虽然被分享出来的都是些零零散散甚至 重复度很高的知识,但是只要投入大量精力,把知识归纳总结,慢慢也就整理出一幅完整的图谱。 然而独自一人学习的过程是孤独的,尤其是遇见困难和问题无人交流,让人一筹莫展。每次 一个人扛下所有问题的时候,总是感叹:要是有一个水平不错的交流者该是多么幸福?虽然也可以 给 Ryan Petrich(@rpetrich)等一线大牛发邮件请教,但很多在我们看来当时解决不了的难题在这 类高手眼中可能就是个低级问题,不苦心钻研一番根本不好意思去问。这个阶段大概持续了有大半 年,直到 2012 年在微博上遇到本书的另一作者 snakeninny,那时他还是一个面临毕业的研究生, 整天“不务正业”地研究 iOS 底层,而且研究得还相当有深度。我曾和他提过:“你看,有多少人 都投入到 App 领域捞钱去了,你咋不去呢?”他说: “小弟的目标远大,要玩就朝着国际一线大牛的 目标去!”小兄弟,你够狠! 不过,多数时候我们都是自己在折腾,虽然偶尔在网上交流一下问题及解决方法,但往往能分 享得到一些有价值的内容。在一起合写本书之前,我们曾经合作逆向分析过陌陌,做了一个插件用 于在陌陌 iPhone 版上把美女的位置标注在地图上,当然我们都是善意的开发者,主动将这个漏洞 XI 告诉了陌陌,他们很快就修复了。这次,我们再次合作,将逆向分析这个方向的知识整理出版,呈 现给各位读者。 在接触越狱开发 / 逆向分析的这两年,个人感觉最大的收获就是看待 App 时,完全以一种庖丁 解牛的眼光去审视:App 如何构成、性能如何间接反映出开发团队水平高低。这些经验知识不仅可 用于越狱开发,也可用于传统的 App 开发,至于带来的影响,有正有负吧。我们不能因为所谓正 统的 iOS 平台不提倡越狱就否定这个领域的存在,盲目相信那些安全问题不存在不过是掩耳盗铃。 有经验的开发者都明白,知识掌握得越深,越会接触到底层技术。比如 sandbox 保护机制之外 到底有什么? runtime 只用来研究理论知识是不是有点大材小用了? 在 Android 领域,底层技术已经被扩散开,而在 iOS 领域,这个方向展现出来的内容还只是冰 山一角。虽然国外也有几本 iOS 安全方向的书籍,比如《Hacking and Securing iOS Applications》、 《 iOS Hacker’s Handbook 》,但是内容太难,多数人读不出所以然,不适合中国国情,即使我们这 些有一定经验的开发者,读这些书也像是在读大学教科书。 阳春白雪不为我们这些喜欢实践的技术宅所好,那么就来点下里巴人的,不必遮遮掩掩,直接 全面展开这些知识岂不是更痛快?于是就有了我们这本书,书中的内容以工具 + 代码的形式全面、 系统地展开知识点,由浅入深,图文并茂,旨在带着读者一步步地探索常规 iOS App 之外的世界。 我们不会像一些技术博客那样貌似很高深的独立分析某一片段的代码,而是尽我们所能将一个完整 的知识体系呈现给读者,相信读者一定会有所收获。 国内投入在越狱开发这个方向的人并不算少,但都比较低调,而且多集中在大公司中,比如腾 讯、360、91、WeiPhone,他们积累的技术非我们这些散兵游勇所能及,不过我们更愿意先将这些 知识分享出来,希望能够抛砖引玉。 读者对象 本书主要面向以下读者: 对 iOS 系统有浓厚兴趣的读者; O 中高级 iOS 开发人员,他们在掌握了普通 App 开发之后对 iOS 有更深的渴求; O 架构师,因为在逆向 App 的整个过程中,有心的技术人员能看到那些经典 App 在结构设计 O 上的经验、优势,并博采众长,有助于整体架构设计水平的提高; 在别的系统上从事逆向工程,想要转向 iOS 系统的逆向工程师。 O XII 如何阅读本书 本书将分为四大部分,分别是概念、工具、理论和实战。前三部分介绍 iOS 逆向分析这个领域 的背景、知识体系,以及相应的工具集、理论知识;第四部分则具体以 4 个实际案例将前面的知识 以实战的方式展开,让读者可以实践验证前面学到的知识并进一步更扎实地掌握相应的知识。 如果读者不具备一定的逆向分析经验,建议还是从头开始按顺序阅读,而不要直接跨越到第四 部分去模拟实战。虽然实战的成果似乎比较炫,但弄个半懂不懂也没意思对不对? 第一部分为概念篇,将简单介绍 iOS 逆向分析的概念以及 iOS 平台系统架构。 第二部分为工具篇,将会介绍一系列基于 Mac 和 iOS 平台的配套工具,并且重点讲解其中的 class-dump、Theos、Reveal、IDA、GDB 等 5 个工具的使用方法,前 3 个侧重于使用,后 2 个侧 重于分析。 第三部分为理论篇,除了介绍 iOS 逆向 / 越狱这个方向的理论知识之外,还顺带聊了一点 iOS 逆向 / 越狱方向的国际一线大牛们的八卦,轻松一下。 第四部分为实战篇,将通过对 3 个 App Store App 及 1 个系统 App 进行逆向分析的实战操作, 让读者能够了解并同步实践已掌握的知识。 勘误和支持 由于作者的水平有限,编写的时间也很仓促,书中难免会出现一些错误或者不准确的地方,恳 请读者批评指正,欢迎微博联系 @iOS 应用逆向工程,或访问我们的技术博客 http://iosre.com,我 们将尽量为读者提供满意的解答。如果你有更多的宝贵意见,也欢迎你通过微博或技术博客与我们 联系,我们很期待能够听到你们的真挚反馈。 致谢 首先要感谢 Jay Freeman(@saurik)这样的顶级高手,他奠定了越狱 iOS 的基石。还要感谢 Dustin Howett(@DHowett),是他提供的 Theos 这样强大的开发工具让我得以迈进 iOS 逆向分析 的大门。 感谢安全管家,为我进入 iOS 逆向领域提供了一个能充分发挥的环境,虽然我早已离开,但希 望它发展得更好。 感 谢 微 博 上 每 一 位 热 心 的 朋 友 —— 唐 巧 _boy、 卢 明 华、 你 在 瓦 西 里、isdada、Jagie、 XIII onevcat、戴铭、费西 FISH、xuzhanji、Life 无法 Debug、移动开发小冉、HorseLuke、网络蝎子、 hongjiang_wang、月之舞狼、StayNStay、bluesea 哈哈哈、郑州 IOS、青年土豆的烦恼、木土吉吉, 以及这个仓促写就的名单之外的更多朋友,感谢他们对我的支持和鼓励。特别感谢唐巧 _boy 的引 荐,他的热心帮助促成了本书的合作与出版。 感谢机械工业出版社华章公司的编辑杨绣国老师,感谢她的魄力和远见,在这 3 个月的时间里 始终支持我的写作,她的指点和帮助引导我们顺利完成全部书稿。 谨以此书献给我最亲爱的家人,以及众多热爱 iOS 开发的朋友们。 吴航(@hangcom2010) 目 录 推荐序一 推荐序二 自序 前言 第一部分 概念篇 第 1 章  i OS 逆向工程简介 2 1.1  i OS 软件逆向工程的要求 2 1.2  i OS 软件逆向工程的作用 2 1.2.1  与安全相关的 iOS 逆向 工程 4 1.2.2  与开发相关的 iOS 逆向 工程 5 1.3  i OS 软件逆向工程的一般过程 6 1.3.1  系统分析 7 1.3.2  代码分析 7 1.4  i OS 软件逆向工程用到的工具 8 1.4.1  监测工具 8 1.4.2  开发工具 9 1.4.3  反编译器 9 1.4.4  调试器 10 1.5  小结 11 第 2 章 越狱 iOS 平台简介 12 2.1  i OS 系统架构 12 2.1.1  iOS 目录结构 13 2.1.2  iOS 文件权限 15 2.2  i OS 程序类型 16 2.2.1  Application 16 2.2.2  Dynamic Library 19 2.2.3  Daemon 19 2.3  小结 20 第二部分 工具篇 第 3 章 Mac 工具集 22 3.1  c lass-dump 22 3.1.1  class-dump 介绍及下载 22 3.1.2  class-dump 使用演示 23 3.1.3  关于 class-dump 的补充 说明 25 3.2  T heos 25 3.2.1  Theos 简介 25 3.2.2  Theos 安装及编译 26 3.2.3  Theos 用法简介 28 3.2.4  Theos 开发 tweak 示例 47 XV 3.3  R eveal 49 3.3.1  Reveal 简介 49 3.3.2  Reveal 安装及功能扩展 50 3.4  I DA 55 3.4.1  IDA 简介 55 3.4.2  IDA 使用说明 56 3.4.3  IDA 分析示例 65 3.5  其他工具 68 3.5.1  iTools 68 3.5.2  dyld_decache 69 3.5.3  MesaSQLite 69 3.6  小结 70 第 4 章 iOS 工具集 71 4.1  S BSettings 71 4.2  M obileSubstrate 72 4.3  O penSSH 73 4.4  G DB 74 4.4.1  GDB 简介 74 4.4.2  GDB 的使用说明 74 4.5  C ycript 85 4.6  其他常用工具 88 4.6.1  BigBoss Recommended Tools 88 4.6.2  AppCrackr 88 4.6.3  iFile 89 4.6.4  MobileTerminal 89 4.6.5  Vi IMproved 90 4.6.6  SQLite 90 4.6.7  top 91 4.6.8  syslogd 92 4.7  小结 92 第三部分 理论篇 第 5 章  O bjective-C 相关的 iOS 逆向理论基础 94 5.1  t weak 的作用原理 94 5.1.1  Objective-C 语言的特性 94 5.1.2  MobileSubstrate 96 5.2  t weak 的编写套路 97 5.2.1  灵感的来源 98 5.2.2  分析文件,寻找切入点 99 5.2.3  定位目标函数 102 5.2.4  测试函数功能 104 5.2.5  解析函数参数 105 5.2.6  class-dump 的局限性 108 5.3  实例演示 108 5.3.1  得到灵感 108 5.3.2  分析文件 109 5.3.3  定位函数 115 5.3.4  测试函数 117 5.3.5  编写实例代码 117 5.4  小结 119 第 6 章  A RM 汇编相关的 iOS 逆向理论基础 120 6.1  A RM 汇编基础 120 6.1.1  基本概念 121 6.1.2  ARM/THUMB 指令解读 123 6.1.3  ARM 调用规则 129 6.2  在 IDA 中分析目标文件 131 6.2.1  分析函数实现细节 132 6.2.2  验证分析结果 139 6.3  在 GDB 中分析目标文件 142 XVI 6.3.1  跟踪代码执行流程 142 6.3.2  动态更改代码 147 6.4  小结 157 第四部分 实战篇 第 7 章  实战 1:去除 OPlayer Lite 的广告 160 7.1  O Player Lite 简介 160 7.2  分析源代码结构,并定位广告 横幅的代码 161 7.2.1  class-dump 获取 .h 文件 161 7.2.2  猜测广告横幅的出现 位置 161 7.2.3  分析 PlayView- Controller.h 162 7.3  去除广告横幅,节省流量 167 7.3.1  找到“准备”广告的 位置 167 7.3.2  追溯到网络连接的起点 173 7.4  编写调试代码 175 7.4.1  编写 Tweak_OPlayer- Lite.xm 175 7.4.2  编辑 control 176 7.4.3  编辑 RemoveOPlayer- Ads.plist 176 7.4.4  编辑 Makefile 177 7.4.5  编译 + 打包 177 7.4.6  安装 177 7.5  调试去广告插件 177 7.6  代码结果整理 178 7.7  小结 179 第 8 章  实战 2:WhatsApp 消息拦截 180 8.1  W hatsApp 简介 180 8.2  分析源代码结构,并定位 监听点 180 8.2.1  class-dump 获取 .h 文件 180 8.2.2  导入 Xcode 182 8.2.3  找到 WhatsAppApp- Delegate 182 8.2.4  找到 ChatManager 183 8.3  编写调试代码 184 8.3.1  分析函数列表 184 8.3.2  编写 Tweak_Whats- App.xm 185 8.3.3  编辑 control 186 8.3.4  编辑 monitor.plist 186 8.3.5  编辑 Makefile 186 8.3.6  编译 + 打包 187 8.3.7  安装 187 8.4  调试运行监听插件 187 8.4.1  运行 WhatsApp, SSH 连接 187 8.4.2  发送 / 接收消息, 监控日志 188 8.4.3  保存数据 189 8.5  代码结果整理 194 8.6  小结 195 第 9 章  实战 3:Instagram 图片 保存 196 9.1  I nstagram 简介 196 XVII 9.2  分析源代码结构,并定位 图片展示点 196 9.2.1  用 class-dump 获取 .h 文件 196 9.2.2  导入 Xcode 198 9.2.3  找到 AppDelegate 198 9.2.4  注入 Reveal 199 9.2.5  寻找图片页相关 class 200 9.3  保存图片 205 9.3.1  尝试保存图片 205 9.3.2  对 .h 文件进行瘦身 206 9.3.3  编译测试 208 9.4  弹出提示菜单 208 9.4.1  弹出菜单代码 208 9.4.2  使用 Theos 新增函数 210 9.4.3  使用 runtime 新增函数 211 9.5  代码结果整理 214 9.6  小结 215 第 10 章 实战 4:iOS 电话操作 216 10.1  常用电话操作 216 10.2  分析源代码结构,并定位 电话操作的代码 216 10.2.1  class-dump 获取 .h 文件 216 10.2.2  寻找拨打电话的函数 217 10.2.3  寻找接听电话的函数 229 10.2.4  寻找挂断电话的函数 234 10.2.5  寻找删除通话记录的 函数 236 10.2.6  寻找拦截电话的方法 238 10.3  编写调试代码 250 10.3.1  编写 Tweak_Phone- Operation.xm 250 10.3.2  编辑 control 254 10.3.3  编辑 Phone- Operation.plist 255 10.3.4  编辑 Makefile 255 10.3.5  编译 + 打包 + 安装 255 10.4  调试电话操作插件 255 10.5  代码结果整理 257 10.6  小结 257 越狱开发一览 258 沙箱逃脱 263 编写 tweak——新时代的 hacking 265 第一部分 概 念 篇 软件的逆向工程指的是通过分析一个程序或系统的功能、结构或行为, 将它的技术实现或设计细节推导出来的过程。当我们因为工作需要,或是对 一个软件的功能很感兴趣,却又拿不到它的源代码时,往往可以通过逆向工 程的方式对它进行分析。 对于 iOS 开发者来说,运行在 iOS 平台上的各种软件是我们知晓的最 复杂且超奇妙的虚拟物品之一,它们精巧而细致,新颖且创意十足。作为开 发人员,在使用这许多经典的 App 的同时,除了会称赞 App 的实现效果之 外,也会经常思考:它们的架构是如何搭建的?它们的运行机制又具体是什 么样的? 第 1 章 iOS 逆向工程简介 虽然从理论上来说 iOS App 是一个运行于沙箱(sandbox)中的程序,但并不表示我们就 对它束手无策,事实上,可以通过逆向工程来一窥其究竟。接下来,就引入 iOS 软件逆向工 程的概念。 1.1 iOS 软件逆向工程的要求 iOS 软件逆向工程指的是在软件层面上进行逆向分析的一个过程。读者如果想要达到对 iOS 软件较强的逆向分析能力,最好能非常熟悉 iOS 设备的硬件构成、iOS 系统的运行原理, 还要具备丰富的 iOS 开发经验。比如:拿到一个 App 之后能够清晰地推断出这个 App 使用 的技术,包括引用了哪些 framework、哪些经典的第三方代码,以及整个 App 工程大致的文 件个数、大致的代码行数,另外,还要想象一下如果由自己来组织设计开发,需要投入的人 员、时间和精力等。 这要求高吗?其实真的不算高!不过,这些条件都是充分非必要的。如果你目前还不具 备这些技术条件,那么有两个必要条件则一定要满足:强烈的好奇心和锲而不舍的精神。因 为在 iOS 软件逆向工程中,好奇心会驱动你去钻研经典的 App,而在钻研的过程中会遇到一 系列的困难和障碍,各种各样的技术坑,别人埋的、自己挖的,此时就需要锲而不舍的精神 来支撑你一步步向前走。但是请相信,在投入大量精力去编写代码、调试程序、分析逻辑之 后,你会在不断的试验和错误中感受到逆向工程的艺术之美。 1.2 iOS 软件逆向工程的作用 打个比喻,iOS 逆向工程就像一杆长矛,专门用于刺破目标程序本以为安全的保护盾, 而且还是从想象不到的角度来刺破。 对于微信、陌陌、WhatsApp 之类的 IM 软件,交流的信息是它们的核心;对于银行、交 第1章 iOS逆向工程简介 ◆ 3 易支付、电商类的软件,交易和客户信息是它们的核心。所有的核心数据都是需要重点保护 的,于是,数据库加密、网络连接加密、云存储等,开发人员通过各种手段重重保护,为的 就是让使用者能够高枕无忧。 可是 iOS 逆向工程对这些常规 App 的攻击不是来自同一个维度!这些攻击可用一个词来 定义:维度攻击(“维度攻击”的概念来自科幻小说《三体》,在此向《三体》致敬)。 从维度的角度来解释,我们看待常规 App 的感觉更像是将 App 的所有数据、UI、逻辑 内容都平展地铺开在一张二维的大纸上,外围圈上厚厚的城墙。它的平面图概念如同图 1-1 所示的谷歌地图一般。 图 1-1 飞到二维城市的上空来俯瞰整座城市 但是当我们跳跃到城墙之外,在三维的天空中俯瞰这个 App 的二维城堡,这个城堡的内 部结构几乎完全开放在眼前,包括所有的 Objective-C 函数定义、所有的接口数据、甚至所 有的函数内执行代码。城墙的防护意义已经荡然无存!此时限制我们的只是这个二维平面城 堡到底有多大,里面的内容到底有多丰富,以及排列是整齐有序的还是杂乱无章的。 此时,基于逆向工程的技术能力,可以选择想进入的任意点“高维进入”,监视甚至改变 二维平面上的运行逻辑,从而达到获取核心信息或软件设计原理等战术目的,而不是从二维 世界打破外围城墙强行攻破。 说得似乎很玄乎,但事实上,就笔者对十余款经典 App 以及 iOS 系统进行逆向的经历过 程来看,逆向工程的使用确实无一例外地达到了目标。 上面的比喻虽有些不恰当,但也形象地说明了 iOS 逆向工程的强大能力。现在回到正 题,概括起来,iOS 逆向工程主要有两个作用: 攻破目标程序,拿到关键信息,可以归类于与安全相关的逆向工程; O 4 ◆ 第一部分 概 念 篇 借鉴他人的程序功能来开发自己的软件,可以归类于与开发相关的逆向工程。 O 接下来就让我们将这些内容逐步展开。 1.2.1 与安全相关的 iOS 逆向工程 从前面的内容介绍已可以大致了解,iOS 逆向工程最突出的应用领域就是与安全相关的。 比如:工程师通过逆向一个金融类 App,来评定这个软件的安全等级;安全专家通过逆向 iOS 病毒,来找到杀毒的方法;安全公司通过逆向 iOS 系统电话、短信功能,来构建一个手 机防火墙…… 1. 评定安全等级 iOS 中那些具有交易功能的 App 一般会先加密敏感数据,然后将加密过的数据存储在本 地或通过互联网传输。而如果安全意识不够强,就完全有可能将重要的用户信息(如银行账 号和密码)直接用明文保存或传输,安全隐患极大。 假如一个有名望的公司考虑推出一款 App,为了让自己 App 的质量能够对得起用户的信 任,该公司请一家安全公司帮忙评估这个 App 的安全性。这家安全公司自然是不会被授权使 用这个 App 源代码的,也就是说,正向分析其安全性不可行,所以他们只有通过逆向工程, 来尝试“攻击”这个 App,然后依据结果评定其安全等级。 补充说明:前面在介绍“维度攻击”的概念时已经提及,App 虽然可以将低维的攻击防 守得如铜墙铁壁一般,但是挡不住高维的逆向攻击。不过不可以据此得出 App 不安全的结 论,因为 iOS 逆向工程的使用均来自一个前提:iOS 越狱。普通用户可能不知道,在将 iOS 设备越狱之后,即将整个平台都置于风险之中,此时也就更谈不上 App 的绝对安全了。在这 种环境下,我们使用这些逆向工程技术来分析评估目标 App 中可被攻击点有多少,可攻击点 越少的自然就是越安全的。 2. 逆向恶意软件 iOS 是智能移动终端操作系统,它同计算机操作系统已没有本质区别。从第一代开始, 它就已具备了上网功能,而互联网正是恶意软件传播的最好媒介。2009 年暴露的 Ikee 病毒 是 iOS 上公开的第一款蠕虫病毒,它会感染那些已经越狱并且安装了 SSH,但是又没有更改 其默认 root 密码“alpine”的 iOS 设备,并且将它们的锁屏背景图改成一个英国歌手的照片。 对于恶意软件的开发者来说,他们通过逆向工程定位系统和软件漏洞,利用漏洞渗透进 目标主机,获取敏感数据,甚至为所欲为。 对于杀毒软件的开发者来说,他们通过逆向工程剖析病毒样本,观察病毒行为,尝试杀 掉被感染主机上的病毒,并总结出可以防范病毒的方法。 3. 检查软件后门 开源软件的一大好处是其具有较好的安全性。成千上万的程序员浏览并修改开源软件的 代码,代码中几乎不可能存在任何后门,软件的安全问题往往在大白于天下之前就能及时得 到解决。而对于闭源软件,逆向工程是检查其软件后门的方法之一,比如我们常会在越狱的 第1章 iOS逆向工程简介 ◆ 5 iPhone 上安装 360、金山、腾讯等各家手机安全助手,这些服务程序的权限极高,无一例外 都拥有超强的能力,可以访问用户的通话记录、短信记录甚至更多,但我们不知道它们会不 会收集不该收集的用户信息,并把这些信息上传到自己的服务器。这种“有或没有”的结论 一直是个争议,我们得不到可信的官方数据,那么就只能通过逆向工程来检查该软件是否存 在类似的后门。 补充说一句,这些手机安全助手的开发者们本身也是逆向工程的高手,善用矛的同时也 善用盾,想要达到同台 PK 的水平需要积累锻炼足够长的时间才行。 4. 去除软件使用限制 iOS 开发者通过 App Store 或 Cydia 出售自己的 App,作为他们最主要的经济来源之一。 在软件的世界里,收费与盗版永远是同时存在的,而不少 iOS 开发者也在自己的 App 里加入 了反盗版的功能。但这场矛与盾的战争永远不会停止,再好的防御也会有被攻破的一天,防 止盗版几乎是一项不可能完成的任务。比如,Cydia 上最知名的“共享”源 xsellize 能够在几 乎所有收费软件发布后的 3 天内对其完成破解,让他们的用户免费享受到收费软件的功能。 1.2.2 与开发相关的 iOS 逆向工程 对于 iOS 开发者来说,逆向工程是最为实用的技术之一。例如,工程师可以逆向系统调 用,在自己的程序里使用一些文档中没有提及的私有功能,还可以逆向一些经典的软件,包 括竞争对手的软件,从而研究自己的软件能够借鉴些什么技术。 1. 逆向系统调用 程序员编写的软件能够运行在操作系统中,提供各种各样的功能,是因为操作系统本身 已经内嵌了这些功能,软件只是拿来重新组合使用罢了。众所周知,能在 App Store 上架的 App 的功能十分有限,在苹果公司严格的审核制度下,绝大多数 App 的实现都源于公开的开 发文档,而不能使用诸如锁屏、关机等文档中不涉及的功能。如果你的程序面向 Cydia,那 么不采用非公开功能将导致程序几乎没有竞争力。如果你的程序想拥有打电话、发短信等不 公开的功能,最有效的途径就是逆向 iOS 系统调用,还原系统实现相应功能的代码,并应用 到自己的程序中。 2. 借鉴别的软件 逆向工程最受欢迎的应用场合就是“借鉴”他人的软件功能。对于来源是 App Store 的 App 来说,大多数技术的实现并不复杂,巧妙的创意和良好的运营才是其成功的关键。如果 只是单纯借鉴其功能,那么采用逆向工程,费时费力,性价比不高,从头开发一个功能类似 的软件反而要省时省力得多。但是,当我们不知道被借鉴软件中的某个功能是如何实现的时 候,逆向工程就能起到关键性的作用。这种情况在大量使用私有函数的 Cydia 软件中尤其常 见,比如 2013 年 3 月面世的,号称 iOS 平台上第一款通话录音软件的 Audio Recorder,足够 有趣,但我们不知其原理如何,此时使用逆向工程的技术就能够对它了解一二。 有些软件,比如微信,功能经典,结构也非常复杂,所涉及的代码自然十分多。图 1-2 6 ◆ 第一部分 概 念 篇 是使用 class-dump 获取微信 4.5 的 .h 文件目录。 图 1-2 通过 class-dump 获取的微信 4.5 的 .h 文件目录 可以看到,在目录中共有 2267 个 .h 文件,光是将文件名一个个地看下来,天都要黑了。 那这种情况下应该怎么办?当然不可能这样傻傻地一个文件一个文件地读过去,事实上,这 时便可以通过合适的逆向分析工具加上丰富的开发经验来帮助定位关键信息点。对于微信这 样足够经典的目标程序,使用的技术及框架都非常有借鉴意义,所以也值得我们对它进行逆 向工程,收集相关的知识并学习,进而一步步地掌握其精髓。 1.3 iOS 软件逆向工程的一般过程 当我们想要逆向一个 iOS 软件时,应该从何入手?应该怎么思考?这本书的初衷就是引 导初学者走进 iOS 逆向工程的大门,培养读者从逆向的角度思考问题。 所谓的 iOS 逆向工程初学者,其实至少也是 iOS App 开发的中高级程序员了,理论上都 拥有相当丰富的开发经验。所以在后续的过程中,对于一些非常初级的技术原理,可能会讲 得非常简单,甚至直接被忽略,毕竟读那些内容对有经验的开发人员来说是在浪费时间。 一般来说,软件逆向工程可以看做系统分析和代码分析两个阶段的有机结合。在系统分 析阶段,要从整体上观察目标程序的行为特征、文件的组织架构,从而找到我们感兴趣的地 方。一旦能够较为熟练地操作这个程序,并且找到了我们想要逆向的点,就可以进入代码分 析阶段,利用各种工具对程序本身的二进制文件进行分析,达到我们的目的。 第1章 iOS逆向工程简介 ◆ 7 1.3.1 系统分析 在系统分析阶段,应在不同的条件下运行目标程序,在程序中进行各种各样的操作,观 察程序的行为特征,同时寻找我们感兴趣的功能点。比如:选择哪个选项会弹框,按下哪个 按钮会发声,输入什么内容屏幕会有什么显示;同时,还可以浏览文件系统,观察程序显示 的图片、程序的配置文件存放在哪里,对应的数据库文件中存放了哪些信息、是否加密等。 以新浪微博 App 为例,当我们将微博的目录展开时,会看到如图 1-3 所示的结构。在微 博目录下有 Documents、Library 等子目录,这些目录中放着对应的数据库文件以及缓存的图 片文件等。 另外,在 Documents 目录下还可以看到 db_36000_3414827754.dat 这样的文件,从文 件名上即可识别出它是数据库文件,此时使用 SQLite 工具打开便可看到如图 1-4 所示的数 据内容。 图 1-3 新浪微博 App 的 Documents 目录 图 1-4 新浪微博 App 的个人数据文件 此时,我们能够看到在新浪微博里的联系人、所发的微博内容等信息。 因为这些信息已经通过 App 自身的目录文件结构呈现在我们面前,所以可以看到,对 iOS 平台以及 App 的理解程度直接决定了我们在逆向工程时所需要花费的时间和精力,以及 所获取信息的性价比。 1.3.2 代码分析 在外围的分析完成之后,接下来就是对程序的可执行文件进行代码这一层级的分析了。 使用逆向分析的方法可以倒推出这个程序的设计思路、内部算法和实现细节,这是一个 非常复杂的过程,甚至可以说是一种解构的艺术。要想让自己的逆向工程水平达到艺术的高 度,需要对软件开发、CPU 工作原理和 iOS 有透彻的理解。而且很多软件的复杂度很高,即 使其代码规范、文档详尽,可是一旦开源,很多人还是会因其具有的复杂度而惊叹,比如 Activator 这样的系统级插件程序。一点一点地分析程序的底层指令绝非易事,也不是一本书 能够完全阐述清楚的。 本书的目标仅仅是向初学者讲述 iOS 逆向工程入门时所用到的工具和可能的思路,书中 8 ◆ 第一部分 概 念 篇 所提及的工具及知识均是笔者长期积累的个人经验之谈,对知识点的覆盖不可能面面俱到, 期望读者能结合书中的理论和实例举一反三,形成自己的学习方法。 1.4 iOS 软件逆向工程用到的工具 对于 iOS 的逆向工程,除了掌握理论知识之外,最重点的内容就是使用好各种工具了。 整个 iOS 逆向工程所涉及的工具数量达到数十款之多,而且这还未 100% 覆盖到。因为毕竟 在这一方向没有一套统一的教学规范来指明哪些工具该用,哪些工具不该用,各个参与者都 是根据自己掌握的深度及喜好来选择最称手的工具的。 好的工具,以及对这些工具的熟练使用能够极大地协助我们进行高效的逆向工程。在本 阶段的逆向工程中,介绍的工具集主要可以分为四大类:监测工具、开发工具、反汇编器 (disassembler)、调试器(debugger)。 1.4.1 监测工具 在逆向工程中,起到嗅探、监测、记录目标程序行为的工具统称为监测工具。这些工具 通常可以记录并显示目标程序的某些操作,如网络活动、文件访问等。iOS 逆向常用的监测 工具有 Reveal、tcpdump、libNotifyWatch 和 PonyDebugger 等。 图 1-5 中所呈现的是一款监测工具——Reveal,它可用来查看目标 App 的 UI 元素。 图 1-5 Reveal——用来查看目标 App 的 UI 元素的监测工具 使用 Reveal 可以非常直观地看见 App 的界面上各个 UI 元素之间的从属关系,并且轻 第1章 iOS逆向工程简介 ◆ 9 松、快捷地定位到我们想查看的 UI 元素。有了类似这样的工具,很多我们原本以为会非常 枯燥的分析工作均可以轻松搞定,达到事半功倍的效果。 1.4.2 开发工具 进入代码分析这一层级,就必须掌握开发工具的使用了。实际上监测工具与开发工具一 直都是组合使用的,单纯使用某一类工具根本无法深入。 对于有成熟开发经验的 iOS 程序员来说,Xcode 是最常用的开发工具,但在此之外,还 有可以用于开发越狱代码的工具,其中最方便也最有名的一个工具就是 Theos。这是一个非 常简单易用的开发工具,但是它能编译生成最具威力的 tweak 插件,直刺 App 心脏,完成我 们期望它完成的任务。 图 1-6 是 Theos 的创建工程命令行。 图 1-6 Theos——tweak 开发工具 在后面的工具篇中会详细介绍 Theos 的使用方法。仅从个人体验来说,这是让笔者最为 兴奋的开发工具,在接触、使用 Theos 之前,笔者感觉自己一直都被限制在普通 App 的低维 世界中,直到学会并掌握了 Theos 的使用方法,才觉得真正突破了普通 App 的开发界限,跨 越了维度的限制,可以从高维来看待 App 了。 1.4.3 反编译器 随着自己能力的一步步进阶,反编译器就会出现在我们的视野中。在 iOS 逆向工程领 域,反编译器主要就是 IDA。 IDA 是逆向工程中最常用的工具之一,横跨 Windows/Linux/Mac 平台,它会把目标程序 的可执行文件作为输入,然后输出这个程序的汇编代码,甚至伪代码。 反编译是跟 CPU 架构相关的,但像 IDA 这样强大的反编译器支持多种 CPU 架构,如 图 1-7 所示。 IDA 有免费版本,可以输出函数列表及对应的汇编代码。而相较于免费版的 IDA,收费 版本所能带来的功能就更为震撼了。图 1-8 是 IDA Pro(收费版)的截图,对于 iOS App,它 10 ◆ 第一部分 概 念 篇 能做到的不仅仅是反汇编,甚至连伪代码都能高度接近。 图 1-7 IDA——强大的反编译器 图 1-8 IDA 反编译 App 的伪代码 笔者第一次看到这样的伪代码时,不禁感叹:逆向分析工具都强大到了这一步,还有什 么是能藏得住的? 1.4.4 调试器 对程序员来说,调试器是相当熟悉的了,最常见、最熟悉的就是在 Xcode 中的单步调 试,程序员可以在某一行代码上设置断点,使调试器能够在那一行代码执行之前暂停程序执 行,并且显示程序当前的状态。 因为程序员拥有自己程序的源代码,所以调试器的断点可以指定在源代码的代码行上, 单步调试可以以源代码的行为单位执行代码。而熟悉 Xcode 调试的人也都知道,其实所谓 第1章 iOS逆向工程简介 ◆ 11 Xcode 的调试器,不过就是把 GDB(GNU Debugger)或 LLDB 做了一层图形化的包装,集 成在一起更好用而已。 但是在逆向工程中,我们往往没有目标程序的源代码,而且需要在 iOS 设备上进行调 试,此时就需要在 iOS 设备上运行基于命令行的 GDB 了。图 1-9 是使用 GDB 进行调试的 示例。 图 1-9 GDB——调试利器 当然,我们同样可以利用调试器设置断点、单步调试,来观察甚至更改程序的执行流 程,从而达到分析程序的目的,只不过这个过程不如拥有代码调试那么直观、方便。 1.5 小结 本章介绍了 iOS 软件逆向工程的基本概念、作用和一般的逆向过程,以及需要用到的一 些有代表意义的工具等,旨在让读者对 iOS 逆向工程有一个概念上的了解,详细的技术内容 会在后面的章节中逐一讲解。 第 2 章 越狱 iOS 平台简介 相较于 iOS 应用的高层表象,人们对其底层实现更感兴趣,这也是大家进行逆向工程的 原动力。 但是,我们也都知道,原版 iOS 是个对开发者封闭的黑盒子,直到 Redsn0w 等越狱组织 对 iOS 进行破解、越狱之后,这个盒子才被揭开,神秘的 iOS 系统得以完全展现在我们面前。 2.1 iOS 系统架构 对于原版(即未越狱)iOS,Apple 官方并未提供直接访问 iOS 文件系统的任何入口, iOS 开发者只需要遵循规定,参考文档即可完成工作,所以,纯粹的 App Store 开发者可能对 iOS 系统的目录结构一无所知。 因为沙箱及权限的关系,从 App Store 下载的 App 不能访问除自己目录以外的绝大多数 文件。这时,可以借助 Xcode,通过点击 Xcode → Organizer → Devices 浏览指定 App 的目 录结构,如图 2-1 所示。但是,这种方式也仅能访问 /var/mobile/Applications 下的 App 目录, 而对系统里的其他目录仍是束手无策。 图 2-1 使用 Xcode 查看 App 的目录结构 第2章 越狱iOS平台简介 ◆ 13 在越狱 iOS 中,用户可通过安装强大的第三方文件管理工具,如 iFunBox、iExplorer 或 iFile 等,访问 iOS 全系统文件。图 2-2 是用 iFile 查看 iOS 文件系 统的界面,它可以直接读取和修改系统中的任何文件,不用再顾 虑严格的沙箱与权限限制。 至此,逆向工程的大门已经向我们敞开了,一起来看看吧。 2.1.1 iOS 目录结构 iOS 是 由 Mac OS X 演 化 而 来 的, 而 Mac OS X 则 是 基 于 UNIX 操作系统的,这三者虽然有很大区别,但它们血脉相连。从 Filesystem Hierarchy Standard(文件系统层次标准)和 hier(7) 中, 可以一窥 iOS 目录结构设计的参考标准。 Filesystem Hierarchy Standard(以下简称 FHS)为类 UNIX 操 作系统的文件目录结构制定了一套标准,制定这套标准的初衷之 一是为了能让用户预知文件或目录的存放位置;Mac OS X 在此基础上形成了自己的 hier(7) 框架。类 UNIX 操作系统的常见目录结构如下所示。 / 根目录,以斜杠表示,其他所有文件和目录在根目录下展开。 O /bin:“binary”的简写,存放提供用户级基础功能的二进制文件,如 ls、ps 等。 O /boot :存放能使系统成功启动的所有文件,这些文件一般在内核用户程序开始执行前 O 得到调用。在 iOS 中此目录为空。 /dev :“ device”的简写,存放 BSD 设备文件。每个文件代表系统的一个块设备或字 O 符设备,一般来说,“块设备”以块为单位传输数据,如硬盘;而“字符设备”以字 符为单位传输数据,如调制解调器。 /sbin:“system binaries”的简写,存放提供系统级基础功能的二进制文件,如 netstat、 O reboot 等。 /etc:“et cetera”的简写,存放系统脚本及配置文件,如 passwd、hosts 等。在 iOS 中, O /etc 是一个符号链接,实际指向 /private/etc。 /lib:存放系统库文件、内核模块及设备驱动等。iOS 中此目录为空。 O /mnt:“mount”的简写,存放临时的文件系统挂载点。iOS 中此目录为空。 O /private:存放两个目录,分别是 /private/etc 和 /private/var。 O /tmp:临时目录。在 iOS 中,/tmp 是一个符号链接,实际指向 /private/tmp。 O /usr :包含了大多数用户工具和程序。/usr/bin 包含那些 /bin 和 /sbin 中未出现的基础 O 功能,如 nm、killall 等;/usr/include 包含所有的标准 C 头文件;/usr/lib 存放库文件。 /var :“ variable”的简写,存放一些经常更改的文件,比如日志、用户数据、临时文 O 件等。其中 /var/mobile/Applications 下存放了所有 App Store App,是要重点关注的目 录之一。 上述目录中的内容多用于系统底层,逆向难度较大,作为初学者,暂时不用在其中投入太 图 2-2 iFile 浏览文件目录 14 ◆ 第一部分 概 念 篇 多精力。从学和练的角度出发,循序渐进,由易到难,从我们熟悉的内容开刀,效率更高。 作为 iOS 开发者,日常操作所对应的功能模块大多来自 iOS 的独有目录,如下所示。 /Applications:存放所有的系统 App 和来自 Cydia 的 App,不包括 App Store App。越 O 狱的过程把 /Applications 变成了一个符号链接,实际指向 /var/stash/Applications,如 图 2-3 所示。这个目录也是我们要重点关注的目录之一。 /Developer:/Developer 相对没那么重要,它的出现完全是因为我们在 Xcode 连接 iOS O 设备时选择了“Use for Development”,这个目录的结构如图 2-4 所示。 /Library:用来存放系统 App 的数据。其中最需要关注的是 /Library/MobileSubstrate 目 O 录,因为这个目录中存放了所有基于 MobileSubstrate 的插件,其结构如图 2-5 所示。 在 iOS 系统中,MobileSubstrate 是一个提供 hook 功能的基础平台,运行在这个平台上 的插件通常被称为 tweak。       图 2-3 /Applications 目录 图 2-4 /Developer 目录 图 2-5 /Library/MobileSubstrate 目录 从图 2-5 中的文件列表中也可看到,/Library/MobileSubstrate 下通常有 3 类文件。 dylib:即 Dynamic Library,也就是 tweak 插件。 O plist:用于配合 dylib 使用的 fi lter 文件,指定注入目标,其格式如下(将在第 3 章中 O 详细介绍): Filter = { Bundles = (com.apple.springboard); }; disabled:被 SBSettings 禁用的 tweak 文件,图 2-5 中的 Weixin.disabled,其实就是把 O Weixin.dylib 改了个名字,不让 MobileSubstrate 加载而已。 /System:iOS 文件系统中最重要的目录之一,包含了大量的系统组件,其目录结构如 O 图 2-6 所示。其中需要重点关注的有: /System/Library/Frameworks 和 /System/Library/PrivateFrameworks : 存 放 iOS 中 的 各种 framework,SDK 文档里提及的各种 framework 只是冰山一角,还有数不清的 未公开功能等待我们去挖掘。 第2章 越狱iOS平台简介 ◆ 15 /System/Library/CoreServices 里的 SpringBoard.app:也就是桌面管理器,是用户与 系统交流的最重要的中介。 /System/Library/PreferenceBundles:其中的各种 bundle 提供了“设置”中的绝大多数 功能,也是 iOS 逆向工程入门阶段练习的好目标。 /User:用户目录,实际指向 /var/mobile,其目录结构如图 2-7 所示。 O 这个目录里存放了大量的用户数据,比如: /var/mobile/Media/DCIM:照片目录。 O /var/mobile/Library/SMS:短信目录。 O /var/mobile/Library/Mail:邮件目录。 O /var/wireless/Library/CallHistory:通话记录。这个稍微特殊一点,在 iOS 4 时代,通话 O 记录是存放在 /var/mobile/Library/CallHistory 下的。 另外一个非常重要的子目录就是 /var/mobile/Applications,里面存放的是通过 App Store 下载的 App,如图 2-8 所示。 图 2-6 System/Library 目录 图 2-7 /var/mobile 目录 图 2-8 /var/mobile/Applications 目录 在对 iOS 文件系统的目录结构有了初步了解之后就能够针对感兴趣的功能定位其对应的 文件,也可以开展下一步的工作了。 2.1.2 iOS 文件权限 iOS 是一个多用户操作系统。“用户”是一个抽象的概念,它代表对操作系统的所有权和 使用权,比如,mobile 用户是无法调用 reboot 命令重启 iOS 系统的,而 root 用户则可以;“组” 是用户的一种组织方式,一个组可以包含多个用户,一个用户也可以属于多个组。 iOS 中的每个文件都有一个属主用户和一个属主组,或者说这个用户和这个组拥有这个 文件;每个文件都具有一系列权限,简单地说,权限的作用在于说明文件的属主用户能做什 么,属主组能做什么,以及其他所有人能做什么。iOS 用 3 bit 来表示文件的使用权,从高位 到低位分别是 r(read)权限、w(write)权限以及 x(execute)权限。文件与用户的关系存在 16 ◆ 第一部分 概 念 篇 以下三种可能性: 此用户是属主用户。 O 此用户不是属主用户,但在属主组里。 O 此用户既不是属主用户,又不在属主组里。 O 因此,需要 3×3 bit 来表示一个文件的权限,其中 1 bit 如果置 1,则代表生效,置 0 代 表无效。例如,111101101 代表 rwxr-xr-x,即该文件的属主用户拥有 r、w、x 权限,而属主 组和其他所有人只具有 r 和 x 权限;同时,二进制的 111101101 转换成十六进制是 755,也 是一种常见的权限表示法。 2.2 iOS 程序类型 越狱 iOS 中最常见的程序有 Application、Dynamic Library 和 Daemon 三类。在当前阶段, 逆向工程的目标仍是这三类程序,对它们的了解越深入,逆向工程就会越顺利。这三类是不 同类型的程序,分工不同,其目录结构和文件权限也有较大区别。下面一起来看看吧。 2.2.1 Application Application 就是我们常说的应用程序,简称 App,其意义早已为所有 iOS 开发人员熟 知。不过,在本节中还是要对 Application 的概念作一个完整的回顾和补充。 1. bundle 在 iOS 这 个 体 系 中,bundle 的 概 念 来 源 于 NeXTSTEP, 其 实 它 就 是 一 个 按 某 种 标 准结构来组织的目录,其中包含可执行程序以及运行所需的资源。App、framework 和 PreferenceBundle 都是以 bundle 的形式存在的,当你将某个 bundle 确立为逆向目标后,绝大 多数逆向资源都可以在 bundle 内找到,大大减少了逆向工程的工作量。 2. App 的结构 在 App Store 中只能发布 App 这一种类型的程序,绝大多数 iOS 开发者对 App 的结构 很熟悉;但在越狱 iOS 平台上,还有两类 App 形式的存在:WeeApp(即依附于 Notifi cation Center 的 App)和 PreferenceBundle(即依附于 Settings 的 App),它们的结构与 App 类似,常 见于 Cydia 平台,这里也把它们看做是 App。 framework 的结构与 App 类似,但 framework 的 bundle 中存放的是一个动态链接库,而 不是可执行程序;相对来说,framework 在逆向工程中的地位比 App 更高,因为一个 App 的 绝大多数功能都是通过调用 framework 提供的接口来实现的。 在逆向工程时,主要关注 App 中的以下三个部分。 (1)Info.plist Info.plist 记录 App 的基本信息,如 bundle identifi er(唯一标识符)、可执行文件名、图标 文件名等。 第2章 越狱iOS平台简介 ◆ 17 这个文件之所以如此重要,是因为后面的开发调试过程中会利用 MobileSubstrate 对 App 进行 hook(钩取、注入),获取正确的 bundle identifi er 是成功逆向的第一前提。图 2-9 是 WhatsApp 的 Info.plist。 图 2-9 Info.plist 详情 (2)Executable(可执行程序) App 的执行入口,也是逆向工程最主要的目标之一,得到它之后,马上斧钺加身,class- dump、IDA 还有 GDB 等重磅武器都会攻击它。图 2-10 是笔者开发的一个联系人信息优化 App, 打开之后即可在目录结构中看到对应的可执行文件(即 Info.plist 中的“Executable fi le”)。 图 2-10 App 的目录内容 18 ◆ 第一部分 概 念 篇 (3)Resources(资源文件) 图标、图片、声音、配置文件、nib 文件以及各种 App 运行时用到的资源文件,同样可见 于图 2-10。其中,各种本地化字符串(.strings)是定位逆向目标的 重要线索。 3. /Applications 和 /var/mobile/Applications /Applications 目录用于存放系统 App 及从 Cydia 下载的 App, 如图 2-11 所示,在此目录下有来自 Cydia 的 iFile.app 和 iOS 自带的 MobileMail.app。 而 /var/mobile/Applications 目录存放的则是从 App Store 下载 的 App。 两者都是 App 文件,目录结构区别不大,但前者的属主用 户和属主组一般是 root 和 admin,后者的属主用户和属主组都 是 mobile,因而它们拥有不同的权限。不同的越狱工具对两者 sandbox(沙箱)的影响不同,一般来说,前者的 sandbox 比后者的限制要少很多。 顺便提一下, /Applications 目录中 App 安装包的格式多为 deb,而 /var/mobile/Applications 目录中 App 安装包的格式则为 ipa,由此又引申出了 iOS 平台上的不同安装包格式。 (1)deb deb 格式是 Debian 系统(包含 Debian 和 Ubuntu)专属安装包格式,配合 APT 软件管理 系统使用,是当前 Linux 下非常流行的一种安装包格式,是由 Cydia 作者 Jay Freeman(saurik) 移植到 iOS 中的。 由于 UNIX 类系统对权限、所有者、组的要求很严格,而 deb 格式安装包又经常会涉及 系统比较底层的操作,可以获取较高的权限,所以从 Cydia 下载的 App 都是 deb 格式的。 (2)ipa ipa 格式是苹果公司在 iOS 平台上推出的专属软件安装包,在 2.0 的固件发布后才正式投 入使用,是目前 iOS 中唯一的官方安装包格式。 ipa 的文件权限很小,sandbox 限制很大,访问资源十分有限,这一点早已为广大开发人 员所熟知。 (3)pxl pxl 格式起源于 Mac 系统上的 pkg 安装包,在 1.x 固件时代被广泛应用,曾经是 iOS 平台 上唯一的软件安装包,现在只有 91 手机助手等少数平台在使用,基本上可以忽略它的存在。 4. sandbox 通俗地说,iOS 中的 sandbox 就是一种访问限制机制。它是 iOS 最核心的安全部件之一, 其实现很复杂,这里不过多讨论其实现细节,只列举两个主要现象供大家参考。 (1)文件访问 总的来说,sandbox 会将 App 的文件访问限制在这个 App 的 bundle 内部,因此一个 App 不知道其他 App 的存在,更别说访问它们了。 图 2-11 Applications 目录 第2章 越狱iOS平台简介 ◆ 19 不过,App 可以通过 framework 来访问诸如照片、歌曲、通讯录等系统数据。 (2)硬件调用 App 可以通过 framework 来调用摄像头、GPS 模块等硬件。跟文件访问一样,因为这些 操作要通过 framework 来进行,所以 App 的作用范围还是在 iOS 的控制之内。 在初学阶段,我们的目标不是逆向 sandbox,所以知道以上两点就够用了。在 iOS 逆向 工程中,越狱操作已经破除了 iOS 的绝大多数安全限制,而这一点往往被我们忽略了。有时 会碰到一些看似奇怪的问题,比如某个 tweak 不能写文件,或者通过 objc_getClass 函数获取 不到类等,在确保自己的代码没有问题的前提下,这时就要回过头来检查这些问题是不是由 对权限或者 sandbox 的误解造成的。 2.2.2 Dynamic Library 大部分的 iOS 开发者可能都没有接触过 Dynamic Library 的概念,因为面向 App Store 的 App 用不到它。但是放眼望去,Cydia 中的 tweak 插件无一不是以 Dynamic Library 的形 式工作的,正是这些 tweak 插件的存在让我们能够随意定制自己的 iOS。所以,有必要了解 Dynamic Library 的基本知识。 Static Library 的概念很简单,在一个 App 启动时,系统会把 App 的代码和它所链接的 Static Library 一股脑放进分配好的内存空间里,不过因为一次性加载的内容过多,会造成 App 启动慢。 Dynamic Library 则相对“智能”一些,只有当 App 要用到这个 Library 时,系统才把这 个 Library 加载进内存。具体来说,当一个 App 启动时,iOS 内核创建一个新进程,然后把 App 的代码加载到新进程的内存空间里;同时内核还会启动 Dynamic Loader(/usr/lib/dyld), 把 App 需要的 Dynamic Library 加载进 App 的内存空间。 值得一提的是,虽然 Dynamic Library 的功能非常强大,但其本身并不是可执行程 序,而是以类似插件的形式存活在一个 App 中的,是这个 App 的一部分。所以,Dynamic Library 的权限及内存空间是由加载它的那个 App 决定的,比如你写了一个 Instagram 的 tweak 插件,用来将你喜欢的图片保存在本地,如果你的保存目录是 /var/mobile/Applications/ InstagramGUID/Documents,那么这样操作没有问题,你的 tweak 插件能够非常好地工作; 如果你想保存在 /Developer 下,而你又没注意或忘记了这个 tweak 插件是存活在一个 App Store App 里,那么可能在兴高采烈地保存了一大堆美图,准备回头细细品味时,却发现 /Developer 里啥也没有——你的写操作都被 sandbox 给禁掉了。 2.2.3 Daemon 相信本书的绝大部分读者从接触 iOS 开发的第一天起,就不断被 Apple 灌输这样一个观 念——iOS 中没有真正的后台多任务,你的 App 在后台将被大大限制 一。如果你是一个纯粹 的 App Store 开发者,坚信并坚守这个观念,那么它将是你的 App 通过 Apple 审核的助推剂; 一  从 iOS 7 开始,官方已经支持真正的后台多任务了。 20 ◆ 第一部分 概 念 篇 但既然你阅读了这本书,想要了解一些官方文档没有阐述的事实,那么你就要保持冷静,谨 慎思考,让我们一起回想一下 iPhone 上的一些现象。 1)当我们正在用 iPhone 上网或刷微博,接到一个电话,所有其他操作会立即中断,系 统第一时间将接听电话的界面呈现在用户面前。如果 iOS 中没有后台多任务,系统是如何迅 速响应这个来电的呢? 2)相信很多越狱手机上都装了 360、QQ 手机助手等类似的软件,用来拦截垃圾短信、 骚扰电话。出于对巨头们的不完全信任,以及同台竞技的小小需求,笔者也做了一款这样的 手机助手软件——SMSNinja。如果 iOS 中没有后台多任务,SMSNinja 这类助手软件如何保 证自己能及时处理收到的短信呢? 3)Backgrounder 是一款帮助 App 实现真正后台运行的强大插件,有了它,再也不 用担心因为 push 功能的不给力而漏收即时信息啦!如果 iOS 中没有真正的后台多任务, Backgrounder 怎么会存在呢? 这些现象无一不说明 iOS 中是存在真正的后台多任务的,那么难道是 Apple 说错了?并 不是!对于 App Store App 来说,当用户按下 home 键,程序就进入后台了,大多数功能都会 被暂停;也就是说,对于遵纪守法的 App Store 开发者来说,可以把 iOS 看做是没有真正后 台多任务的系统,因为你唯一能干的事不支持后台多任务。但 iOS 是基于 Mac OS X 的,后 者又跟所有类 UNIX 操作系统一样,有 daemon(即守护进程,Windows 称 Service)的概念, 随着越狱 iOS 全文件系统的开放,daemon 也展现在我们面前。 daemon 存在的意义就是后台运行,为用户使用操作系统提供各种“守护”,如 imagent 保障 iMessage 的正确收发,mediaserverd 处理几乎所有的音频、视频,syslogd 记录系统日志等。 iOS 系统中的 daemon 主要由一个可执行文件和一个 plist 文件构成。iOS 的根进程 是 /sbin/launchd,会在开机或接到命令时检查 /System/Library/LaunchDaemons 和 /Library/ Daemons 下所有符合格式规定的 plist 文件,然后按需启动对应的 daemon。这里的 plist 文件 与 App 中的 Info.plist 文件作用类似,记录了 daemon 的基本信息。 相对于 App,daemon 提供的功能要底层得多,逆向难度也要大得多,如果对某个 daemon 的认识不够成熟,随意更改它可能导致系统崩溃。当你在 iOS 逆向工程上有了一定 的积累后,就可以挑战这些 daemon 了,虽然相比 App,花费的精力会更多,但它们也会给 你更丰厚的回报。例如,前段时间刚刚发布的“ iOS 第一款电话录音软件”Audio Recorder 就是通过逆向 /usr/sbin/mediaserverd 这个 daemon 实现的。 2.3 小结 本章介绍了 iOS 系统架构和 iOS 中的常见程序类型,App Store 开发者一般不需要了解也 接触不到这些知识,容易形成概念盲区。本章旨在科普那些在逆向工程中非常重要但 Apple 官方闭口不提的 iOS 系统知识点,为 App Store 开发者打开 iOS 系统中的另一扇门。 就本章所涉及的知识点,将其内容扩充成一整本书都不为过,但作为逆向工程的初学 者,了解这些内容就已足够为我们的逆向之路开一个好头了。
还剩37页未读

继续阅读

下载pdf到电脑,查找使用更方便

pdf的实际排版效果,会与网站的显示效果略有不同!!

需要 8 金币 [ 分享pdf获得金币 ] 0 人已下载

下载pdf

pdf贡献者

1219372716

贡献于2014-12-14

下载需要 8 金币 [金币充值 ]
亲,您也可以通过 分享原创pdf 来获得金币奖励!
下载pdf