0x00 摘要
Apk脱壳方法有两种:
(1)使用脱壳神器ZjDroid进行脱壳(现在此方法不是很好使,因为很多应用都同步更新自己的防御机制,个人觉得熟练脱壳还是得使用 IDA 进行操练)。
(2)使用 IDA Pro 在 dvmDexFileOpenPartial 这个函数下断点进行脱壳。(大杀技)
加壳能防止源代码被偷窥,但是这只能防止静态分析,无法防止动态调试。不管怎么加壳保护,原始的classes.dex在App运行时都要加载到内存中。所以如果在App加载classes.dex处下个断点,然后再把classes.dex对应内存中的内容抠出来还原成原始的classes.dex文件,就能达到脱壳的目的了。
0x01 实验
(1)以第1届Alictf的EvilApk300(如图0所示)为例,简单介绍一下使用IDA Pro 进行脱壳的步骤
- step 1:将手机连接电脑
[Bash shell] 纯文本查看 复制代码
|
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 |
|
如果成功,手机上 app 会弹出 “Waiting For Debugger”
- step 2:操作 IDA
依次点击”Debbuger -> Attach -> Remote ARMLinux/Android debugger”启动IDA Pro中的Android Debbuger
然后在弹出的对话框中点击”Debug options”按钮,将“Suspend on process entry point”,“Suspend on thread start/exit”,“Suspend on library load/unload”这几个选项勾选上,再将Hostname配置为localhost,端口:23946
注意:Ctrl + F 方便查找
-
step 3:继续 IDA
脱壳的时候重点关注:dvmDexFileOpenPartial 函数(在该函数处下断点)
依次点击“Debugger -> Debugger windows -> Module list”,找到so文件列表
在Module list中找到libdvm.so这个文件(注意:Ctrl + F 方便查找)
双击libdvm.so,在弹出的函数列表中找到dvmDexFileOpenPartial函数,然后双击该函数就看到dvmDexFileOpenPartial函数的具体实现
在dvmDexFileOpenPartial函数处下断点(F2 下断点)
- step 4:使用jdb命令动态调试Apk
点击 ida 左上角的绿色运行按钮(F9)
打开 DDMS 工具(android-sdk\sdk\tools\ddms.bat)
使用jdb命令进行调试时,一般选择8700端口,因为8700是默认的调试端口;打开终端窗口,输入:
[Bash shell] 纯文本查看 复制代码
|
1 2 3 |
|
此时 IDA 会弹出 ”Add map…” 窗口(点击 cancel 按钮即可):
此时进程就执行到了dvmDexOpenPartial函数断点处,dvmDexOpenPartial 函数的定义:
[C++] 纯文本查看 复制代码
|
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
dvmDexFileOpenPartial 函数的原型如下所示:
int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)
其中 addr表示Dex文件在内存中的起始地址,
len 表示Dex文件的大小,
ppDvmDex是一个指向DvmDex类型的二级指针,具体表示什么,我也不知道
脱壳只用到 addr 和 len 这两个参数,所以需要获取 R0 和 R1 寄存器的值(ARM的传递参数机制规定 R0 保存着函数从左至右的第一个参数,R1 保存着函数从左至右的第二个参数),可以查看到寄存器列表中的内容如图所示:
- step 5:在 IDA 中编写idc脚本dump内存还原dex文件
选择 File -> Script command…
稍等片刻,即可以把 dump 出来的 dex 文件保存在 C 盘根目录
IDC脚本:
[C] 纯文本查看 复制代码
|
1 2 3 4 5 |
|
- step 6:使用 JEB 分析dump 出来的 dex 文件[此处内容请参考原文]
| 本文脱壳核心思想:在 dvmDexFileOpenPartial 函数处下断点,然后动态调试 Apk,待App 运行到断点处后,写一个 idc 脚本将 dex 文件所对应的内存 dump 出来,然后还原成 dex 文件就完成脱壳操作了,最后再分析反编译 dex 所得到的 smali 文件。 |
- 参考文献
[1] 听鬼哥说ZJDROID脱壳的简单使用:http://blog.csdn.net/guiguzi1110/article/details/38727753
[2] 安卓逆向学习笔记(9)- 使用IDA Pro进行简单的脱壳 :http://blog.csdn.net/pengyan0812/article/details/46275317
[3] Android应用方法隐藏及反调试技术浅析:http://www.kuqin.com/shuoit/20151012/348473.html0x00 摘要
Apk脱壳方法有两种:
(1)使用脱壳神器ZjDroid进行脱壳(现在此方法不是很好使,因为很多应用都同步更新自己的防御机制,个人觉得熟练脱壳还是得使用 IDA 进行操练)。
(2)使用 IDA Pro 在 dvmDexFileOpenPartial 这个函数下断点进行脱壳。(大杀技)
加壳能防止源代码被偷窥,但是这只能防止静态分析,无法防止动态调试。不管怎么加壳保护,原始的classes.dex在App运行时都要加载到内存中。所以如果在App加载classes.dex处下个断点,然后再把classes.dex对应内存中的内容抠出来还原成原始的classes.dex文件,就能达到脱壳的目的了。
0x01 实验
(1)以第1届Alictf的EvilApk300(如图0所示)为例,简单介绍一下使用IDA Pro 进行脱壳的步骤
- step 1:将手机连接电脑
[Bash shell] 纯文本查看 复制代码
|
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 |
|
如果成功,手机上 app 会弹出 “Waiting For Debugger”
- step 2:操作 IDA
依次点击”Debbuger -> Attach -> Remote ARMLinux/Android debugger”启动IDA Pro中的Android Debbuger
然后在弹出的对话框中点击”Debug options”按钮,将“Suspend on process entry point”,“Suspend on thread start/exit”,“Suspend on library load/unload”这几个选项勾选上,再将Hostname配置为localhost,端口:23946
注意:Ctrl + F 方便查找
-
step 3:继续 IDA
脱壳的时候重点关注:dvmDexFileOpenPartial 函数(在该函数处下断点)
依次点击“Debugger -> Debugger windows -> Module list”,找到so文件列表
在Module list中找到libdvm.so这个文件(注意:Ctrl + F 方便查找)
双击libdvm.so,在弹出的函数列表中找到dvmDexFileOpenPartial函数,然后双击该函数就看到dvmDexFileOpenPartial函数的具体实现
在dvmDexFileOpenPartial函数处下断点(F2 下断点)
- step 4:使用jdb命令动态调试Apk
点击 ida 左上角的绿色运行按钮(F9)
打开 DDMS 工具(android-sdk\sdk\tools\ddms.bat)
使用jdb命令进行调试时,一般选择8700端口,因为8700是默认的调试端口;打开终端窗口,输入:
[Bash shell] 纯文本查看 复制代码
|
1 2 3 |
|
此时 IDA 会弹出 ”Add map…” 窗口(点击 cancel 按钮即可):
此时进程就执行到了dvmDexOpenPartial函数断点处,dvmDexOpenPartial 函数的定义:
[C++] 纯文本查看 复制代码
|
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
|
dvmDexFileOpenPartial 函数的原型如下所示:
int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex)
其中 addr表示Dex文件在内存中的起始地址,
len 表示Dex文件的大小,
ppDvmDex是一个指向DvmDex类型的二级指针,具体表示什么,我也不知道
脱壳只用到 addr 和 len 这两个参数,所以需要获取 R0 和 R1 寄存器的值(ARM的传递参数机制规定 R0 保存着函数从左至右的第一个参数,R1 保存着函数从左至右的第二个参数),可以查看到寄存器列表中的内容如图所示:
- step 5:在 IDA 中编写idc脚本dump内存还原dex文件
选择 File -> Script command…
稍等片刻,即可以把 dump 出来的 dex 文件保存在 C 盘根目录
IDC脚本:
[C] 纯文本查看 复制代码
|
1 2 3 4 5 |
|
- step 6:使用 JEB 分析dump 出来的 dex 文件[此处内容请参考原文]
| 本文脱壳核心思想:在 dvmDexFileOpenPartial 函数处下断点,然后动态调试 Apk,待App 运行到断点处后,写一个 idc 脚本将 dex 文件所对应的内存 dump 出来,然后还原成 dex 文件就完成脱壳操作了,最后再分析反编译 dex 所得到的 smali 文件。 |
- 参考文献
[1] 听鬼哥说ZJDROID脱壳的简单使用:http://blog.csdn.net/guiguzi1110/article/details/38727753
[2] 安卓逆向学习笔记(9)- 使用IDA Pro进行简单的脱壳 :http://blog.csdn.net/pengyan0812/article/details/46275317
[3] Android应用方法隐藏及反调试技术浅析:http://www.kuqin.com/shuoit/20151012/348473.html