移动互联网已是一种趋势,仅2012年就有450亿应用程序下载量。伴随着移动互联网的火爆,众多攻击者也被吸引到这个平台,移动平台恶意软件呈现爆炸式增加态势。与PC平台不一样的是,PC平台有大量的反病毒包和恶意软件分析工具,而新兴的移动互联网却缺少强大的分析工具和技术。这些工具和技术将是保持移动互联网远离恶意软件和恶意应用程序的关键。它们通常来自于学术界和安全界的研究人员,可是它们都有必定的缺陷,并不适合全部的状况,加入安全社区能够帮助咱们学习和发展android应用的分析方法。
1、介绍
首先介绍一下移动应用程序的分析方法和背景。咱们能够采用不少工具来对应用程序进行分析,Android应用程序的分析通常都是基于APK文件,APK文件表明了一个应用程序。
它存储了如下内容:java
一、程序逻辑:dex字节码和so本地库。 二、元数据信息:AndroidManifest.xml文件。 三、资源文件:图像或其余类型数据。 分析工具通常采用如下两种应用分析方法: 一、静态分析:该方式收集有关应用程序的信息,但程序代码不执行。 二、动态分析:该方式执行应用程序,同时收集应用运行行为。 这两种分析技术都各有利弊,在Android逆向分析领域,许多工具都是基于静态分析技术,也有用于动态分析的沙箱系统,但受限于动态分析系统的交互灵活性,分析师每每在那些部分须要动态分析上没有足够的控制力。在逆向工程过程当中,分析人员一旦肯定了感兴趣的应用程序部分,它们更侧重于使用静态分析工具。问题是如何找到那些部分呢?静态分析技术的另外一个主要缺点是不知道什么被真正执行和程序上下文在某特定点的执行是否有效。当咱们假定应用程序代码在运行过程当中不会改变时,分析工做将是十分容易的,咱们能够经过分析apk文件来识别程序代码逻辑,混淆的应用程序会给分析人员带来必定的挑战。随着运行时篡改Dalvik字节码的讲解,咱们将暴露这些基于代码流分析的工具的限制和问题。 咱们将在接下来的部分描述一下应用程序的基本组成部分,并指出重要的运行时组件。这将使咱们更容易明白当运行crackme时发生了什么事情。以后,咱们将讲述用于欺骗静态分析工具所采用的主要技术。最后咱们会进入crackme挑战的细节。
2、应用程序执行的上下文android
应用程序的生命周期开始于zygote进程的fork方法,由于它已经预先加载了Android框架,因此应用程序没必要再花时间加载这些基础类,同时这也能够有效下降总体的内存开销。在新的进程下降权限以后,它加载了apk文件中的classes.dex文件,该文件包含了可被Dalvik虚拟机(DVM)解释执行的Dalvik字节码,表明了应用程序逻辑。此外,应用程序还带有能够在运行时动态加载的Native库。由于Dalvik虚拟机和Native库运行在同一进程中,所以它们具备相同的权限。一个典型的(缩短的)应用程序的内存布局如图1所示。
图1典型的APP内存布局git
咱们能够看到,Android框架和共享库及dex文件同样被映射到咱们的进程。咱们的dex文件字节码被映射为只读。
3、篡改技术github
回到静态分析工具的话题,若是Dalvik字节码在运行时不能改变的话,静态分析工具将能很好的工做。由于咱们能够直接从APK文件中提取的出和运行时相匹配的字节码。你可能会说这种假设是成立的,由于dex文件映射为只读,因此Dalvik指令集是不可以修改的字节码自己的。有限的Dalvik指令集使咱们不可以篡改程序字节码,但咱们能够利用捆绑在APK文件中的本地库。本地代码和DVM运行在相同的较低水平,如图2:
图2 本地代码和DVM在同一级别的操做segmentfault
本地代码是可以任意操做本身进程上下文内存的,所以咱们能够经过本地代码覆盖已加载Dalvik字节码。可是classes.dex被映射为只读。这意味着,若是咱们修改该段内存,内核将会杀掉咱们的进程,所以在实际篡改咱们的应用程序的字节码以前,咱们必须从新映射该段内存为可写。以后,咱们就能够写咱们的新字节码到咱们的应用程序。若是程序调用咱们篡改过的方法,那么将执行新的字节码。没有进一步修改应用程序或DVM的必要。经过这种方法,咱们发现“字节码在运行时不能修改”的假设也不是绝对的。只关注classes.dex文件的静态分析工具没有考虑到这种状况,这样的工具就必须改进以应对这种状况。可使用静态和动态分析的组合来克服这种限制,但这样的复杂的分析系统是不常见的。
3、示例-Crackme安全
为了说明咱们前面所讨论的一些问题,咱们决定建立一个案例研究“challenge”的应用程序“crackme”,它使用恶意软件使用的混淆技术进行了处理。您可使用任何分析技术和工具,并弄清楚它是如何工做的。找到正确的密码,输入到上面的文本框中。点击按钮,查看是否获得了正确的答案。这将显示按钮下面的文字。 您能够在这里下载crackme的apk文件的副本:https://github.com/blueboxsecurity/DalvikBytecodeTampering/raw/master/delta.apk
中止阅读,若是你打算接受挑战。下面是挑战的答案 -----框架
首先咱们开始分析Action类,这是咱们的应用程序的Activity的入口,按钮会触发verify()方法。在这里,咱们第一次获取TextField中的输入的文本,并把它转换成一个String。这个String对象并非java.lang.String类的一个实例而是咱们本身的实现。在构造函数中,咱们使用第二种方法改变字符串。结果将被储存在私有的区域,和Action类的硬编码在一块。若是密码相同,将被用于显示在屏幕上的消息的加密。 可是String类内所使用的改变文本方法的方法,或者更准确地说,这种方法的字节码,将永远不会被执行。当应用程序启动后,在Action的静态类的构造函数中,这个方法的字节码已经被替换掉了。在这里,咱们加载本地库'libnet.so'和执行READMEM()函数。在这个库中,咱们获取一个指针从堆栈到咱们的映射的dex文件,并尝试找到文件的开头。这能够很容易地经过正向搜索内存页,直到咱们发现dex文件的magic byte。如今咱们能够从dex文件的开头解析头文件。当咱们解析dex文件时,咱们能够找到的咱们要篡改方法的地址。但正如前面提到的,咱们首先要从新映射内存为可写。这可使用mprotect()函数实现。以后,咱们就能够覆盖原来的字节码,并经过从本机代码到类的初始化的返回来完成。类初始化已经结束,Activity在Android设备上弹出。如今,当咱们按下按钮时,咱们执行的是新的字节码,而不是原来dex的字节码。
在此向你介绍一款:自动化App安全检测平台(http://safe.ijiami.cn),一键上传,方便快捷,能够帮助开发者找出本身APP所存在的漏洞和薄弱环节,帮助能够帮助本身进行APP加壳加密保护。函数
更多内容,期待您的探索,请关注爱加密,让您精彩不断!工具
爱加密官方地址:http://www.ijiami.cn/布局