Android软件安全与逆向分析

更多详情

内容简介: 《Android软件安全与逆向分析》由浅入深、循序渐进地讲解了Android 系统的软件安全、逆向分析与加密解密技术。包括Android软件逆向分析和系统安全方面的必备知识及概念、如何静态分析Android 软件、如何动态调试Android 软件、Android 软件的破解与反破解技术的探讨,以及对典型Android 病毒的全面剖析。
《Android软件安全与逆向分析》适合所有Android 应用开发者、Android 系统开发工程师、Android 系统安全工作者阅读学习。

目录: 《Android软件安全与逆向分析》
第1章  Android程序分析环境搭建  1
1.1  Windows分析环境搭建  1
1.1.1  安装JDK  1
1.1.2  安装Android SDK  3
1.1.3  安装Android NDK  5
1.1.4  Eclipse集成开发环境  6
1.1.5  安装CDT、ADT插件  6
1.1.6  创建Android Virtual Device  8
1.1.7  使用到的工具  9
1.2  Linux分析环境搭建  9
1.2.1  本书的Linux环境  9
1.2.2  安装JDK  9
1.2.3  在Ubuntu上安装Android SDK  10
1.2.4  在Ubuntu上安装Android NDK  11
1.2.5  在Ubuntu上安装Eclipse集成开发环境  12
1.2.6  在Ubuntu上安装CDT、ADT插件  13
1.2.7  创建Android Virtual Device  13
1.2.8  使用到的工具  15
1.3  本章小结  15
第2章  如何分析Android程序  16
2.1  编写第一个Android程序  16
2.1.1  使用Eclipse创建Android工程  16
2.1.2  编译生成APK文件  19
2.2  破解第一个程序  20
2.2.1  如何动手?  20
2.2.2  反编译APK文件  20
2.2.3  分析APK文件  21
2.2.4  修改Smali文件代码  26
2.2.5  重新编译APK文件并签名  26
2.2.6  安装测试  27
2.3  本章小结  28
第3章  进入Android Dalvik虚拟机  29
3.1  Dalvik虚拟机的特点——掌握Android程序的运行原理  29
3.1.1  Dalvik虚拟机概述  29
3.1.2  Dalvik虚拟机与Java虚拟机的区别  29
3.1.3  Dalvik虚拟机是如何执行程序的  34
3.1.4  关于Dalvik虚拟机JIT(即时编译)  36
3.2  Dalvik汇编语言基础为分析Android程序做准备  37
3.2.1  Dalvik指令格式  37
3.2.2  DEX文件反汇编工具  39
3.2.3  了解Dalvik寄存器  40
3.2.4  两种不同的寄存器表示方法——v命名法与p命名法  42
3.2.5  Dalvik字节码的类型、方法与字段表示方法  43
3.3  Dalvik指令集  44
3.3.1  指令特点  45
3.3.2  空操作指令  45
3.3.3  数据操作指令  46
3.3.4  返回指令  46
3.3.5  数据定义指令  46
3.3.6  锁指令  47
3.3.7  实例操作指令  47
3.3.8  数组操作指令  48
3.3.9  异常指令  48
3.3.10  跳转指令  48
3.3.11  比较指令  49
3.3.12  字段操作指令  50
3.3.13  方法调用指令  50
3.3.14  数据转换指令  51
3.3.15  数据运算指令  51
3.4  Dalvik指令集练习——写一个Dalvik版的Hello World  52
3.4.1  编写smali文件  52
3.4.2  编译smali文件  54
3.4.3  测试运行  54
3.5  本章小结  55
第4章  Android可执行文件  56
4.1  Android程序的生成步骤  56
4.2  Android程序的安装流程  59
4.3  dex文件格式  66
4.3.1  dex文件中的数据结构  66
4.3.2  dex文件整体结构  68
4.3.3  dex文件结构分析  71
4.4  odex文件格式  80
4.4.1  如何生成odex文件  80
4.4.2  odex文件整体结构  81
4.4.3  odex文件结构分析  83
4.5  dex文件的验证与优化工具dexopt的工作过程  88
4.6  Android应用程序另类破解方法  91
4.7  本章小结  93
第5章  静态分析Android程序  94
5.1  什么是静态分析  94
5.2  快速定位Android程序的关键代码  94
5.2.1  反编译apk程序  94
5.2.2  程序的主Activity  95
5.2.3  需重点关注的Application类  95
5.2.4  如何定位关键代码——六种方法  96
5.3  smali文件格式  97
5.4  Android程序中的类  100
5.4.1  内部类  100
5.4.2  监听器  102
5.4.3  注解类  105
5.4.4  自动生成的类  108
5.5  阅读反编译的smali代码  110
5.5.1  循环语句  110
5.5.2  switch分支语句  115
5.5.3  try/catch语句  121
5.6  使用IDA Pro静态分析Android程序  127
5.6.1  IDA Pro对Android的支持  127
5.6.2  如何操作  128
5.6.3  定位关键代码——使用IDA Pro进行破解的实例  132
5.7  恶意软件分析工具包——Androguard  135
5.7.1  Androguard的安装与配置  135
5.7.2  Androguard的使用方法  137
5.7.3  使用Androguard配合Gephi进行静态分析  144
5.7.4  使用androlyze.py进行静态分析  148
5.8  其他静态分析工具  152
5.9  阅读反编译的Java代码  152
5.9.1  使用dex2jar生成jar文件  152
5.9.2  使用jd-gui查看jar文件的源码  153
5.10  集成分析环境——santoku  154
5.11  本章小结  156
第6章  基于Android的ARM汇编语言基础——逆向原生!  157
6.1  Android与ARM处理器  157
6.1.1  ARM处理器架构概述  157
6.1.2  ARM处理器家族  158
6.1.3  Android支持的处理器架构  159
6.2  原生程序与ARM汇编语言——逆向你的原生Hello ARM  160
6.2.1  原生程序逆向初步  160
6.2.2  原生程序的生成过程  162
6.2.3  必须了解的ARM知识  164
6.3  ARM汇编语言程序结构  166
6.3.1  完整的ARM汇编程序  166
6.3.2  处理器架构定义  167
6.3.3  段定义  168
6.3.4  注释与标号  169
6.3.5  汇编器指令  169
6.3.6  子程序与参数传递  170
6.4  ARM处理器寻址方式  170
6.4.1  立即寻址  170
6.4.2  寄存器寻址  171
6.4.3  寄存器移位寻址  171
6.4.4  寄存器间接寻址  171
6.4.5  基址寻址  171
6.4.6  多寄存器寻址  171
6.4.7  堆栈寻址  172
6.4.8  块拷贝寻址  172
6.4.9  相对寻址  172
6.5  ARM与Thumb指令集  173
6.5.1  指令格式  173
6.5.2  跳转指令  174
6.5.3  存储器访问指令  175
6.5.4  数据处理指令  177
6.5.5  其他指令  184
6.6  用于多媒体编程与浮点计算的NEON与VFP指令集  185
6.7  本章小结  186
第7章  Android NDK程序逆向分析  187
7.1  Android中的原生程序  187
7.1.1  编写一个例子程序  187
7.1.2  如何编译原生程序  188
7.2  原生程序的启动流程分析  194
7.2.1  原生程序的入口函数  194
7.2.2  main函数究竟何时被执行  198
7.3  原生文件格式  199
7.4  原生C程序逆向分析  200
7.4.1  原生程序的分析方法  200
7.4.2  for循环语句反汇编代码的特点  204
7.4.3  if...else分支语句反汇编代码的特点  208
7.4.4  while循环语句反汇编代码的特点  211
7.4.5  switch分支语句反汇编代码的特点  215
7.4.6  原生程序的编译时优化  218
7.5  原生C++程序逆向分析  222
7.5.1  C++类的逆向  222
7.5.2  Android NDK对C++特性的支持  225
7.5.3  静态链接STL与动态链接STL的代码区别  227
7.6  Android NDK JNI API逆向分析  232
7.6.1  Android NDK提供了哪些函数  232
7.6.2  如何静态分析Android NDK程序  233
7.7  本章小结  235
第8章  动态调试Android程序  236
8.1  Android动态调试支持  236
8.2  DDMS的使用  237
8.2.1  如何启动DDMS  237
8.2.2  使用LogCat查看调试信息  238
8.3  定位关键代码  240
8.3.1  代码注入法——让程序自己吐出注册码  240
8.3.2  栈跟踪法  244
8.3.3  Method Profiling  247
8.4  使用AndBug调试Android程序  250
8.4.1  安装AndBug  251
8.4.2  使用AndBug  251
8.5  使用IDA Pro调试Android原生程序  254
8.5.1  调试Android原生程序  255
8.5.2  调试Android原生动态链接库  256
8.6  使用gdb调试Android原生程序  260
8.6.1  编译gdb与gdbserver  260
8.6.2  如何调试  262
8.7  本章小结  264
第9章  Android软件的破解技术  265
9.1  试用版软件  265
9.1.1  试用版软件的种类  265
9.1.2  实例破解——针对授权KEY方式的破解  265
9.2  序列号保护  271
9.3  网络验证  272
9.3.1  网络验证保护思路  272
9.3.2  实例破解——针对网络验证方式的破解  273
9.4  In-app Billing(应用内付费)  277
9.4.1  In-app Billing原理  277
9.4.2  In-app Billing破解方法  280
9.5  Google Play License保护  281
9.5.1  Google Play License保护机制  281
9.5.2  实例破解——针对Google Play License方式的破解  283
9.6  重启验证  284
9.6.1  重启验证保护思路  285
9.6.2  实例破解——针对重启验证方式的破解  285
9.7  如何破解其他类型的Android程序  296
9.7.1  Mono for Android开发的程序及其破解方法  296
9.7.2  Qt for Android开发的程序及其破解方法  301
9.8  本章小结  309
第10章  Android程序的反破解技术  310
10.1  对抗反编译  310
10.1.1  如何对抗反编译工具  310
10.1.2  对抗dex2jar  311
10.2  对抗静态分析  312
10.2.1  代码混淆技术  312
10.2.2  NDK保护  315
10.2.3  外壳保护  316
10.3  对抗动态调试  316
10.3.1  检测调试器  316
10.3.2  检测模拟器  317
10.4  防止重编译  318
10.4.1  检查签名  318
10.4.2  校验保护  319
10.5  本章小结  320
第11章  Android系统攻击与防范  321
11.1  Android系统安全概述  321
11.2  手机ROOT带来的危害  321
11.2.1  为什么要ROOT手机  321
11.2.2  手机ROOT后带来的安全隐患  322
11.2.3  Android手机ROOT原理  322
11.3  Android权限攻击  329
11.3.1  Android权限检查机制  329
11.3.2  串谋权限攻击  333
11.3.3  权限攻击检测  336
11.4  Android组件安全  339
11.4.1  Activity安全及Activity劫持演示  340
11.4.2  Broadcast Receiver 安全  343
11.4.3  Service安全  345
11.4.4  Content Provider安全  346
11.5  数据安全  347
11.5.1  外部存储安全  347
11.5.2  内部存储安全  348
11.5.3  数据通信安全  350
11.6  ROM安全  351
11.6.1  ROM的种类  352
11.6.2  ROM的定制过程  352
11.6.3  定制ROM的安全隐患  359
11.6.4  如何防范  360
11.7  本章小结  361
第12章  DroidKongFu变种病毒实例分析  362
12.1  DroidKongFu病毒介绍  362
12.2  配置病毒分析环境  363
12.3  病毒执行状态分析  364
12.3.1  使用APIMonitor初步分析  365
12.3.2  使用DroidBox动态分析  369
12.3.3  其他动态分析工具  373
12.4  病毒代码逆向分析  376
12.4.1  Java层启动代码分析  376
12.4.2  Native层启动代码分析  381
12.4.3  Native层病毒核心分析  393
12.5  DroidKongFu病毒框架总结  404
12.6  病毒防治  406
12.7  本章小结  406

前言: 近几年,Android在国内的发展极其迅猛,这除了相关产品强大的功能与丰富的应用外,更是因为它优良的性能表现吸引着用户。2011年可谓是Android的风光年,从手机生产商到应用开发者都纷纷捧场,短短几个月的时间,Android在国内红遍了大街小巷,截止到2012年的第一个季度,Android在国内的市场份额就超过60%,将曾经风靡一时的塞班系统远远的甩在了身后,与此同时,它也带动了国内移动互联网行业的发展,创造了更多就业的岗位,国内IT人士为之雀跃欢呼。
随着Android在国内的兴起,基于Android的平台应用需求也越来越复杂。形形色色的软件壮大了Android市场,也丰富了我们的生产生活,越来越多的人从起初的尝试到享受再到依赖,沉浸在Android的神奇海洋中。事情有利也总有弊,即使Android如此优秀也会有怨声载道的时候,各种信息泄露、恶意扣费、系统被破坏的事件也屡见不鲜,Android系统的安全也逐渐成为人们所关注的话题。
如今市场上讲解Android开发的书籍已经有很多了,从应用软件开发层到系统底层的研究均丰富涵盖,其中不乏一些经典之作,然而遗憾的是,分析Android软件及系统安全的书籍却一本也没有,而且相关的中文资料也非常匮乏,这使得普通用户以及大多数Android应用开发者对系统的安全防护及软件本身没有一个全面理性的认识。因此,笔者决定将自身的实际经验整理,编写为本书。
内容导读
本书主要从软件安全和系统安全两个方面讲解Android平台存在的攻击与防范方法。
第1章和第2章主要介绍Android分析环境的搭建与Android程序的分析方法。
第3章详细介绍了Dalvik VM汇编语言,它是Android平台上进行安全分析工作的基础知识,读者只有掌握了这部分内容才能顺利地学习后面的章节。
第4章介绍了Android平台的可执行文件,它是Android软件得以运行的基石,我们大多数的分析工作都是基于它,因此这部分内容必须掌握。
第5章起正式开始了对Android程序的分析,对这部分的理解与运用完全是建立在前面章节的基础之上。这一章详细讲述了Android软件的各种反汇编代码特征,以及可供使用的分析工具,如何合理搭配使用它们是这章需要学习的重点。
第6章主要讲解ARM汇编语言的基础知识,在这一章中,会对ARM汇编指令集做一个简要的介绍,为下一章的学习做铺垫。
第7章是本书的一个高级部分,主要介绍了基于ARM架构的Android原生程序的特点以及分析它们的方法,读者需要在这一章中仔细的体会并实践,鉴于此类程序目前在市场上比较流行,读者在阅读时需要多进行实践操作,多动手分析这类代码,加强自己的逆向分析能力。
第8章介绍了Android平台上软件的动态调试技术,动态调试与静态分析是逆向分析程序时的两大主要技术手段,各有着优缺点,通过动态调试可以让你看到软件运行到某一点时程序的状态,对了解程序执行流程有很大的帮助。
第9章详细介绍了Android平台软件的破解方法。主要分析了目前市场上一些常见的Android程序保护方法,分析它们的保护效果以及介绍如何对它们进行破解,通过对本章的学习,读者会对Android平台上的软件安全有一种“恍然大悟”的感觉。
第10章介绍了在面对软件可能被破解的情况下,如何加强Android平台软件的保护,内容与第9章是对立的,只有同时掌握了攻与防,才能将软件安全真正地掌握到位。
第11章从系统安全的角度出发,分析了Android系统中不同环节可能存在的安全隐患,同时介绍了面对这些安全问题时,如何做出相应的保护措施。另外,本章的部分小节还从开发人员的角度出发,讲解不安全代码对系统造成的危害,读者在掌握这部分内容后,编写代码的安全意识会明显提高。
第12章采用病毒实战分析的方式,将前面所学的知识全面展示并加以应用,让读者能彻底地掌握分析Android程序的方法。本章的内容详实、知识涵盖范围广,读者完全掌握本章内容后,以后动手分析Android程序时,便能够信手拈来。
为了使读者对文中所讲述的内容有深刻的认识,并且在阅读时避免感到乏味,书中的内容不会涉及太多的基础理论知识,而更多的是采用动手实践的方式进行讲解,所以在阅读本书前假定读者已经掌握了Android程序开发所必备的基础知识,如果读者还不具备这些基础知识的话,请先打好基础后再阅读本书。
适合的读者
本书适合以下读者:
Android应用开发者、Android系统开发工程师、Android系统安全工作者。
本书约定
为了使书中讲述的知识更加容易理解,思路更加清晰,本书做了如下约定:
本书在讲解部分内容时,可能会对Android系统与内核的源码加以引用,如文中无具体说明系统版本,则统一为Android 4.1的系统, Linux 3.4的内核。
本书不介绍Android系统源码的下载方法,假定读者已经自行下载好了Android系统源码。
本书在引用Android系统源码时,为了避免代码占用过多篇幅及影响主体的分析思路,在不影响理解的情况下,对摘抄的内容进行了适量的删减。
本书在列举实例代码时,为了方便读者阅读与理解,对代码中的关键部分采用加粗显示。
本书中在给出命令的格式用法时,为了醒目起见,采用斜体显示。
对于部分操作容易发生错误或理解上造成歧义的地方,本书会在下面加上文本框注解。如:
注意 Smali代码的语法与格式会在本书第3章进行详细介绍。
本书源代码
下载地址:
http://www.ituring.com.cn/book/1131
点击“随书下载”即可看到本书源代码的下载链接。
本书正文中提到的“随书的附图x”也一并打包在源代码中。
致谢
首先,要感谢本书的编辑陈冰先生。在编写本书时,陈冰先生对书中每个章节的细节都严格把关,并多次耐心地教导我写作的技巧,是他对书稿质量的严格要求,以及对工作的一丝不苟,才使得本书得以顺序出版。
感谢我的父母,是他们养育了我,给了我生命,他们永远是我心中最伟大的人。
写作本身是一件很辛苦的事,尤其是每天还要被生活中的琐事困扰。在这里,我要感谢这半年多来对我无言支持的大哥与大嫂,大嫂可口的饭菜补充了我每天写作所需的营养,而大哥更是帮助我解决了很多烦心的琐事,让我在写作时无后顾之忧。
好书总能给人带来心灵上的震撼。感谢美女作家李沉嫣,是她那扣人心弦的文字感染了我,给了我创作的最初源动力。
感谢那些共享Android安全技术的组织与个人,如果没有他们前期的奉献,笔者现在可能还处在独自探索的阶段,不可能有机会与大家分享如此前沿的技术。
看雪学院是国内最具权威性的软件安全研究论坛。感谢看雪学院站长段钢先生对本书内容上的肯定与支持。
最后,感谢那些关注本书、为本书提过意见的朋友,你们的支持是我写作本书最大的动力。
作者:丰生强
2012年11月2日


编辑的话
每一本书的诞生,都有让人记住的事情。在这本书的出版中,我印象深刻的是三点:
一,作者丰生强在第一次给我交来样稿时,其粗糙不规范的写书格式和读起来不是那么顺溜的语言表达让我囧了一下,我耐心地(也或许是有些耐着性子的?)在QQ上边截图边详细地告诉了他有哪些地方的格式被他忽略了,有哪些地方的话说得不够清楚。
我说完后,他说他会认真修改好后再次给我发来。但说实话,我心里没指望他第一次就能把格式给改好,因为对于第一次写书的作者来说,这种情况几乎不曾出现过。我做了继续指导第3、4次的心理准备。让我没想到的是,几天后他第二次交来的稿件就相当靓仔,让我多少有些不相信自己的眼睛,格式规范美观,语言流畅清楚,很难相信这是同一个人仅相隔几天后的作品。他跟我说他是一个字一个字地来阅读和修改每句话的。
二,他是很少的按时且保质保量完成书稿的。对于作者,不管水平高低,大多都擅长干一件事情——拖稿,而策划编辑不得不被迫干另一件事情——催稿。但丰生强以实际行动打破了这一魔咒,他努力工作,在合同规定的期限内按时交来了全稿。作为对作者拖稿见怪不怪的一名策划编辑来说,纵然不至于说是老泪纵横吧,那也是感触良多啊。
但从另一角度说,那些能完全视合同交稿期限为无物的作者也着实让人不敢小觑,这得有多强大的心理素质才能做到这一点呢,就这么心平气和地跨过了最后期限。真心让人纠结。
三,在整个写作过程中,在谈及技术时,丰生强所表现出的那些热情、专注和乐观。我一直信奉的一点是,如果一个作者不能在他所钻研的领域体会到乐趣和幸福,那这样的作者写出来的东西是不值得一读的。好的内容就像好的食材,而那份热情和乐趣则是烹饪的手法。
现在,书已经打开,希望你会喜欢。
本书策划编辑 陈冰
2013年1月15日


序言: 推 荐 序
第一次看到生强的文章是在看雪安全论坛,他以“非虫”的笔名发表了几篇Android安全的文章。标题很低调,内容却极为丰富,逻辑清晰,实践性强,最重要的是很有“干货”。后来得知他在写书,一直保持关注,今日终于要出版了。
这本书的价值无疑是巨大的。
在此之前,即便我们把范围扩大到全球,也没有哪本书具体而系统地专门介绍Android逆向技术和安全分析技术。这可能有多方面的原因,但其中最重要的一点是竞争与利益。推动信息安全技术发展的,除了爱好者,大致可以分为三类:学术研究人员、企业研发人员、攻击者。
在Android安全方向,研究人员相对更为开放——许多团队开放了系统原型的源码,或者提供了可用的工具——但有时候他们也只发表论文以介绍系统设计和结果,却不公开可以复用的资源。近两年来,顶级会议对Android安全的研究颇为青睐,他们如此选择,可以理解。
在这个市场正高速增长的产业中,对企业而言,核心技术更是直接关系到产品的功能和性能,关系到企业竞争力和市场份额,许多企业会为了扩大技术影响而发布白皮书,但真正前沿的、独有的东西,极少会轻易公开。
攻击者则最为神秘,为了躲避风险,他们大都想尽一切办法隐藏自己的痕迹,低调以求生存。在地下产业链迅速形成后,对他们而言,安全技术更是非法获利的根本保障。
在这种情况下,刚刚进入或希望进入这一领域的人会发现,他们面临的是各种零散而不成体系的、质量参次不齐的、可能泛泛而谈的、也可能已经过时的技术资料,他们不得不去重复别人走过的路、犯别人犯过的错,将精力消耗在这些琐碎之中,而难以真正跟上技术的发展。
生强的这本书,无疑将大为改善这种局面,堪称破局之作。做到这一点颇为不易,这意味着大量的阅读、总结、尝试和创造。事实上,书中介绍的很多技术和知识,我此前从未在别的地方看到过。
另一方面,在Android这个平台,我们已经面临诸多的威胁。恶意代码数量呈指数增长,并且出现了多种对抗分析、检测、查杀的技术;应用软件和数字内容的版权不断遭到侵害,软件破解、软件篡改、广告库修改和植入、恶意代码植入、应用内付费破解等普遍存在;应用软件本身的安全漏洞频繁出现在国内外互联网企业的产品中,数据泄露和账户被盗等潜在风险让人担忧;官方系统、第三方定制系统和预装软件的漏洞不断被发现,对系统安全与稳定产生极大的威胁;移动支付从概念逐步转为实践,而对通信技术的攻击、对算法和协议的攻击时常发生;移动设备正融入办公环境,但移动平台的攻击与APT攻击结合的趋势日益明显……更糟的是,随着地下产业链的不断成熟和扩大,以及攻击技术的不断发展和改进,这些威胁和相关攻击只会来势更凶。
毫无疑问,在Android安全上我们面临极大的挑战。在这个时候,生强的这本书起到的将是雪中送炭的作用。
安全技术几乎都是双刃剑,它们既能协助我们开发更有效的保护技术,也几乎必定会被攻击者学习和参考。这里的问题是,大量安全技术的首次大范围公开,是否会带来广泛的模仿和学习,从而引发更多的攻击?在这个问题上,安全界一直存在争议。1987年出版的一本书中首次公布了感染式病毒的反汇编代码,引发大量模仿的新病毒出现。自此,这个问题成为每一本里程碑式的安全书籍都无法绕开的话题。我个人更喜欢的则是这样一个观点,在《信息安全工程》中,Ross Anderson说:“尽管一些恶意分子会从这样的书中获益,但他们大都已经知道了这些技巧,而好人们获得的收益会多得多。”
在生强写这本书的过程中,我们就不少细节有过交流和讨论。他的认真给我留下了非常深刻的印象。与其他的安全书籍相比,这本书在这样几个方面尤为突出:
实践性强。这本书的几乎每一个部分,都结合实际例子,一步步讲解如何操作。因此,它对刚入门的人或者想快速了解其中某个话题的人会有很大的帮助。事实上,缺乏可操作性,是Android安全方面现有论文、白皮书、技术文章和书籍最大的问题之一,很多人读到最后可能对内容有了一些概念,却不知道从何下手。但这本书则有很大不同。
时效性强。在交流中,我惊讶地发现,刚刚发布不久的Santoku虚拟机、APIMonitor等工具,以及Androguard的新特性等,已经出现在了这本书中。这意味着,生强在一边写作的同时,还一边关注业界的最新进展,并做了学习、尝试和总结。因此,这本书将具有几乎和论文一样的时效性。
深度和广度适当。这本书涉及的面很广,实际上,仅仅是目录本身,就是一份极好的自学参考大纲。而其中最实用的那些话题,例如常见C/C++代码结构的ARM目标程序反汇编特点,没有源码情况下对Android软件的调试技术等,都有深入的介绍。
此前,我曾写过一本叫amatutor的Android恶意代码分析教程,并通过网络分享,后来由于时间和精力暂停了更新。这段经历让我尤其深刻地体会到在这样一个新的领域写出一本好书的不易。一直有人来信希望我能继续写,但自从了解到生强的这些工作,我就松了一口气,并向他们大力推荐这本书。同时,我也向周边的同事、同行推荐,我相信这本书的内容可以证明它的价值。
肖梓航(Claud)
安天实验室高级研究员
secmobi.com创始人
看 雪 致 序
移动平台逐渐成为人们上网的主要方式。随着Android应用的普及,安全问题日益突出。出于商业利益的考虑,Android系统的所有者谷歌,一直回避公开讨论其安全性。国外用户一般是从谷歌应用商店下载应用,由于谷歌自身安全检测机制的保障,其安全性不太可能出现大的问题。但是,中国用户无法直接访问谷歌应用商店,大都是通过国内第三方Android市场下载应用,而谷歌无法控制第三方的应用商店。因此,国内的Android应用安全问题更加突出,安全威胁更高。
Lookout Mobile Security移动杀毒软件公司预测:2013年将有超过1800万台Android设备会遭遇某种形式的恶意软件的攻击。国内安全公司的数据也显示:流氓推广、恶意扣费、窃取用户数据等恶意软件增长迅速,危害日益严重。在黑色产业链中,骇客通过技术手段将非法SP提供的扣费号段植入到应用中,实现恶意吸费。手机骇客的攻击目标正在瞄准用户的手机支付与消费行为。为了更好地防范恶意软件和骇客带来的威胁,最好的办法是了解他们的攻击方法和工具,建立技术壁垒。
目前市场上研究Android安全相关问题的图书很少。因此当我拿到看雪论坛Android安全版版主“非虫”(丰生强)先生的倾力之作《Android软件安全与逆向分析》的书稿时非常高兴,并认真通读了全文。我感到这是一本深入浅出、可以快速提升开发者Android安全技术水平的好书,其在注重实际操作讲解的同时,还特别重视一些原理的讲解,如Dalvik 虚拟机与Java虚拟机的比较、APK加载机理等内容。
据我所知,丰先生以前多年从事Java相关软件的开发,并对Android系统的全部源代码进行过深入的研究和分析,他有着很强的Android应用开发能力,尤其在安全相关专业领域经验丰富。他能够在繁忙的工作之余,耗费大量的时间和精力为读者呈现这样一部技术专著,并顺利出版,不仅是读者的幸运,也是看雪论坛的骄傲。在此,我对他表示由衷地祝贺,并期盼他今后为读者带来更多的技术成果和更大的惊喜。
段钢
看雪安全网站站长
www.pediy.com
2013年1月15日于北京

媒体评论: 期待已久了,希望早日出版。
看目录内容,感觉还是不错,有干货。
感觉书的内容更偏向于Android软件安全,而非系统安全,也许叫《Android软件安全揭密》更合适些,各位怎么看?
——riusksk:
虫子的书终于出来了,速度出版。
——微笑哥:
卧槽……看了目录就饥渴难耐了……有预订么~!
——天涯一鸿:
求非虫大大的签名书。
——benniu:
擦,多会儿出啊,坐等啊。
——b23526:
看了下目录,非常感兴趣啊。
——windflyer:
潜水多年,看到这本书出来冒泡,期待尽快出版。
——hackbozy:

书摘: 第1章 Android程序分析环境搭建
在实际的Android软件开发过程中,可能很多开发人员有过这样的经历:
? 我有一个不错的idea,正在开发一款类似想法的软件,可是涉及到的一些功能上的具体代码细节却难以下手,我看到别人的程序中有这个功能,它们是如何实现的呢?
? 我不小心安装了一个流氓软件,软件运行时会自动下载木马程序、恶意扣费、篡改手机系统,它是如何做到这些的呢?
? 我按照网上介绍的方法来分析Android程序,可是根本就无法正确地反编译程序,或是反编译出的代码语法混乱,根本无法阅读。
这些场景都提出了一个疑问,那就是如何分析一个Android应用程序?如何掌握这些软件的架构思想?分析别人的程序在很多人看来是不能够接受的行为,在他们眼中这种行为都应被视为盗窃。其实任何技术的起源本身就是从学习开始的,用正确的态度对待程序分析技术是可以的。
如果说,开发Android程序是一种学问,那么分析Android程序更像是一门艺术。在浩瀚如海的反汇编代码中分析出程序的执行流程与架构思想是一件很了不起的事情,这需要分析人员有着扎实的编程基础与深厚的思维分析能力。分析软件的过程犹如一次艰难的旅程,这条旅程会有多长?该怎么走?会有多少崎岖险路?没有人知道,但是先行者已经为我们铺下了台阶,我们只需沿着它慢慢前行。
1.1 Windows分析环境搭建
搭建Windows分析平台的系统版本要求不高,Windows XP或以上即可。本书的Windows平台的分析环境采用Windows XP 32位系统,如果读者使用Windows 7或其他版本,操作上是大同小异的。
1.1.1 安装JDK
JDK是Android开发必须的运行环境,在安装JDK之前,首先到Oracle公司官网上下载它。下载地址为:http://www.oracle.com/technetwork/java/javase/downloads/index.html,打开下载页面,目前最新版本为Java SE 6 Update 33,如图1-1所示。

图1-1 下载JDK
点击JDK下面的DOWNLOAD按钮进入下载页面,勾选“Accept License Agreement”单选框,然后点击jdk-6u33-windows-i586.exe进行下载。下载完成后双击安装文件,启动JDK安装界面,如图1-2所示。

图1-2 JDK安装界面
与安装其他Windows软件一样,JDK的安装过程也很简单,只需要不停点击下一步就可以顺利安装完成。安装完成后手动添加JAVA_HOME环境变量,值为“C:\Program Files\Java\jdk1.6.0_33”,并将“C:\Program Files\Java\jdk1.6.0_33\bin”添加到PATH变量中。如图1-3所示。

图1-3 设置Java环境变量
完成所有步骤后检查一下Java是否安装成功。单击“开始”按钮,选择“运行”,在出现的对话框中输入CMD命令打开CMD窗口,在CMD窗口中输入java –version,如果屏幕上出现如图1-4所示的提示,说明安装成功。

图1-4 查看Java是否正确安装
1.1.2 安装Android SDK
Android SDK是以zip压缩包的形式提供给开发人员的。首先到Android官网下载最新版本的SDK,下载地址为:http://developer.android.com/sdk/index.html。SDK提供了压缩包与安装文件两种方式供开发者下载,为了方便部署,本书采用下载安装文件的方式直接安装,目前Android SDK的最新版本为r20,完整下载地址为:http://dl.google.com/androidinstaller_r20- windows.exe。
双击下载后的安装文件,将Android SDK安装到任意位置,本书安装环境为D:\android-sdk目录,然后将“D:\android-sdk\tools”与“D:\android-sdk\platform-tools”目录添加到系统的PATH环境变量中。添加完成后打开一个CMD窗口,输入“emulator -version”与“adb version”命令查看是否能成功运行。执行结果如图1-5所示。

图1-5 检查Android SDK是否正确安装
Android SDK安装成功后,需要通过SDK管理器下载具体版本的SDK,双击“D:\android-sdk\SDK Manager.exe”文件,打开Android SDK Manager,运行后如图1-6所示。
读者可以根据自己的需要选择相应的一个或多个版本进行下载,本书选择了2.2、2.3.3、4.0、4.0.3、4.1等几个版本,点击Install package按钮打开“Choose Package to Install”对话框,选择“Accept All”单选框,最后点击“Install”按钮开始下载,下载所需的时间根据网络环境差异可能会有所不同。

图1-6 Android SDK Manager运行界面
1.1.3 安装Android NDK
Android NDK是Google提供的开发Android原生程序的工具包。如今越来越多的软件与病毒采用了基于Android NDK动态库的调用技术,隐藏了程序在实现上的很多细节,掌握Android NDK程序的分析技术也成为了分析人员必备的技能,本书将会在第7章对Android NDK程序的特点以及分析技术进行详细的讲解。
Android NDK的下载地址为:http://developer.android.com/sdk/ndk/index.html,目前最新版本为R8,Windows平台下的完整下载链接为:http://dl.google.com/android/ndk/android-ndk- r8-windows.zip。将下载后的压缩包解压到硬盘任意位置,本书为D盘根目录。新建环境变量ANDROID_NDK,值为D:\android-ndk-r8,然后将ANDROID_NDK添加到PATH环境变量中,做好这一步,Android NDK就算安装完成了。
接下来测试配置是否正确,打开一个CMD窗口,进入目录“D:\android-ndk-r8\samples\ hello-jni”,输入“ndk-build”命令编译Android NDK中自带的hello-jni工程,如果输出如图1-7所示的结果,就说明Android NDK安装成功了。

图1-7 使用Android NDK编译hello-jni工程
1.1.4 Eclipse集成开发环境
Eclipse是Android开发推荐使用的IDE。它的下载地址为:http://www.eclipse. org/downloads,选择下载“Eclipse IDE for Java Developers”或“Eclipse for Mobile Developers”版本即可。强烈建议下载使用后者,后者自带了CDT(C/C++Development Tools)插件,并针对手机开发做了优化。
Eclipse是一款绿色软件,下载完成后解压到硬盘任意目录,本书为D盘根目录。进入“D:\eclipse”目录,运行eclipse.exe,Eclipse会根据前面设置的环境变量自动进行初始化,如果启动时没有提示错误说明安装成功。
1.1.5 安装CDT、ADT插件
如果读者使用的Eclipse是For Mobile Developers版本或自带CDT插件,可以跳过CDT插件的安装;否则需要手动安装CDT插件。安装Eclipse的插件比较简单,有在线安装与离线安装两种方式,步骤分别为:
? 启动Eclipse,点击菜单“Help→Install New Software”打开Install对话框,在“Work With”旁边的编辑框中输入http://download.eclipse.org/tools/cdt/releases/juno并回车,稍等片刻后下面列表框就会解析出CDT插件。
? 到Eclipse官网上手动下载最新版的CDT插件,目前最新8.1.0。下载地址为:http://www. eclipse.org/cdt/downloads.php。启动Eclipse,点击菜单“Help→Install New Software”打开Install对话框,点击界面上的Add按钮,打开Add Repository对话框,接着点击Archive按钮,选择下载的CDT压缩包,点击OK按钮返回。
无论采用上面哪一种方式进行安装,最终都会在Name下面的列表中列出可供安装的CDT插件,如图1-8所示, 全部勾选后点击Next按钮即可安装,在线安装耗费的时间根据网络环境差异可能有所不同。

图1-8 安装CDT插件
ADT插件是Google为Android开发提供的Eclipse插件,方便在Eclipse开发环境中创建、编辑、调试Android程序。安装过程与CDT插件类似。目前最新版本为20.0.0,官方下载地址为:http://dl.google.com/android/ADT-20.0.0.zip,在线安装的repository地址为:https://dl- ssl.google.com/android/eclipse/,读者可以按照上面的步骤自行完成安装。
ADT插件安装完成后需要进行相应的配置。点击Eclipse菜单项“Window-Preferences”,选择Android列表项,在右侧SDK Location处选择Android SDK的安装位置,如D:\android-sdk,展开Android列表项,选择NDK,在右侧NDK Location处选择Android NDK的安装位置,如D:\android-ndk-r8。设置完后点击OK按钮关闭对话框。到此,CDT与ADT插件就安装完成了。
1.1.6 创建Android Virtual Device
Android SDK中提供了“Android Virtual Device Manager”工具,方便在没有真实Android设备环境的情况下调试运行Android程序。
双击运行“D:\android-sdk-windows\ AVD Manager.exe”,点击“New”按钮,打开AVD创建对话框,在“Name”栏输入AVD的名称,如输入“Android2.3.3”,在Target一栏选择要模拟的Android版本,这里选择“Android 2.3.3 – API Level 10”,SD Card大小指定为256MB,其它选项保持不变,结果如图1-9所示。

图1-9 创建AVD
点击“Create AVD”按钮完成AVD的创建。选中创建的AVD,点击右侧的“Start”按钮,如果没有错误会成功启动这个Android虚拟设备。
如果使用真实Android设备来调试程序,需要先在设备的“设置→程序→开发”选项中开启“USB调试”,然后安装相应设备厂商提供的USB驱动程序。一份常见的USB驱动程序下载地址列表可以在http://developer.android.com/tools/extras/oem-usb.html中找到。安装完驱动后在命令提示符下输入“adb devices”就可以列出连接的Android设备了。
1.1.7 使用到的工具
分析Android程序需要用到很多工具,包括:反编译工具、静态分析工具、动态调试工具、集成分析环境等。所有的工具中,大多数是开源或免费的软件,笔者在此不详细列出使用到的工具,在每一章对知识点进行介绍时,会同时介绍相关工具的使用方法与下载地址。
1.2 Linux分析环境搭建
本书中介绍的Windows环境下的大多数操作,在Linux环境下同样适用。本节将介绍如何在Linux环境下搭建Android程序的分析环境。
1.2.1 本书的Linux环境
本书在写作时使用的Linux环境为Ubuntu 10.04 32位系统,在最后一章进行Android病毒分析时使用的是Ubuntu 12.04 32位系统。
1.2.2 安装JDK
首先在当前用户主目录下新建tools目录来存放Android分析常用的工具。
到Oracle官方网站下载JDK安装包。本书Ubuntu平台使用的版本为jdk-6u33-linux-i586,下载地址为http://www.oracle.com/technetwork/java/javase/downloads/index.html,将下载的jdk-6u33-linux-i586.bin文件放到/home/feicong/tools目录(feicong为本机用户名),打开一个终端环境输入以下命令:
cd tools
chmod +x ./jdk-6u33-linux-i586.bin
./jdk-6u33-linux-i586.bin
此时安装程序会自动将JDK安装到当前目录的jdk1.6.0_33目录下。接着设置环境变量,执行:
sudo gedit /etc/profile
在配置文件中加入如下部分:
export JAVA_HOME=/home/feicong/jdk1.6.0_33
export JRE_HOME=/home/feicong/jdk1.6.0_33/jre
export PATH=/home/feicong/jdk1.6.0_33/bin: