首页(yè)> 技(jì )术观点 > 安(ān)卓APP安(ān)全保卫发展历程史

安(ān)卓APP安(ān)全保卫发展历程史

发布时间:2015-11-11

很(hěn)多(duō)智能(néng)手机用(yòng)户可(kě)能(néng)并没有(yǒu)意识到,自己下载在手机中(zhōng)的APP,可(kě)能(néng)是山(shān)寨APP或被破解的官方APP。以游戏“植物(wù)大战僵尸”為(wèi)例,只要在安(ān)卓市场搜索“植物(wù)大战”关键词,会出现 “植物(wù)大战小(xiǎo)鸟”、“植物(wù)大战小(xiǎo)怪兽”、“植物(wù)大战害虫”等一系列相关APP。这些APP背后的开发者之间可(kě)能(néng)没有(yǒu)关系,更与官方APP的软件原始创作(zuò)者毫无渊源。

很(hěn)明显,Android平台已经成為(wèi)恶意程序和破解者攻击的众矢之的,于是越来越多(duō)的Android开发者开始意识到应用(yòng)安(ān)全的重要性。于是,一场APP反编译和防止APP反编译上演了一场惨烈无比的世纪大战,安(ān)卓加固也从最初最简单的单一的代码混淆发展成今天越来越成熟的一个體(tǐ)系。下面,就让我為(wèi)大家介绍一下“防止APP反编译”这位斗士成長(cháng)的历程。

原始社会时期——代码混淆 
    最早的应用(yòng)保护当属代码混淆,谷歌官方发布的sdk中(zhōng)就包含ProGuard这种混淆工(gōng)具(jù)。混淆工(gōng)具(jù)会把你用(yòng)java语言编写的代码的类名(míng)、变量名(míng)混淆為(wèi)自己定义的格式,这样可(kě)以增加破解者在破解时阅读难度。 
  图1是用(yòng)ProGuard混淆过的dex文(wén)件截图,从图中(zhōng)可(kě)以看到,左侧的类名(míng)大多(duō)都变成了a、b等这样自定义字母的形式。在未混淆前,破解者可(kě)以根据一个类名(míng)叫做HttpGet的文(wén)件,大致猜测出它是做http get相关的。而混淆后,变成了a等自定义类名(míng),破解者无法猜测它的含义,增加了阅读难度。

但代码混淆只是简单的改变类名(míng)或者变量的名(míng),只要能(néng)找dex,反编译為(wèi)smali或者java,花(huā)些时间还是可(kě)以轻松破解的。如果说不用(yòng)混淆工(gōng)具(jù)我们破解一个apk需要2两天,那么用(yòng)了这个工(gōng)具(jù),破解者可(kě)能(néng)需要4天,只是时间成本增加了。 
    奴隶社会时期——自我校验 
    经过漫長(cháng)的混淆时期,开发者发现他(tā)们的应用(yòng)还是照常被破解。于是新(xīn)的保护方式又(yòu)出现了——自我校验。 
  简单说,自我校验就是在程序中(zhōng)加一些对自己应用(yòng)的完整性校验,可(kě)以借助签名(míng)、或计算自己应用(yòng)dex的md5值等等来完成。有(yǒu)些开发者直接把校验功能(néng)加入到dex中(zhōng),有(yǒu)些则是通过http协议请求相关服務(wù)来得到校验。有(yǒu)了这种校验,应用(yòng)在被二次打包的时候会无法运行。 
  那这种方法的弊端是什么?举一个有(yǒu)意思的例子。在悬崖的拐弯处都会有(yǒu)一个路标,用(yòng)来正确指示方向。但如果有(yǒu)人故意搞破坏,把路标指示方向弄反,那开車(chē)的人被误导后,顺着错误的方向行驶,就会发生不幸的悲剧。 
  这个例子的意思是,计算机在执行指令的时候也是按照预先定义好的逻辑(开发者写的)去执行,然而如果破解者对开发者校验的地方近进行了修改,那么计算机也会按照新(xīn)的逻辑执行,这种保护措施风险很(hěn)大,所以也就逐渐没落了。 
    封建社会时期——dex文(wén)件变形 
   经历了两个时代,开发者也逐渐提高了保护技(jì )能(néng)。于是很(hěn)多(duō)做java出身的开发者,在经过无数日夜的努力下摇身一变成為(wèi)了c、c++专家。越来越多(duō)的逻辑被写入到c层,并且所有(yǒu)的校验也被移到c层,混淆也同样存在。同时,开发者开始对dex文(wén)件AndroidManifest文(wén)件做变形处理(lǐ),这样做的好处是既能(néng)保证应用(yòng)能(néng)正常运行,也能(néng)使一些反编译工(gōng)具(jù)如apktool在反编译时奔溃。由下图可(kě)见, apktool在反编译时完全失去了作(zuò)用(yòng)。

但对dex文(wén)件和manifest文(wén)件的变形同样有(yǒu)它的弱点。基本世面上的dex变形都可(kě)以通过baksmali来得到smali,这样破解者就可(kě)继续分(fēn)析。而manifset文(wén)件格式官方有(yǒu)明确的规范,破解者按照规范去解析,遇到不正确字节可(kě)以推敲,最终还是可(kě)以将其还原。 
   资本主义社会时期——混合加密 
  这是一个移动互联网高速发展的时期,但盗版和二次打包等问题也日益凸显,在这个开放的时期,為(wèi)了满足开发者保护应用(yòng)的迫切需要,相继出现了一些基于Android APP加固的第三方产(chǎn)品如梆梆、爱加密、360,通常他(tā)们的基本做法有(yǒu): 
1.Dex保护 
(1)隐藏dex文(wén)件 
  既然dex文(wén)件中(zhōng)包含了核心逻辑,那么把dex隐藏,再通过另外的方式加载起来,是不是就能(néng)达到保护dex的目的了呢(ne)?于是这成為(wèi)一些第三方加固产(chǎn)品保护应用(yòng)的方式。 
  他(tā)们通过加密甚至压缩(早期是不存在压缩的,只是单纯的加密)方式把dex转换為(wèi)另外一个文(wén)件。而被加固后的apk里面的dex则是那些第三方加固产(chǎn)品用(yòng)来启动和加载隐藏dex的入口,也就是壳。 
  (2)对dex文(wén)件进行变形 
  这里所说的变形,不同于封建社会时期提到的变形。这种办(bàn)法不隐藏dex,而是让dex保留在外面,但是当破解者去分(fēn)析这个dex的时候,会发现dex里面的内容是不完整的。 
  (3)对dex结构进行变形 
  此类方法是比较复杂的,了解dex结构的人应该很(hěn)清楚,dex结构中(zhōng)包含DexClassDef、ClassDataItem、DexCode,这些是dalvik虚拟机运行一个dex必不可(kě)少的部分(fēn),特别是DexCode,DexCode包含了虚拟机运行的字节码指令。 
  部分(fēn)第三方加固产(chǎn)品开始尝试这种方式,他(tā)们的保护方案中(zhōng)可(kě)能(néng)抽取了DexCode中(zhōng)的部分(fēn),然后对字节码指令添加nop,或者连ClassDataItem和DexCode一同抽取,或者对上面提到的三个部分(fēn)都做处理(lǐ)。抽取完之后,还要做修正、修复等工(gōng)作(zuò),总之很(hěn)烦锁。因為(wèi)dex运行时有(yǒu)很(hěn)多(duō)关于dex的校验,即使校验通过还有(yǒu)一些偏移问题。 
  Dex都被抽取修改后為(wèi)什么还能(néng)运行呢(ne)?那是因為(wèi)在运行之前或者运行之中(zhōng)对这个内存中(zhōng)的dex做修正。修正工(gōng)作(zuò)也很(hěn)复杂,一般选择在运行之前做修正,这样可(kě)以减少很(hěn)大的工(gōng)作(zuò)量,甚至可(kě)能(néng)还需要借助hook来帮忙。 
2.So保护 
(1) 修改Elf头、节表 
  我们知道so其实是一个ELF文(wén)件,ELF文(wén)件有(yǒu)着自己的格式。有(yǒu)些第三方加固保护是对so文(wén)件进行保护,他(tā)们的做法是稍微修改一下ELF头或者节表信息,因為(wèi)这并不会影响程序的正常运行。 
  图3和图4是对ELF文(wén)件头中(zhōng)的节头表信息做了修改后,再用(yòng)010 Editor打开,显示的异常界面:


接着我们用(yòng)ida打开该ELF文(wén)件,发现该文(wén)件根本无法打开(一直卡在那里)                            
  其次,还有(yǒu)修改程序头表这种保护方式,如图5所示,对PT_NOTE段做了一些修改。在该段的属性值中(zhōng)填充了一些无效的数字,导致逆向工(gōng)具(jù)无法正常解析。由于系统并不会对PT_NOTE段进行分(fēn)析,防御逆向工(gōng)具(jù)的同时保证了该文(wén)件能(néng)被系统正常加载。


(2)选择开源加壳工(gōng)具(jù) 
  最常用(yòng)的当属UPX壳,因為(wèi)它支持arm架构的ELF加固。在加壳之后再对原文(wén)件做一些处理(lǐ),这样对破解者的分(fēn)析工(gōng)作(zuò)又(yòu)增加了一些难度。 
  (3)进程防调试、或增加调试难度 
  有(yǒu)时候静态分(fēn)析是非常局限的,这个时候动态分(fēn)析的好处就體(tǐ)现出来了,然而动态分(fēn)析的核心就是调试,而调试一个进程首先要ptrace这个进程,如果能(néng)有(yǒu)效的防止进程被ptrace,就能(néng)有(yǒu)效的防止动态调试。当然还有(yǒu)其他(tā)反调试技(jì )术,或者增加调试难度等等。 
    社会主义时期 
   这个时期,技(jì )术的发展与普及让人人都是开发者成為(wèi)可(kě)能(néng)。而破解者的破解技(jì )术和手段也在随之变化。单一的应用(yòng)保护措施已经无法有(yǒu)效的应对破解者的攻击,所以还需要从多(duō)重维度和深度对应用(yòng)进行加固保护。 
  在上面的资本主义时期提到的几种保护措施中(zhōng),遗留了很(hěn)多(duō)问题,比如: 
  (1)隐藏dex遗留的问题 
  首先dex是被完整隐藏起来的,一旦破解者得到了dex,就等于破解完成了一半。如果破解了加壳原理(lǐ),就可(kě)以轻易做出脱壳机。 
  另外就是实现自定义rom,这种方式可(kě)谓最為(wèi)简单,只需要在相关的点加一些代码,然后编译一个自己的rom,这样在虚拟机中(zhōng)就可(kě)以顺利的脱壳了。 
  还有(yǒu)就是利用(yòng)Inject原理(lǐ)将目标进程注入,代码进行hook系统函数来达到脱壳的目的。 
  (2)Dex结构变形带来的弊端 
  随着安(ān)卓5.0的发布,Art步入我们的视野。Art可(kě)以直接将dex编译為(wèi)本地指令运行。 
可(kě)是它编译时需要完整的dex,这怎么办(bàn)?或许有(yǒu)些第三方加固产(chǎn)品选择了根本不编译,当然开发者和用(yòng)户不知道,因為(wèi)它表现出来的是程序可(kě)以正确运行,但是系统在Art模式下运行的更快这种优势就永遠(yuǎn)得不到體(tǐ)现了。 
  所以Dex结构变形遗留的问题很(hěn)明显,即兼容性和Art模式下的编译问题。 
  (3)ELF简单修改遗留问题 
对应修改ELF头和节头表信息的技(jì )巧很(hěn)容易被识破和修复,所以只能(néng)防住初级破解者。 
  (4)UPX方面的劣势 
  虽然upx是最為(wèi)so加壳的首选,但是upx代码逻辑复杂,很(hěn)难达到定制,特别是让它同时支持多(duō)种架构。 
  基于上述原因一些第三方加固产(chǎn)品只是简单的利用(yòng)upx加壳,并修改一些数据。不过很(hěn)容易被有(yǒu)upx经验的人识破并脱壳。 
  安(ān)全防护当然不是绝对的,但既然能(néng)发现这些遗留问题和弊端,就一定能(néng)找到相应的解决方案。据爱加密技(jì )术工(gōng)程师介绍,一款能(néng)防得住破解者攻击、兼容性好、能(néng)體(tǐ)现系统各优势的加固产(chǎn)品就是值得开发者选择的好产(chǎn)品。

爱加密(www.ijiami.cn)是國(guó)内顶尖的移动信息安(ān)全體(tǐ)系服務(wù)商(shāng),专注于為(wèi)移动领域的金融、游戏、企业级应用(yòng)及移动互联网开发者提供安(ān)全可(kě)靠的移动应用(yòng)保护解决方案,服務(wù)范围覆盖Andriod和iOS两大主流智能(néng)手机系统。 

加入收藏