首页
社区
课程
招聘
[翻译]Android安全分析挑战:运行时篡改Dalvik字节码
发表于: 2013-4-24 21:49 27839

[翻译]Android安全分析挑战:运行时篡改Dalvik字节码

2013-4-24 21:49
27839
本文章由Jack_Jia编写,转载请注明出处。  
文章链接:http://blog.csdn.net/jiazhijun/article/details/8833710
作者:Jack_Jia    邮箱: 309zhijun@163.com

     移动互联网已经是一种趋势,仅2012年就有45亿应用程序下载量。伴随着移动互联网的火爆,众多攻击者也被吸引到这个平台,移动平台恶意软件呈现爆炸式增长态势。与PC平台不同的是,PC平台有大量的反病毒包和恶意软件分析工具,而新兴的移动互联网却缺乏强大的分析工具和技术。这些工具和技术将是保持移动互联网远离恶意软件和恶意应用程序的关键。它们一般来自于学术界和安全界的研究人员,但是它们都有一定的缺陷,并不适合所有的情况,加入安全社区可以帮助我们学习和发展android应用的分析方法。

一、介绍

      首先介绍一下移动应用程序的分析方法和背景。我们可以采用很多工具来对应用程序进行分析,Android应用程序的分析一般都是基于APK文件,APK文件代表了一个应用程序。
     它存储了以下内容:

           1、程序逻辑:dex字节码和so本地库。
           2、元数据信息:AndroidManifest.xml文件。
           3、资源文件:图像或其他类型数据。

     分析工具一般采用以下两种应用分析方法:

          1、静态分析:该方式收集有关应用程序的信息,但程序代码不执行。
          2、动态分析:该方式执行应用程序,同时收集应用运行行为。

     这两种分析技术都各有利弊,在Android逆向分析领域,许多工具都是基于静态分析技术,也有用于动态分析的沙箱系统,但受限于动态分析系统的交互灵活性,分析师往往在那些部分需要动态分析上没有足够的控制力。在逆向工程过程中,分析人员一旦确定了感兴趣的应用程序部分,它们更侧重于使用静态分析工具。问题是如何找到那些部分呢?静态分析技术的另一个主要缺点是不知道什么被真正执行和程序上下文在某特定点的执行是否有效。当我们假定应用程序代码在运行过程中不会改变时,分析工作将是十分容易的,我们可以通过分析apk文件来识别程序代码逻辑,混淆的应用程序会给分析人员带来一定的挑战。随着运行时篡改Dalvik字节码的讲解,我们将暴露这些基于代码流分析的工具的限制和问题。

     我们将在接下来的部分描述一下应用程序的基本组成部分,并指出重要的运行时组件。这将使我们更容易明白当运行crackme时发生了什么事情。之后,我们将讲述用于欺骗静态分析工具所采用的主要技术。最后我们会进入crackme挑战的细节。

二、应用程序执行的上下文

      应用程序的生命周期开始于zygote进程的fork方法,因为它已经预先加载了Android框架,所以应用程序不必再花时间加载这些基础类,同时这也可以有效降低整体的内存开销。在新的进程降低权限之后,它加载了apk文件中的classes.dex文件,该文件包含了可被Dalvik虚拟机(DVM)解释执行的Dalvik字节码,代表了应用程序逻辑。此外,应用程序还带有可以在运行时动态加载的Native库。因为Dalvik虚拟机和Native库运行在同一进程中,因此它们具有相同的权限。一个典型的(缩短的)应用程序的内存布局如图1所示。


图1典型的APP内存布局

       我们可以看到,Android框架和共享库及dex文件一样被映射到我们的进程。我们的dex文件字节码被映射为只读。

三、篡改技术

       回到静态分析工具的话题,如果Dalvik字节码在运行时不能改变的话,静态分析工具将能很好的工作。因为我们可以直接从APK文件中提取的出和运行时相匹配的字节码。你可能会说这种假设是成立的,因为dex文件映射为只读,所以Dalvik指令集是不能够修改的字节码本身的。有限的Dalvik指令集使我们不能够篡改程序字节码,但我们可以利用捆绑在APK文件中的本地库。本地代码和DVM运行在相同的较低水平,如图2:



图2 本地代码和DVM在同一级别的操作

      本地代码是能够任意操作自己进程上下文内存的,因此我们可以通过本地代码覆盖已加载Dalvik字节码。但是classes.dex被映射为只读。这意味着,如果我们修改该段内存,内核将会杀掉我们的进程,因此在实际篡改我们的应用程序的字节码之前,我们必须重新映射该段内存为可写。之后,我们就可以写我们的新字节码到我们的应用程序。如果程序调用我们篡改过的方法,那么将执行新的字节码。没有进一步修改应用程序或DVM的必要。通过这种方法,我们发现“字节码在运行时不能修改”的假设也不是绝对的。只关注classes.dex文件的静态分析工具没有考虑到这种情况,这样的工具就必须改进以应对这种情况。可以使用静态和动态分析的组合来克服这种限制,但这样的复杂的分析系统是不常见的。

三、示例-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的字节码。

英文源址:http://blog.bluebox.com/2013/03/25/android-security-analysis-challenge-tampering-dalvik-bytecode-during-runtime/

[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法

收藏
免费 6
支持
分享
最新回复 (33)
雪    币: 219
活跃值: (738)
能力值: (RANK:290 )
在线值:
发帖
回帖
粉丝
2
广告位置出租
2013-4-25 07:13
0
雪    币: 204
活跃值: (1678)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
顶,感谢楼主的好文章
2013-4-25 08:24
0
雪    币: 27
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
前排卖瓜子 边看边卖
2013-4-25 08:32
0
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
下来玩玩~谢

~~~玩过lvl或数字那种内部自校验的...这货竟然是zip加密包啊。。。?鄙陋了。。。第一次见,好强悍~研究。。。
2013-4-25 08:57
0
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
求教静态编译方法...这种加密打包如何实现的?这要是普及了那还得了。。。
2013-4-25 09:24
0
雪    币: 90
活跃值: (126)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
7
很不错的资料
2013-4-25 10:07
0
雪    币: 49
活跃值: (40)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
不是静态编译,而是运行时修改程序的逻辑
2013-4-25 10:07
0
雪    币: 761
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
看雪有你更精彩~
本文深刻地阐述了在当前手机安全形势严峻的情况下,又爆发出的针对安卓平台的新技术,将篡改Dalvik字节码这一新技术剖析得体无完肤,这是革命性的突破。
另外,本文的翻译也是一个亮点,不仅言简意赅,主旨明确,更重要的是,能够分享这些宝贵的技术资料是如此的需要勇气和毅力,让我们为这些最可爱的人们鼓掌!
啪啪啪啪。
PS:真心受教了。
2013-4-25 10:11
0
雪    币: 107
活跃值: (326)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
呵呵..谢谢分享............
2013-4-25 11:23
0
雪    币: 192
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
拿回去慢慢看。
2013-4-25 11:33
0
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
谢谢大牛,我上面就是想问静态编译的可行性及这种加密apk的方法及对策...
2013-4-25 12:45
0
雪    币: 93944
活跃值: (200219)
能力值: (RANK:10 )
在线值:
发帖
回帖
粉丝
13
Thanks for share.
2013-4-25 15:24
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
14
mprotect是需要root的。
2013-4-25 16:07
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
你妹,神奇啊,搞一搞,神清气爽!
2013-4-25 18:14
0
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
老大,请教此样本如何实现的加密打包?
2013-4-25 19:54
0
雪    币: 10
活跃值: (10)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
17
楼上的你可以看看英文版文章里面,Further Issues: APK Packaging 节里面提到,大致原因是:除了在动态修改方面的诡计,还使用zip文件方面的小技巧
这个APK文件其实没加密,只是修改了zip头文件的加密标志,正常的zip软件检测这个标志便认为该软件被加密了,就会提示输入密码,然后实际上他并没有加密,那么你也不能真正输入一个正确的密码,然而,android系统使用的unzip功能是不略过zip 头文件的,它不检测‘isEncrypted’ flag 的,所以直接把它当成正常的zip文件处理了。
2013-4-26 15:49
0
雪    币: 298
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
18
非常感谢,昨晚看到了。可以没看到文件头构造的图片。
wordpress图床在我这开不了。所以之前没注意还有一段~
2013-4-26 16:14
0
雪    币: 435
活跃值: (172)
能力值: ( LV13,RANK:280 )
在线值:
发帖
回帖
粉丝
19
mark下,,,
2013-4-27 15:00
0
雪    币: 1585
活跃值: (182)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
mark,稍后回来心~
2013-4-28 08:48
0
雪    币: 34
活跃值: (10)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
21
好文章,。。。收藏
2013-4-28 13:21
0
雪    币: 61
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
22
求教 怎样获取 映射到dex的指针
2013-4-28 14:13
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
23
标记标记,继续研究
2013-4-28 15:05
0
雪    币: 347
活跃值: (25)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
24
感谢分享~收藏
2013-4-29 20:40
0
雪    币: 1552
活跃值: (1566)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
25
慢慢学习...
2013-7-27 00:46
0
游客
登录 | 注册 方可回帖
返回
//