#梆梆安全杯#浅析安卓Native逆向技术

>>>  技術話題—商業文明的嶄新時代  >>> 簡體     傳統

上回说到了安卓平台上基于Dalvik指令的反编译技术,以及面对破坏者的反编译攻击如何比较有效的防范。这篇文章作为上一讲的扩展内容,讲讲破坏者是如何利用工具进行安卓平台上Native代码部分的攻击篡改。
 
一、什么是安卓平台的Native代码?
安卓平台的Native代码说的有些含糊,因为Native代码不区分平台,都是代指C/C++语言编写的代码。因为是底层语言,和硬件衔接的比较紧密,所以称为Native。
安卓平台上面的Native代码是需要Android NDK来进行编译,以生成*.so动态库来供java层调用的,而java层与Native层的数据通信是通过jni技术实现的。这个过程,或者说这项技术不止在Android平台上,Windows/linux上面也是适用的。
关于如何编写安卓平台的Native代码,以及如何生成*.so文件不在本文介绍范围,有兴趣的可以在论坛搜索学习。
 
二、什么样的程序会用到Native代码呢?
这个问题回答起来比较泛泛,一般来说,需要使用C/C++来提升程序的运行效率时会考虑使用Native代码。当然,如果用C/C++写出的库文件可以方便地进行移植,比如作者的项目里,我写的图形控制部分可以轻松的布置到Android和IOS上运行。
除去运行效率不说,由于C语言天生的不可反编回源代码的特性,Native语言在Android平台上也经常被用于保护APP中关键代码部分,比如注册、收费部分。
 
三、APP的NDK保护及逆向演练
由于对逆向工程比较感兴趣,所以对Android平台的程序逆向比较关心,今年年初的时候在群里有妹子共享了一个apk,号称是他们公司内部的一个比赛,能破解的人可以得到XXX奖励。
忍不住内心的好奇,下载下来看了一下,初步断定限制关口是一个类似收费的sp通道,通过发送短信达到注册(收费)的目的后,去除程序限制。当然由于是个比赛性质,发送的短信不是收费短信,而是给写程序的这个人,本帖的最后会附上这个apk,有兴趣的可以试试如何去除限制,当然,最好在离线模式下测试,以免发出短信~~~
其实上面的场景短信限制场景非常普遍,早在java功能手机上就有类似的技术,所以这个限制关口的破解理论上也很简单——在程序监听短信是否发送成功的代码处做文章就可以了。于是拿来apk,反编classes,找到关键入口处进行修改,之后打包签名。一切看上去很简单,但是在程序运行的时候尴尬了,程序根本无法启动,在用eclipse查看日志输出的时候还有截图中的文字。。。。。。瞬时恼火。
 
仔细分析了一下apk的文件结构,基本判定这个apk是做了NDK保护的,而在assets目录下的defense.data文件就是存放某些特征值的文本文件。如下图:
                 
于是,深深的觉得,这个东西需要做Native代码的逆向破解了。
 
3.1 Native逆向的工具准备
1)使用arm-linux-androideabi-objdump工具
如果你技术比较牛的话,可以使用Android NDK自带的arm-linux-androideabi-objdump.exe进行反汇编(Windows环境),该工具位于NDK根目录的toolchains\arm-linux-androideabi-4.6\prebuilt\windows-x86_64\bin路劲下,这里推荐使用arm-linux-androideabi-4.6版本,因为一般的NDK编译默认使用这个版本。
使用方法:
Cmd窗口命令cd到该exe所在路径运行arm-linux-androideabi-objdump -dS libicg.so>dump.txt,当然,你首先需要把要反编译的so文件放在相应的路径下,我的是和工具放在了同目录下。运行完成后,反汇编结果在同级目录下生成。
 
 
 
 
看到了反编译过来的结果是不是很头疼?先留个悬念,我们下面介绍另一个工具。
2)使用IDA进行So文件的静态分析
IDA很有名,可以分析很多文件类型,如果你有看过我的第一篇文章的话应该有印象,那里面也有提过,今天我们就要用它来帮助我们进行so文件的静态分析。
软件的下载安装过程我们省去不说了,直接打开ida,把要分析的SO文件拖进IDA里面。我用的版本是6.4。一直点确定,等IDA分析完成后会显示如图界面:
 
主界面显示的是各个方法间的调用关系。查看最左侧的Function Name,我们在里面发现了Verfication函数,这个函数的命名就很直观嘛,应该就是它了,如果你在实际的操作过程中没有发现一些具有明显特征的函数名,那就要一点一点分析了,比如我们上一篇里讲到的特征字符串啊,动态调试之类的,这些东西需要一定的经验,说起来不是很清楚,有兴趣的可以找个实际工程体会一下。
好,我们点击那个方法名,主界面会跳到该方法下,显示的仍然是调用关系。
 
我们鼠标点击verification,也就是图中绿色部分,然后按空格,主界面会进入该方法,显示的仍然是调用关系,只不过会更加详细。如下图:
 
如果我们想回到刚才的那个大界面的话,使用ctrl+1,点第二项:Proximity browser可以回到上一界面。
来到verification这个方法后,我们发现这里的东西好像和我们用arm-linux-androideabi-objdump反汇编出来的东西类似呢?没错,其实它们都是Arm的指令集。只不过在IDA里面,每段指令间的调用关系都用箭头标出了,在视觉上更加清楚、明了。
在IDA里面先不忙着动手,我们从头到尾观察一下这个方法。
在方法的接近尾部我们发现了图中的指令段:
 
IDA非常人性化地把调用文字以注释的方式显示了出来(在用arm-linux-androideabi-objdump反汇编的文件里没有显示注释,这也是为什么IDA强大的原因)。ICG-FUCk。。。。。这个不就是前面我们修改过classes之后运行APP打印出来的东西么?
统观这个方法,一共有两处调用了这个字符串资源,一处是上图所示,一处是在方法的最后。那倒是哪个才是判断Classes被修改之后的输出呢?我们比对一下两处指令:
                           
第一份截图不知大家能不能看清,在比较指令(CMP)的上方是调用了(BL)zip_fopen,我们这里推测,zip_fopen是一个方法,它应该会返回zip文件是不是被成功打开了,结合cmp指令,这里的BEQ应该判断的是zip文件是不是成功打开了,如果没有则跳转到LOC_33d4,也就是输出icg-fuck。。。。所以说,这处应该不是判断classes文件是否被修改的地方,那么关键代码部分应该是第二份截图的代码段了,这段指令接近方法最后,按理说,是关键指令没错。在观察cmp指令的上一指令,bl了一个decoding的方法,按照这个方法名,应该是把某字符串进行了编码操作,回想起在assets目录下的defense.data文件,这个地方应该就是那段莫名其妙的字符串生成的地方了。到此,关键指令定位成功。
3.2 开始修改so文件
找到了关键代码,那么就很简单了,只需要把BEQ这个跳转指令修改为B(无条件跳转)即可,我们单击BEQ后按空格,界面跳转到16进制显示。
 
 
 
在16进制显示中的几个重要参数我在图片中已经明确表明了,大家注意看,尤其是左下角的偏移量。
 
找到了关键指令位置,我们用16进制编辑器打开SO文件,我用的是HEX Workshop,打开SO文件后按Ctrl+g进行偏移定位,在偏移量中填写刚才在IDA里看到的32ec,选择16进制并选择从文件开头处开始:
 
转到位置后我们看机器码3800000A,和我们在IDA中看到的一样,说明我们定位准确:
 
下一步,我们只需要把BEQ对应的机器码0A改成B(无条件跳转)对应的EA即可,改完后记得保存。
关于指令和机器码对应的关系,我在博客中有整理,大家可以参考:http://521.be/post/307
 
3.3 文件打包
打包很简单,把修改过的SO文件放回原位(winrar就可以)并进行签名就可以运行测试了。
至此,安卓平台的Native逆向技术就介绍完了,想想,其实SO文件的逆向也不是很难。
四、总结及加固建议
本文通过向大家展示一个完整的SO文件逆向工程,来让大家了解“破坏者”的攻击手段,以提醒开发者在实际开发过程中注意自身的代码安全。
宏观来开,不论是java文件的逆向,还是Native的逆向都是不难的,要想通过代码手段来阻止“破坏者”的攻击基本是不可能的,但是我们可以把关键代码部分写的复杂些,逻辑判断更复杂些以扰乱“破坏者”的思路,达到让他放弃攻击的目的。
看到这里有人可能会问,对于Native本身的保护怎么办呢?答案是可以给SO文件加壳,而这个内容已然超出本文讨论范围,这里不再赘述。
附一个IDA的下载地址:http://pan.baidu.com/s/1ntNWwlV

clxy 2014-07-25 19:33:22

[新一篇] .NET程序員不要錯過如此強大的T4模板

[舊一篇] android sdk manager 無法更新解決方法
回頂部
寫評論


評論集


暫無評論。

稱謂:

内容:

驗證:


返回列表