Apk脱壳圣战之---脱掉“爱加密”的壳

一、前言

今天是端午节,然而小编不能吃粽子了,只能继续破解之路,今天我们来看一下在了解了破解三部曲之后,如何开始脱掉各个市场中的apk壳,关于破解三部曲在之前已经介绍了:

第一篇:Android中使用Eclipse动态调试smali源码

第二篇:Android中使用IDA动态调试so源码

第三篇:Android中破解加固的apk

在看完这三篇文章之后,我们开始操作如何破解市场中的加壳方案,现在市场中比较流行的加壳平台就那么几个:爱加密,梆梆加固,360加固,腾讯加固等,所以后面会一一介绍如何脱掉这些平台的壳。之前也说过现在加固的方案大体思路都是:把源apk进行加密拆分处理,然后在套一个外部的壳Application做一些初始化操作:比如解密apk,动态加载运行即可。但是我们已经知道了如何去破解那些加固的apk了,就是使用IDA给dvmDexFileOpenPartial函数下断点,然后dump出内存中的dex数据即可。因为内存中的dex肯定是解密之后的,所以大体思路知道了,但是这些加固平台也有对策,他们会把做一些反调试操作,对so文件进行混淆加密等,让我们的调试变得比较困难。这才是我们脱壳的阻碍地方。

二、案例分析

好了,说了这么多,下面我们就开始脱壳第一站:爱加密家的壳

为了脱掉他家的壳,我们得首先有一个案例程序,这个比较简单,我们自己弄一个demo程序,然后去他家的网站上加固一下,得到加固之后的apk,然后这时候我们开始破解了,按照惯例:

第一步:解压apk,看看大体的目录,得到classes.dex文件,然后用dex2jar+jd-gui得到Java源码

看到,这里只有Application的壳,而且这个是爱加密加固之后的特点,都是这两个Application的。

第二步:使用apktool来反编译apk,获取资源文件信息

分析一下爱加密的加密流程

也是国际惯例,爱加密把我们的源程序进行加密操作然后隐藏到了一个地方,在之前破解加固apk的那篇文章中也说过了,隐藏的地方就那么几个:assets目录、libs目录、自己的dex文件中

这里我们直接看assets目录:

多了这个东东,猜想这个可能就是处理之后的源apk了。我们在AndroidManifest.xml中看到了入口的Application类,先来看这个类

下面我们来分析一下这个SuperApplication类:

这里一般都是在attachBaseContext这个方法中进行操作的,这里的时机比较早,我们看到首先会调用loadLibs方法进行加载libs:

这里区分不同的平台,然后进行拷贝不同的so文件,继续看copyLib方法:

这里我们可以看到了,从assets目录下把爱加密增加的两个so文件:libexec.so和libexecmain.so拷贝到应用程序的files目录下,我们可以去看看assets/ijm_lib目录下的so文件:

到这里loadLibs方法就执行完了,下面就开始调用NativeApplication的load方法进行加载数据,继续看NativeApplication类:

这里会开始从应用程序的files目录中加载这两个so文件,而且load方法也是一个native方法,我们继续看看这两个so文件内容:

我们首先用IDA打开libexecmain.so文件,但是发现,他里面并没有什么重要信息,连JNI_OnLoad函数都没有东东

我们继续在查看libexec.so文件:

擦,可惜的是,打开提示so文件格式错误,到这里,我们就猜到了,这个so可能被加密处理了,elf格式改了,关于so如何进行加密操作的,不了解的同学可以看这里:Android中如何对so文件进行加密 那么这里我们点击Yes继续强制打开之后,在使用Ctrl+S查看so的各个段信息:

现在可以百分百的确定,这个so文件被处理了,段格式被修改了。我们没办法分析so文件了,当然这里我们可以在dump出内存中的so文件,然后在分析的,但是这个不是今天讲解的重点。我们先分析到这里,也知道了爱加密的大体加密流程。

好了,到这里,我们差不多分析完了爱加密的加密流程了:

1、按照国际惯例把源apk进行加密处理存放在一个地方,通过分析猜想是assets目录下的ijiami.dat文件

2、添加壳Application:SuperApplication类,在这个壳的attachContext方法中,主要做了两件事:

1》第一件事是把assets/ijm_lib目录下的两个so文件copy到程序的files目录中;

2》第二件事是调用NativeApplication的load方法,在这个类中同时也把上面的两个so文件加载到内存中

3、对apk的加密操作都是放在底层的两个so文件中操作的,我们通过IDA去分析这两个so文件之后,发现核心功能的so文件被加密了,IDA打开是看不到具体信息了

到这里,我们知道爱加密加固之后的特点是:在程序的assets目录下多了一个ijiami.dat文件和两个so文件,同时这两个so文件被加密处理了,增加破解难度。

三、破解脱壳

上面就简单分析了爱加密的原理和流程,但是我们没有继续往下面分析了,因为这个不是我们今天讲解的重点,我们今天的重点是如何脱掉爱加密的壳,那么还是开始说到的,脱壳的核心就一个:给dvmDexFileOpenPartial函数下断点,dump出内存的dex文件即可,那么下面我们就是用IDA开始脱壳操作了:

第一步:启动设备中的android_server,然后进行端口转发

adb forward tcp:23946 tcp:23946

第二步:用debug模式启动程序

adb shell am start -D -n com.droider.crackme0201/.MainActivity

这里的包名和入口Activity都可以在上面反编译之后的AndroidManifest.xml中找到

第三步:双开IDA,一个用于静态分析libdvm.so,一个用于动态调试

记录dvmDexFileOpenPartial函数的相对地址:4777C

再次打开一个IDA,进行attach调试进程

第四步:使用jdb命令attach上调试器

jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700

第五步:对dvmDexFileOpenPartial函数下断点

进入调试页面之后,Ctrl+S查找libdvm.so的内存基地址:415BB000

在第三步得到相对地址:4777C+415BB000=4160277C 得到了dvmDexFileOpenPartial在内存中的绝对地址

注意:

当然这里还有一个更方便的办法:

就是直接打开Modules View:

在这里查找libdvm.so文件:

然后双击libdvm.so文件:

查找需要下断点的函数名称,看到这里的绝地地址也是:4160277C

这里有两种方式可以得到一个函数在内存中的绝对地址。

然后我们使用G键,直接跳转到函数处,下断点:

第六步:设置Debugger Options选项

能够让程序断在dvmDexFileOpenPartial函数处

注意:

上面的第四步,第五步,第六步,没有顺序的,只要在运行之前设置到就可以了。

第七步:运行程序

出现这个对话框,不要在意,一路点击Cancel即可

jdb也attach上了调试程序:

我们一路点击运行按钮,知道运行到dvmDexFileOpenPartial处的断点,但是可惜的是,这里我们遇到了错误:

我们点击OK之后,出现了下面对话框:

再次点击任何一个按钮,都会退出了调试页面:

我们在重新尝试一次上面的流程,开始调试,但是错误是一样的,好了,到这里我们就立马想到了,之前说的IDA调试so的那篇文章遇到的那个问题:反调试检测

当时我们也是遇到这个情况,在没有运行到我们下的断点处,就退出了调试页面,其实这个是现在加固平台必要选择的一种方式,其实反调试原理很简单,就是在程序运行最早的时机比如so加载的时候即:JNI_OnLoad方法中,读取本进程的status文件,查看TracerPid字段是否为0,如果不为0,那么就表示自己的进程被别人跟踪了,也就是attach了,那么这时候立马退出程序,下面我们使用IDA在attach进程成功之后,查看本进程的status信息:

看到这里的TracerPid为11340,不为0,表示被11340进程attach了,那么我们可以查看一下这个进程是谁:

其实这个进程就是我们在设备中安插的android_server,它用于和IDA进行通信。

好了到这里,我们可以看到爱加密做了反调试检测,但是按照之前的那篇文章中,我们可以给JNI_OnLoad函数下断点,然后找到检测代码,把对应的arm指令改成空指令,检测失效了,但是这里我们知道爱加密的两个so文件被处理了,IDA没法分析了,那么这里我们该怎么办呢?如何应对反调试呢?其实我们可以借助IDA可以修改寄存器和内存数据的特性来做到?

首先我们上面分析了反调试的原理,一般在native代码去做检测的话,都是用fopen系统函数打开status文件,然后用fgets函数读取一行的内容,这个是国际惯例的,操作文件都是用的fopen函数的

好了,那么这里思路就有了:既然反调试肯定用到了fopen和fgets这两个函数,那么我们直接像给dvmDexFileOpenPartial下断点的方式一样,给这两个函数下断点,然后运行到fgets断点处的时候,发现如果是读取TracerPid这行内容的时候,就开始修改内存内容,把TracerPid字段的值改成0,或者修改R0寄存器的内容,跳过反调试检测

这两个函数是在libc.so文件中的,我们可以把设备的/system/lib/libc.so使用adb pull到本地即可,然后用IDA得到他的相对地址,在调试页面得到基地址,然后相加得到绝对地址,跳转即可,但是这里不用这种复杂的方式,有两种方式可以进行跳转:

第一种方式:在Modules界面,找到libc.so,然后在找到这两个函数,就可以得到他们的绝对地址了

然后使用G键,跳转下断点即可:

第二种方式:也是最简单的方式,就是G键,本身就有可以直接输入函数名进行跳转的功能

下断点:

看到了吧,这种方式是不是非常简单高效

好了到这里就给这两个函数下好了断点,当然这里还需要给dvmDexFileOpenPartial函数下断点,一切弄好了之后,这时候我们再次运行:

停在了fopen断点处,我们使用F8单步调试,看到R7寄存器中的内容是/proc/...,我们直接点击R7查看全部内容:

内容有点长,大致的内容是:/proc/self/cmdline.debug.atrace.app_cmdlines,这个是干什么的?

我们看看这个目录内容:

发现没有这个文件内容,只有cmdline文件,但是这里先不管他了,我们知道这个肯定不是读取status文件的,那我们直接略过这个断点,点击F9运行到下一个断点,中间过程先忽略,一路F9,直到运行到了fopen这个断点:

果然,这里使用了fopen来读取status文件了,点击R7寄存器查看全部内容:

这个16396就是我们本进程的id:

到这里,我们知道下一个断点肯定是fgets,所以点击F9进入到fgets断点处:

这里还看不到什么信息,我们继续点击F8单步调试:

途中,会看到有memchr和memcpy这两个重要函数,这个也是操作字符串的核心点,继续往下走:

到了fgets函数结束的地方,我们看到了R0寄存器的内容是Name...点击R0查看全部内容:

全部内容是:Name:   der.crackme0201;这个就是status文件的第一行内容:

到这里,我们知道了,开始读取status文件的每行内容了,但是到TracerPid那行还要继续执行5次fgets函数,所以还会进入5次断点,为了节省时间,这里点击5次F9,直接运行到读取TracerPid那行的内容的fgets断点处:

看到了关键的内容了TracerPid字段了,这时候,我们打开Hex View 查看16进制的内存数据:

但是我们看到,这个并没有和调试页面View位置相对应,我们可以这么操作:

在寄存器窗口查看到R0寄存器的内容:

这里就是TracerPid字段在内存的地址,记录一下,然后在Hex View页面中使用G键,进行跳转,这里一定要注意是在HexView,而不是调试页面,调试页面使用G键跳转到的是指令地址了。

好了,这里我们看到了TracerPid的内存内容了,这里我们就开始修改吧,选择我们要修改的内容:是11340那里:

选择内容开始处,右击,选择Edit,进入修改状态:

改了之后的内容是橘黄色的,修改完成之后,在点击右键,选择Apply changes:

完成修改,颜色变成灰土色了:

注意:

这里其实还可以直接修改寄存器R0的值:

这时候就表示修改成了,我们继续使用F8单步调试下去:

这里就开始把TracerPid字段的值和0作比较了,我们点击R0寄存器查看全部内容:

这里的值已经被改成了0,所以这里就骗过去了。继续运行,我们会发现,又进入了fopen函数的断点处,而且查看还是读取status文件,这个也不好奇,因为是反调试检测肯定是一个轮训机制的,所以肯定会反复的读取的这个文件,fopen走多次也是正常的,但是这个反调试肯定是在子线程的,所以只要到了主线程中解密dex文件就肯定到了dvmDexFileOpenPartial,所以这里会多次重复上面的操作,修改多次TracerPid的值,这里就不在演示了,我在操作的过程中修改了三次,当没有在走fopen函数的时候,遇到了这个错误,这里不关心,直接点击ok就可以了。

再次点击运行:

这里说明已经改开始解密dex文件了,应该离成功不远了,继续运行:

终于到了我们想要的地方了,到这里就好办了,直接点击Shirt+F2,打开脚本运行窗口,运行下面脚本:

static main(void)
{
    auto fp, dex_addr, end_addr;
    fp = fopen(“F:\\dump.dex”, “wb”);
    end_addr = r0 + r1;
    for ( dex_addr = r0; dex_addr < end_addr; dex_addr ++ )
        fputc(Byte(dex_addr), fp);
}

把内存中的dex保存到F:\dump.dex中,这里不再解释了,之前的一篇文章已经介绍过了,这里R0寄存器就是dex在内存中的起始地址,R1寄存器就是dex文件的大小:

我们使用G键,可以在HexView页面中查看R0寄存器中的地址内容:

看到了吧,这里就是dex的头文件格式。

四、还原应用apk

我们得到了内存中的dex数据之后,可以使用baksmali工具转化成smali源码,查看代码逻辑即可,这里不再演示了。

然后最后还有一步:还原apk

首先我们修改反编译之后的AndroidManifest.xml中:

把这段内容删除,如果有自己的Application的话,就改成自己的Application即可,同时删除assets目录下面的文件。

然后使用apktool进行回编译,这时候,先不要着急签名apk,而是替换classes.dex:

我们把上面得到的dump.dex改成classes.dex然后直接用压缩软件,替换未签名的apk中的dex文件即可

最后在进行签名操作,完成还原apk工作。

五、总结爱加密的破解流程

好了到这里,我们算是脱壳成功了,下面来总结一下吧:

目标:

在脱壳的过程中,我们就一个目标:dump处内存中的dex文件

但是在上面分析了爱加密的加固流程之后,发现他做了这些事:

1、把源程序apk加密处理放到了assets目录下的ijiami.dat,也同时在assets\ijm_lib目录下添加两个so文件:libexec.so和libexecmain.so,这里两个so文件用来处理整个apk解密,动态加载等逻辑,但是我们用IDA查看得知,这两个so文件被加密处理了

2、添加自己的壳Application:SuperApplication类,这个类中的attachContext方法中,首先把assets目录中的两个so文件copy到应用的files目录下,然后在使用System.load方法,加载这个files目录中的两个so文件

3、我们在给dvmDexFileOpenPartial下断点,进行调试的时候,发现有反调试检测,因为无法给JNI_OnLoad下断点来去除反调试功能的arm指令,所以只能去修改内存数据,把TracerPid的值变成0,骗过检测了。这里我们的思路就是给fopen和fgets这两个函数下断点,因为我们知道反调试的原理就是读取本进程的status文件,然后获取TracerPid那行内容即可,所以这里肯定用到了fopen和fgets函数,在使用fgets这个函数的时候,会读取每行内容,那么我们只要发现在读取到TracerPid那行内容的时候,去修改内存值,把TracerPid字段的值改成0即可。

4、有了上面的反调试思路之后,我们就开始进行操作了,但是在操作的过程中发现多次执行了fopen和fgets函数,而且我们需要修改多次TracerPid的值,原因很简单,因为是反调试检测,肯定是在子线程中轮训去检测这个值,所以会执行多次很正常,所以我们要修改多次TracerPid的值,骗过检测,直到当在主线程中,代码运行到了解密dex文件的时候,即到了dvmDexFileOpenPartial函数处的断点处为止

5、最后修改多次TracerPid值,骗过检测,到了dvmDexFileOpenPartial这里,这时候,在执行dump脚本,把内存中的dex数据dump到本地即可。

通过上面的调试和破解流程其实不难发现,爱加密的流程是这样的:

1》fopen—/proc/self/cmdline.debug.atrace.app_cmdlines
2》fgets—-com.droider.crackme0201
3》dvmLoadNativeCode–加载libexec.so
4》dvmLoadNativeCode–加载libexecmain.so
5》建立反调试线程(通过检查是否存在调试进程)
6》调用fopen—-打开/proc/pid/status
7》调用fgets—读取调试进程pid

这里除了dvmDexFileOpenPartial函数,还有一个重要的函数dvmLoadNativeCode,它是加载和初始化so的函数,如果感兴趣的同学,可以去给这个函数下断点看看运行逻辑。

所以我们只要记住我们的目的只有一个:达到dvmDexFileOpenPartial函数处,dump处内存中的dex文件,就算是完成脱壳工作

六、总结

到这里我们就分析完了如何去脱掉爱加密的壳,其实在之前说过,现在各个加固平台的原理都差不多,最后看到的就是各家的加固算法了,所以我们在脱壳的过程中目标也很明确,就是dump出内存中的dex文件即可。不管他上层再怎么牛逼的加密拆分操作,到了内存肯定是完整的dex文件了,所以现在加固平台也是一个思想就是不让你dump出来,就是让你给dvmDexFileOpenPartial函数下断点失败,调试失败。

更多内容:点击这里

关注微信公众号,最新Android技术实时推送

时间: 2024-10-10 09:25:27

Apk脱壳圣战之---脱掉“爱加密”的壳的相关文章

Apk脱壳圣战之---脱掉“360加固”的壳

一.前言 现在主流的加固平台有:梆梆加固,爱加密,360加固,腾讯加固,在之前的一篇文章中介绍了:如何脱掉"爱加密"的壳,现在这里要脱掉另外一个平台的壳:360加固,因为有了之前的脱壳经验,很多基础知识和准备工作这里就不详细介绍了,为了能够脱掉他家的壳,用一个案例来去360平台进行加固,然后进行脱壳.下面就来开始脱壳: 二.分析360加固的原理 首先拿到加固之后的apk,这里为了方便查看内部信息,先不用dex2jar+jd-gui工具进行分析了,直接使用我们之前分析了源码的一个工具:J

Apk脱壳圣战之---如何脱掉“梆梆加固”的保护壳

一.前言 现如今Android用户的安全意识不是很强,又有一些恶意开发者利用应用的名字吸引眼球,包装一个恶意锁机收费的应用,在用户被骗的安装应用之后,立马手机锁机,需要付费方可解锁.这样的恶意软件是非常让人痛恨的.所以本文就用一个案例来分析如何破解这类应用,获取解锁密码,让被骗的用户可以找回爽快! 二.分析软件锁机原理 本文用的是一款叫做:安卓性能激活.apk,关于样本apk文件后面会给出下载地址,从名字可以看到它肯定不会是一个恶意软件,但是当我们安装的时候,并且激活它的权限之后就完了.下面不多

ZJDroid脱 爱加密 的壳的经过

用ZJDroid给某爱加密加壳的apk脱壳的经过. 本菜鸟虽然编码的经验还是有的,但是破解可以说是第一次.这次在用ZJDroid给某个APK脱壳碰到了一些问题,所以记录下来,如果能给碰到同样问题的童靴提个醒,就很高兴了.所以 高手请绕道,别笑话菜鸟啊 :) 背景 这个APK包名为com.xxx.client包含了一个so文件,叫libxxx.so 整个包用爱加密加了壳. 典型特征就是apk的assert目录下有ijiami.dat文件 原理 一句话来说的话,就是用ZJdroid的"backsma

【天翼杯安卓题二】 爱加密脱壳实战

前言 这个apk使用爱加密加密,加密时间是2017.6月.这个题其实就是个脱壳题,脱完立马见flag.(出题人也太懒了) 题目链接:https://gitee.com/hac425/blog_data/blob/master/app02.apk 壳介绍 爱加密的壳16年年底就已经开始通过 hook dvmResolveClass ,在调用具体方法时解密方法指令,然后将 DexFile结构体中的对应方法的 md->insns 指向 解密后的方法指令数据区,然后进入 真正的dvmResolveCla

手游Apk破解疯狂,爱加密apk加固保护开发人员

2013年手游行业的规模与收入均实现了大幅增长,发展势头强劲.权威数据显示, 我国移动游戏市场实际销售收入从2012年的32.4亿猛增到2013年的112.4亿元,同比增长了246.9%,手游用户从2012年的8900万迅 速增长到2013年的3.1亿,增长幅度高达248.5%.来源!www.ijiami.cn 可是,在移动手游快速发展的同一时候,暴露出的手游破解问题也日益严重,手机游戏软件被破解后注入恶意代码.盗取用户財产.窃取用户设备信息的现象屡见不鲜.2014年1月,台湾易游网络有限公司旗

App山寨疯狂 爱加密Apk加密平台防破解

App山寨疯狂 爱加密Apk加密平台防破解,Android系统由于其开源性,眼下已占领全球智能机近80%的市场,远超微软的WP系统和苹果的IOS系统.然而也正是由于开源性,Android盗版App在国内横行泛滥,盗版App通过广告骚扰.窃取账号.盗取隐私.远程控制.恶意扣费.购物欺诈等影响用户的体验,侵害用户利益.文章出处:www.ijiami.cn App山寨疯狂 爱加密Apk加密平台防破解,面对严重的App山寨横行的现象,国内第三方针对Android应用加固的平台爱加密,致力于保护App安全

爱加密加固病毒分析-脱壳篇

一.文件信息 文件名称:久秒名片赞系统 包名: android.support.v8 大小: 1497829 bytes MD5: 8123AC1150B47EF53507EC2360164E3B SHA1: 958B1E341C72DBCF52863C570B77C71A862987B1 程序壳:爱加密 描述:爱加密有反调试功能,无法直接给关键函数下断点,所以只能单步跟踪到它检测反调试的地方修改比较值,从而跳过反调试.壳程序通过读取进程文件(/proc/uid/status)中的TracerP

如何阻止APK反编译查看源代码? 爱加密保护开发者创意

小编曾看到一篇文章,说是一个在校大学生开发一个App并上传应用市场,不久,市场即出现相同的App,下载量还很可观,这个App是反编译了他的应用包.因为他当时没有资金和团队,无从申诉,反被同学认为是剽窃他人的创意,创业之路也因此夭折. 他说道如果市场上早些出现关于App加密保护的平台,也许自己的创业道路会更顺遂.小编也感到很惋惜,今天就说说如何防止黑客反编译查看APK源码的问题,想要防止反编译APK,就要知道反编译得到源码是如何进行的. 反编译APK得到Java源代码 就用反编译工具来举例,例如d

如何防止Android反编译apk,爱加密进行安卓加密保护!

近年来,针对网购.交友网站,发送伪装成"样品"或"私照"的钓鱼.木马链接类诈骗逐渐增多:套取个人信息类诈骗手法有所升级,如借卡转账.机票退订等,要求提供银行卡卡号.身份证号及短信验证码:大家熟悉的网络买卖,买家可能"易容",网上的店铺也可能是"僵尸".尤其是近日<E天下>头条报道<小心!不明链接勿乱按>后,引来众多读者反馈:骗子是怎样伪装的呢?常用的伎俩有哪些?现在,爱加密就来为大家一一揭晓,帮助大家在