在安卓脱壳过程中,经常需要用ida动态调试so,并且在解密代码执行前下断点,下面介绍用IDA在Android so文件的.init
、.init_array
上和JNI_OnLoad
处下断点方法。我们以自己编写的一个小程序initTest.apk
为例,该apk实现了在.init
、.init_array
上和JNI_OnLoad
中的方法中打印日志功能.
下载地址:http://download.csdn.net/detail/u012417380/9919842
一、上传android_server
,启动android_server
上传android_server
到手机/data/local/tmp
目录
adb push android_server /data/local/tmp
赋予 android_server
执行权限
$ chmod 777 android_server
以root身份执行android_server
文件,android_server
文件默认监听23946
端口,可以通过-p端口
参数进行设置端口,注意p
和端口之间无空格
$ ./android_server -p23946
二、打开DDMS程序
打开DDMS程序,DDMS程序会将应用的调试端口映射到电脑上,使用jdb命令能够对被挂起的程序恢复执行。
三、进行端口转发
使用adb命令进行端口转发
$ adb forward tcp:23946(PC_port) tcp:23946(Phone_port)
四、以调试模式启动app
我们以debug模式启动程序。程序会出现waiting for debugger的调试界面
$ adb shell am start -D -n com.example.inittest/.MainActivity
Starting: Intent { cmp=com.example.inittest/.MainActivity }
程序会出现waiting for debugger
的调试界面
这时DDMS显示,调试端口在8700
五、用IDA 附加到启动ida并attach这个app的进程。
六、当so加载的时候挂起
我们在debugger setup里勾选 suspend on library load。然后点击继续(按F9键继续)。
七、使用jdb命令恢复程序执行
使用jdb命令恢复程序执行
$ jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
设置未捕获的java.lang.Throwable
设置延迟的未捕获的java.lang.Throwable
正在初始化jdb...
>
这时DDMS中该应用的颜色变为了绿色:
程序加载so,由于之前的设置,程序停在了liner
处
八 确定模块的加载地址,在linker
和libvm.so
中下断点
在android4.4.4_r1
源码中,linker
中 .init
和.init_array
的断点位置为0000274C
,JNI_OnLoad
的断点位置为00050004
我们先查看内存中segment
中linker
加载的位置
按Ctrl
+S
组合键打开内存中的segmets
,知道linker
的内存加载地址4008B000
,那么断点的位置是4008B000
+0000274C
=4008D74C
。
按G
键输入地址4008D74C
进行跳转,将光标移至该处后按P
键进行反汇编,看到了汇编代码,在该处4008D74C
下断点
同理按Ctrl
+S
组合键打开内存中的segmets
,知道libdvm.so
的内存加载地址41503000
,那么断点的位置是41503000
+00050004
=41553004
。
按G
键输入地址41553004
进行跳转,将光标移至该处后按P
键进行反汇编,看到了汇编代码,在该处41553004
下断点
九、继续执行
按F9
键继续执行,发现在第一处断点停了下来
按F7
键步入函数执行,发现其首先进入了_init
函数中,调用了自定义的打印日志函数输入函数名
接着按F8
跨过执行,直到函数返回
接着按F9
键继续执行到下一断点,发现第二次在该断电处停了下来
按F7
键步入函数执行,发现其先进入了.init_array
段的myConstructor1
函数中,调用了自定义的打印日志函数输入函数名
接着按F8
跨过执行,直到函数返回
接着按F9
键继续执行到下一断点,发现第三次在该断电处停了下来
按F7
键步入函数执行,发现其先进入了.init_array
段的myConstructor2
函数中,调用了自定义的打印日志函数输入函数名
接着按F8
跨过执行,直到函数返回
接着按F9
键继续执行到下一断点,发现在libdvm处断点停了下来
按F7
键步入函数执行,发现其先进入了JNI_OnLoad
函数中,调用了自定义的打印日志函数输入函数名