返回介绍

23.2 获取解密之后的 dex 文件

发布于 2024-10-10 22:32:23 字数 4955 浏览 0 评论 0 收藏 0

分析完上面的破解流程之后,发现首要的任务是先得到源 apk 程序,通过分析知道,处理源 apk 程序很难找到,所以就要引出本章的内容了:使用动态调试,给 libdvm.so 中的函数 dvmDexFileOpenPartial 下断点,然后得到 dex 文件在内存中的起始地址和大小,然后 dump 出 dex 数据即可。

这里会有人提出几个问题。

第一个问题:为何要在 dvmDexFileOpenPartial 函数下断点?

不管之前的源程序如何加固,放到哪了,最终都是需要被加载到内存中然后运行,而且是没有加密的内容,那么只要找到 dex 的内存位置,把这部分数据弄出来就可以了,管它之前是如何加固的,那么问题就变成了,如何获取加载到内存中的 dex 的地址和大小。这要用到函数 dvmDexFileOpenPartial,因为这个函数是最终分析 dex 文件,加载到内存中的函数:

第一个参数是 dex 内存起始地址,第二个参数是 dex 大小。

第二个问题:如何使用 IDA 给这个函数下断点

在前一章中介绍了动态调试 so,下断点的时候必须知道一个函数在内存中的绝对地址,而函数的绝对地址是:这个函数在 so 文件中的相对地址+so 文件映射到内存中的基地址。这个函数肯定是存在 libdvm.so 文件中的,因为一般涉及 dvm 有关的函数功能都是存在这个 so 文件中,那么可以从这个 so 文件中找到这个函数的相对地址,运行程序之后,再找到 libdvm.so 的基地址,相加即可。如何获取到 libdvm.so 文件呢?这个文件是存放在设备的/system/lib 目录下的:

只需要使用 adb pull 命令把这个 so 文件弄出来就可以了。

解决了这两个问题,下面就开始操作了。

第一步:运行设备中的 android_server 命令,使用 adb forward 进行端口转发:

这里的 android_server 工具可以去 ida 安装目录中 dbgsrv 文件夹中找到:

第二步:使用命令以 debug 模式启动 apk:

因为需要给 libdvm.so 下断点,这个库是系统库,所以加载时间很早。需要像之前给 JNI_OnLoad 函数下断点一样,采用 debugger 模式运行程序,这里通过上面的 AndroidManifest.xml 中得到应用的包名和入口 Activity:

而且这里的 android:debuggable=true 可以进行 debug 调试的。

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

通过 IDA 的 Debugger 菜单,如图 23-6 所示。进行进程附加操作,如图 23-7 所示。

图 23-6 设置调试端口

图 23-7 搜索附加进程

第四步:使用 jdb 命令启动连接 attach 调试器:

但是这里可能会出现这样的错误:

这是因为 8700 端口没有指定,这时候可以通过 Eclipse 的 DDMS 进行端口查看,如图 23-8 所示。

图 23-8 查看进程调试端口

这里是 8600 端口,但是基本端口 8700 不在。有两种处理方式,一种方式是把上面的命令的端口改成 8600,还有一种方式是选中这个应用,使其具有 8700 端口,如图 23-9 所示。

图 23-9 设置 8700 端口

点击这个条目即可,这时候再运行上面的 jdb 命令:

处于等待状态。

第五步:给 dvmDexFileOpenPartial 函数下断点。

使用一个 IDA 静态分析得到这个函数的相对地址 43308,如下所示:

在动态调试的 IDA 中进行解密,使用 Ctrl+S 键找到 libdvm.so 在内存中的基地址 41579000,如图 23-10 所示。

图 23-10 函数的基地址

然后将两者相加得到绝对地址 43308+41579000=415BC308,使用 G 键,跳转,如图 23-11 所示。

图 23-11 跳转到绝对地址

跳转到 dvmDexFileOpenPartial 函数处,下断点,如下所示:

第六步:点击运行按钮或者 F9 键运行程序。

之前的 jdb 命令就连接上了:

IDA 出现一些提示界面,不要理会,一路点击 Cancel 按钮即可,如图 23-12 所示。

图 23-12 加载 so 文件对话框

运行到了 dvmDexFileOpenPartial 函数处,如下所示:

使用 F8 键进行单步调试。这里需要注意的是,只要运行过了 PUSH 命令就可以了,记得不要越过下面的 BL 命令,因为没必要走到那里。当执行了 PUSH 命令之后,就是使用脚本来 dump 出内存中的 dex 数据了。这里有一个知识点:R0~R4 寄存器一般是用来存放一个函数的参数值的,而 dvmDexFileOpenPartial 函数的第一个参数就是 dex 内存起始地址,第二个参数就是 dex 大小,如下所示:

这里就可以使用这样的脚本进行 dump 操作:

脚本不解释了,非常简单,而且这是固定的格式,以后 dump 内存中的 dex 都是用这段代码,将 dump 出来的 dex 保存到 F 盘中。

然后使用 Shirt+F2 键调出 IDA 的脚本,如图 23-13 所示。

图 23-13 dump 出 dex 文件

点击 Run,这里可能需要等一会。运行成功之后,去 F 盘得到 dump.dex 文件。到这里,IDA 使命就完成了,因为得到了内存的 dex 文件了,下面只要分析 dex 文件即可。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文