使用IDA调试Android原生程序
2018-01-10 22:10
274 查看
今天已是国庆的第五天,白天去武馆训练过后,晚上回来品一杯西湖龙井,更一篇博客,一来帮助需要之人,二来加深自己的理解。
下面就说关于在IDA中Android so的动态调试的问题以及在so的三个层次下断点的操作。
问题篇:
1.动态调试的作用以及与我们常说的脱壳区别之处?
2.IDA的下断点调试的原理?
3.有无反调试的步骤区别?以及原理?
4.反调试与反附加的区别?
5.IDA动态调试so时有哪三个层次?以及如何下断点?
注意:so的动态调试与脱壳在步骤上有很多的相似之处,关于脱壳在后面会详细介绍加壳以及脱壳的发展历程。
解答原理篇:
第一个问题:
曰:动态调试作用有二:
其一:dump内存,即:找准时机dump出解密后的正确文件;
其二:查看每一步状态,进一步分析出正确的逻辑;
脱壳只是我们在调试系统级别的.so文件后 ,找准时机dump出正确而真实的.so文件,而动态调试只不过是手动脱壳的一种表现方式。
第二个问题:
曰:(由于师哥说面试时喜欢问,此处列出来)
下断点原理:
由于下断点有硬件断点和软件断点,我们在这里只说IDA中的软件断点原理:
X86系列处理器提供了一条专门用来支持调试的指令,即INT 3,这条指令的目的就是使CPU中断(break)到调试器,以供调试者对执行现场进行各种分析。
当我们在IDA中对代码的某一行设置断点时,即:F2,调试器会先把这里的本来指令的第一个字节保存起来,然后写入一条INT 3指令,因为INT 3指令的机器码为11001100b(0xCC)当运行到这的时候CPU会捕获一条异常,转去处理异常,CPU会保留上上下文环境,然后中断到调试器,大多数调试器的做法是在被调试程序中断到调试器时,会先将所有断点位置被替换为INT 3的指令恢复成原来的指令,然后再把控制权交给用户。这样我们就可以愉快的开始调试了。如下图所示也是写调试器的原理图:
![](https://img-blog.csdn.net/20161005205539869?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
第三个问题:
曰:先说无反调试:
1.adb push d:\android_server(IDA的dbgsrv目录下) /data/local/tmp/android_server(这个目录其实可以随便放,有的反调试会检测这)
2.adb shell
3.su(一定要有root权限)
4.cd /data/local/tmp
5.chmod 777 android_server(执行权限要给)
6.再开一个cmd
adb forward tcp:23946 tcp:23946(端口转发,调试手机上的某个进程要有协议支持通信)
7.打开待调试的应用程序,就可以愉快的调试了
再来说有反调试:
曰:在很多情况下我们遇到的是有反调试并且用上面的步骤,附加进去以后直接就退出了,这样的例子数不胜数,那就是反调试惹的货。
这时候我们就要改变调试战略了
在上文的基础上:
1.启动android_server;
2.端口转发adb forward tcp:23946 tcp:23946;
3.adb shell am start -D -n 包名/类名;
(说明:以启动模式启动,是停在加载so文件之前,报名在AndroidMainfest文件中可以找到)
4.打开IDA,附加上对应的进程之后,设置IDA中的load so的时机,在debug options中设置一下,后面会有实战部分;
5.adb forward tcp:8700 jdwp:进程号;(jdwp是后面jdb调试器的协议,转换到待调试的指定的应用程序);
6.jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700(jdb进行附加);
7.可以愉快的下断点,开始调试了;
第四个问题:
曰:反调试就是阻止你进行动态调试所采用的一种手段,在下一篇中会进行具体的讲解反调试的手段,以及解决反调试的办法。
反附加,在这块重要的是说jdb的反附加,很多情况下jdb会附加不上,就是会出现“无法附加到目标的VM”这样的问题那是因为在每个应用程序下,有这个android:debuggable="true"才能调试,因为篇幅问题,照样会在下一篇中会针对反附加寻找目前所有解决办法。
第五个问题:
曰:我们知道在so的加载时候有个这个过程:
.init->->.init array->->JNI_Onload->->java_com_XXX;
还有我们在脱壳的过程中会在一些系统级的.so中下断点比如:fopen,fget,dvmdexfileopen,等等
而.init以及.init_array一般会作为壳的入口地方,那我们索性叫它外壳级的.so文件
这里归纳为三类:
应用级别的:java_com_XXX;
外壳级别的:JNI_Onload,.init,.init_array;
系统级别的:fopen,fget,dvmdexfileopen;
对于在应用级别的和系统级别的就不说了比较简单容易理解,这里也是在实现篇中会重点说的,看到上面的.so的加载执行过程我们知道如果说反调试放在外壳级别的.so文件的话我们就会遇程序在应用级核心函数一下断点就退出的尴尬,事实上多数的反调试会放在这,那么过反调试就必须要在这些地方下断点,那么我们就重点的说如何在.init_array和JNI_Onload处理下断点。
实现篇:
这里我们会拿阿里有一年的比赛样本,会放在附件中。
在JNI_Onload处下断点方法一:(双开定位)
1.启动android_server;
2.端口转发以及调试模式启动:如图所示:
![](https://img-blog.csdn.net/20161006102410075?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
3.打开IDA,设置
![](https://img-blog.csdn.net/20161006102711404?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
4.附加上对应的进程进去之后如图:
![](https://img-blog.csdn.net/20161006102927270?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
5.这一步很重要在Debugger option下面选择这三个选项(让在load so的每个接口处停下来)
![](https://img-blog.csdn.net/20161006103057741?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
6.jdwp协议端口转发
![](https://img-blog.csdn.net/20161006103655549?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
7.jdb附加
![](https://img-blog.csdn.net/20161006103939472?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
8.F9执行,忽略提示框;这时候运行到linker处,如图:
![](https://img-blog.csdn.net/20161006104233148?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
9.这时候找JNI_Onload的绝对地址:
基地址+相对地址;
基地址为:ctrl+s显示为:
![](https://img-blog.csdn.net/20161006104642795?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
相对地址,用IDA静态分析libcrack.so可得到相对地止:
![](https://img-blog.csdn.net/20161006104847829?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
绝对地址为:4151E000+1B9C=4151FB9C
按下“G”键输入4151FB9C
如图所示:按下F2下好断点,再按F9执行到断点处就可以愉快的调试了
![](https://img-blog.csdn.net/20161006105104723?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
在JNI_Onload处下断点方法二:(简单好用)
1.首先把要分析的libcrackme.so文件拉进IDA里面在要下断点的JNI_Onload处下好断点如图所示:
![](https://img-blog.csdn.net/20161006111825395?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
2.启动android_server与上面一样;
3.端口转发以及调试模式启动:如图所示
![](https://img-blog.csdn.net/20161006102410075?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
4.先设置一下Debugger 如图所示
![](https://img-blog.csdn.net/20161006112617461?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
5.IDA进行附加进程回到之前静态分析libcrackme.so的IDA界面单击Debugger -> Process options 配置调试信息,这里只需配置hostname为localhost,其余的保持默认设置即可
![](https://img-blog.csdn.net/20161006112736962?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
6.单击Debugger -> Attach to process进行附加进程
![](https://img-blog.csdn.net/20161006112914071?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
7.jdwp转发(当然打开DDMS就不需要这一步了)jdb附加
![](https://img-blog.csdn.net/20161006113723240?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
8.F9执行一路取消就OK,得到如图所示:
![](https://img-blog.csdn.net/20161006113948515?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
是不是很简单??
在.iniy_array处下断点(与上面方法二雷同)
得到的结果是:
![](https://img-blog.csdn.net/20161006114658049?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
OK,搞定
在JNI_Onload处下断点方法三:(适合于脱壳的时候)
1.可以根据看源码,对应不同版本的系统源码就会发现一点,如下在vm/Native.cpp路径下:
![](https://img-blog.csdn.net/20170525095503454?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVpYmFiZWliZWlfYmVpYmVp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
2.我们逆向去看,首先把系统中的libdvm.so a db pull出来,拉到IDA中去分析;
找到JNI_Onload处进行分析:F5可以看到,首先V20进行“JNI_Onload”符号查找,同时在V23有对V20的调用,
![](https://img-blog.csdn.net/20170525094128622?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVpYmFiZWliZWlfYmVpYmVp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
回到ARM指令处可以看到如下:
![](https://img-blog.csdn.net/20170525094442439?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvZmVpYmFiZWliZWlfYmVpYmVp/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
0x50008就是偏移处,这个时候我们就开始下断:
加载上要调试的APK以后,找到libdvm.so的基址,然后加上50008,下断点。如果看不到汇编,那就P一下,下断点,这个比较适合于脱壳的时候。
附件:点击打开链接
----------------------
9.png (30.63
KB, 下载次数: 13)
![](https://attach.52pojie.cn/forum/201611/14/225746oewfjme3ft3km34m.png)
10.png (69.44
KB, 下载次数: 11)
![](https://attach.52pojie.cn/forum/201611/14/225746bwf7mpr5evrjwf5w.png)
转自:http://blog.csdn.net/feibabeibei_beibei/article/details/52740212
下面就说关于在IDA中Android so的动态调试的问题以及在so的三个层次下断点的操作。
问题篇:
1.动态调试的作用以及与我们常说的脱壳区别之处?
2.IDA的下断点调试的原理?
3.有无反调试的步骤区别?以及原理?
4.反调试与反附加的区别?
5.IDA动态调试so时有哪三个层次?以及如何下断点?
注意:so的动态调试与脱壳在步骤上有很多的相似之处,关于脱壳在后面会详细介绍加壳以及脱壳的发展历程。
解答原理篇:
第一个问题:
曰:动态调试作用有二:
其一:dump内存,即:找准时机dump出解密后的正确文件;
其二:查看每一步状态,进一步分析出正确的逻辑;
脱壳只是我们在调试系统级别的.so文件后 ,找准时机dump出正确而真实的.so文件,而动态调试只不过是手动脱壳的一种表现方式。
第二个问题:
曰:(由于师哥说面试时喜欢问,此处列出来)
下断点原理:
由于下断点有硬件断点和软件断点,我们在这里只说IDA中的软件断点原理:
X86系列处理器提供了一条专门用来支持调试的指令,即INT 3,这条指令的目的就是使CPU中断(break)到调试器,以供调试者对执行现场进行各种分析。
当我们在IDA中对代码的某一行设置断点时,即:F2,调试器会先把这里的本来指令的第一个字节保存起来,然后写入一条INT 3指令,因为INT 3指令的机器码为11001100b(0xCC)当运行到这的时候CPU会捕获一条异常,转去处理异常,CPU会保留上上下文环境,然后中断到调试器,大多数调试器的做法是在被调试程序中断到调试器时,会先将所有断点位置被替换为INT 3的指令恢复成原来的指令,然后再把控制权交给用户。这样我们就可以愉快的开始调试了。如下图所示也是写调试器的原理图:
第三个问题:
曰:先说无反调试:
1.adb push d:\android_server(IDA的dbgsrv目录下) /data/local/tmp/android_server(这个目录其实可以随便放,有的反调试会检测这)
2.adb shell
3.su(一定要有root权限)
4.cd /data/local/tmp
5.chmod 777 android_server(执行权限要给)
6.再开一个cmd
adb forward tcp:23946 tcp:23946(端口转发,调试手机上的某个进程要有协议支持通信)
7.打开待调试的应用程序,就可以愉快的调试了
再来说有反调试:
曰:在很多情况下我们遇到的是有反调试并且用上面的步骤,附加进去以后直接就退出了,这样的例子数不胜数,那就是反调试惹的货。
这时候我们就要改变调试战略了
在上文的基础上:
1.启动android_server;
2.端口转发adb forward tcp:23946 tcp:23946;
3.adb shell am start -D -n 包名/类名;
(说明:以启动模式启动,是停在加载so文件之前,报名在AndroidMainfest文件中可以找到)
4.打开IDA,附加上对应的进程之后,设置IDA中的load so的时机,在debug options中设置一下,后面会有实战部分;
5.adb forward tcp:8700 jdwp:进程号;(jdwp是后面jdb调试器的协议,转换到待调试的指定的应用程序);
6.jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=8700(jdb进行附加);
7.可以愉快的下断点,开始调试了;
第四个问题:
曰:反调试就是阻止你进行动态调试所采用的一种手段,在下一篇中会进行具体的讲解反调试的手段,以及解决反调试的办法。
反附加,在这块重要的是说jdb的反附加,很多情况下jdb会附加不上,就是会出现“无法附加到目标的VM”这样的问题那是因为在每个应用程序下,有这个android:debuggable="true"才能调试,因为篇幅问题,照样会在下一篇中会针对反附加寻找目前所有解决办法。
第五个问题:
曰:我们知道在so的加载时候有个这个过程:
.init->->.init array->->JNI_Onload->->java_com_XXX;
还有我们在脱壳的过程中会在一些系统级的.so中下断点比如:fopen,fget,dvmdexfileopen,等等
而.init以及.init_array一般会作为壳的入口地方,那我们索性叫它外壳级的.so文件
这里归纳为三类:
应用级别的:java_com_XXX;
外壳级别的:JNI_Onload,.init,.init_array;
系统级别的:fopen,fget,dvmdexfileopen;
对于在应用级别的和系统级别的就不说了比较简单容易理解,这里也是在实现篇中会重点说的,看到上面的.so的加载执行过程我们知道如果说反调试放在外壳级别的.so文件的话我们就会遇程序在应用级核心函数一下断点就退出的尴尬,事实上多数的反调试会放在这,那么过反调试就必须要在这些地方下断点,那么我们就重点的说如何在.init_array和JNI_Onload处理下断点。
实现篇:
这里我们会拿阿里有一年的比赛样本,会放在附件中。
在JNI_Onload处下断点方法一:(双开定位)
1.启动android_server;
2.端口转发以及调试模式启动:如图所示:
3.打开IDA,设置
4.附加上对应的进程进去之后如图:
5.这一步很重要在Debugger option下面选择这三个选项(让在load so的每个接口处停下来)
6.jdwp协议端口转发
7.jdb附加
8.F9执行,忽略提示框;这时候运行到linker处,如图:
9.这时候找JNI_Onload的绝对地址:
基地址+相对地址;
基地址为:ctrl+s显示为:
相对地址,用IDA静态分析libcrack.so可得到相对地止:
绝对地址为:4151E000+1B9C=4151FB9C
按下“G”键输入4151FB9C
如图所示:按下F2下好断点,再按F9执行到断点处就可以愉快的调试了
在JNI_Onload处下断点方法二:(简单好用)
1.首先把要分析的libcrackme.so文件拉进IDA里面在要下断点的JNI_Onload处下好断点如图所示:
2.启动android_server与上面一样;
3.端口转发以及调试模式启动:如图所示
4.先设置一下Debugger 如图所示
5.IDA进行附加进程回到之前静态分析libcrackme.so的IDA界面单击Debugger -> Process options 配置调试信息,这里只需配置hostname为localhost,其余的保持默认设置即可
6.单击Debugger -> Attach to process进行附加进程
7.jdwp转发(当然打开DDMS就不需要这一步了)jdb附加
8.F9执行一路取消就OK,得到如图所示:
是不是很简单??
在.iniy_array处下断点(与上面方法二雷同)
得到的结果是:
OK,搞定
在JNI_Onload处下断点方法三:(适合于脱壳的时候)
1.可以根据看源码,对应不同版本的系统源码就会发现一点,如下在vm/Native.cpp路径下:
2.我们逆向去看,首先把系统中的libdvm.so a db pull出来,拉到IDA中去分析;
找到JNI_Onload处进行分析:F5可以看到,首先V20进行“JNI_Onload”符号查找,同时在V23有对V20的调用,
回到ARM指令处可以看到如下:
0x50008就是偏移处,这个时候我们就开始下断:
加载上要调试的APK以后,找到libdvm.so的基址,然后加上50008,下断点。如果看不到汇编,那就P一下,下断点,这个比较适合于脱壳的时候。
附件:点击打开链接
----------------------
[align=left]1.动态调试一般的Android原生程序[/align] [align=left]实例程序:debugnativeapp[/align] [align=left]①在Android设备中添加、配置android_server程序[/align] [align=left]先将IDA目录下的./dbgsrv/android_server程序拷贝到Android设备下:[/align] [align=left]adb push[IDA]/dbgsrv/android_server /data/local/tmp/[/align] [align=left]配置文件权限属性,使其为可执行文件:[/align] [align=left]adb shell chmod 755/data/local/tmp/android_server[/align] [align=left][/align] [align=left]②将实例程序添加到Android设备[/align] [align=left]adb push debugnativeapp/data/local/tmp/[/align] [align=left]adb shell chmod 755/data/local/tmp/debugnativeapp[/align] [align=left][/align] [align=left]③启动调试服务[/align] [align=left]adb shell/data/local/tmp/android_server[/align] ![]() [align=left][/align] [align=left]④进行端口转发,使PC端口与Android端口可进行交互[/align] [align=left]adb forward tcp:23946tcp:23946[/align] [align=left][/align] [align=left]⑤启动IDA,进行程序调试[/align] [align=left]启动IDA的32bit程序,点击:Debugger-Run-RemoteArmLinux/Android debugger,打开调试程序的设置对话框:[/align] [align=left]Application:对应调试程序所在的路径[/align] [align=left]Directory:对应调试程序所在的目录路径[/align] [align=left]HostName:输入localhost,Port:PC端口[/align] ![]() [align=left]点击OK,IDA便可进入调试界面:[/align] ![]() [align=left]IDA动态调试的小技巧[/align] [align=left]①调试快捷键:[/align] [align=left]F2设置断点,F4运行到鼠标位置,F7单步步入,F8单步步过,F9运行程序[/align] [align=left]F5/Tab 将相应的简单汇编代表粗略转换为C/C++代码[/align] [align=left][/align] [align=left]②将IDA误识别的代码手动转为ARM汇编代码[/align] [align=left]如下图,程序在Thumb状态执行BX PC,PC最后一位为0,应是跳转到ARM状态,但应IDA仍误识别为16位的Thumb,所以不是正常的程序。[/align] ![]() [align=left]如果按快捷键C来直接强制转换,将不成功。应先通过Edit-Segment-Change segment register value(Alt+G),将Value改为0x00,这时程序会变为下边CODE32的编码方式,但仍非正常转换[/align] ![]() [align=left]再按下U,转为未定义[/align] ![]() [align=left]最后通过快捷键C,来转换便可成功。如是ARM转为Thumb状态,则相似(将Value改为0x01)[/align] ![]() [align=left][/align] [align=left]③修改二进制码并保存修改程序[/align] [align=left]修改:Edit-PatchProgram-Change byte[/align] [align=left]保存:Edit-PatchProgram-Apply patches to input file[/align] [align=left][/align] [align=left]2.调试Android原生动态链接库[/align] [align=left]实例:debugjniso.apk[/align] ①将apk安装在设备中,运行后界面如下,点击“设置标题”按钮,便会调用动态链接库libdebugjniso.so中的jniString()方法返回一个修改标题栏的字符串。在分析加壳程序的壳时,应以调试方式来启动调试程序(adb shell am start-D -n packagename/activityname) ![]() [align=left][/align] [align=left]②启动调试服务,进行端口转发[/align] [align=left]adb shell/data/local/tmp/android_server[/align] [align=left]adb forward tcp:23946tcp:23946[/align] [align=left][/align] [align=left]③启动IDA进行程序调试[/align] [align=left]点击Debugger-Attach-RemoteArmLinux/Android debugger,打开设置框[/align] [align=left]HostName:输入localhost,Port:对应PC端口[/align] ![]() [align=left]点击OK,便会弹出附加Android进程的对话框,选中进程com.droider.debugjniso[/align] ![]() [align=left] [/align] [align=left]④使用jdb来连接上apk的java层[/align] [align=left]jdb -connectcom.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8601[/align] [align=left]程序所对应的端口可通过eclipse中的devices窗口查看,执行上边jdb的命令后,便会在连接上的程序前显示绿色昆虫[/align] [align=left] [/align] [align=left]⑤确定jniString()方法的偏移地址[/align] [align=left]从apk中取出动态链接库文件,并在另启的IDA实例上加载,在反汇编代码中定位方法的程序位置,由下图可知,jniString()方法在相应段中的偏移地址为:0xC38(一般固定不变)[/align] ![]() [align=left][/align] [align=left]⑥确定jniString()方法当前的基地址[/align] [align=left]回到调试的IDA,使用Ctrl+S快捷键打开段选择对话框,可查找到libdebugjniso.so当前的基地址为:4B1F2000(随加载改变)[/align] ![]() [align=left][/align] [align=left]⑦定位到jniString()方法的程序位置[/align] [align=left]由内存地址=基地址+偏移地址(4b1f2000:00000c38),可得当前jniString()方法的内存地址为:0x4b1f2c38,使用快捷键G打开地址跳转框,输入内存地址[/align] ![]() [align=left]⑧设定断点,进行调试[/align] [align=left]跳转在jniString()方法的程序位置,在0x4b1f2c38行设置断点(F2)[/align] ![]() [align=left]点击工作栏上的绿色箭头(F9)让程序运行起来,然后按下Android上的“设置标题”按钮,程序会中断在0x4b1f2c38行,便可进行相应调试。如按F9执行程序,标题修改结果如下:[/align] ![]() [align=left]3.另一种调试动态链接库的方法(无需用到jdb)[/align] [align=left]①先使用IDA来加载libdebugjniso.so,定位到jniString()方法的程序位置,并在程序开始处设置下断点[/align] [align=left][/align] [align=left]②点击Debugger-Processoptions,将HostName设置为localhost,然后点击Debugger-Attach to Process,弹出附加Android进程的对话框,选中进程com.droider.debugjniso[/align] [align=left][/align] [align=left]③加载进程后,便会弹出警告框,询问两个文件是否相同,选择same[/align] ![]() [align=left]④点击Debugger-Breakpoints-Breakpointlist查看断点列表,可发现原先设置的断点在加载动态库后仍然存在,且定位到相应的内存地址[/align] ![]() [align=left]⑤进入断点位置,点击工作栏上的绿色箭头(F9)让程序运行起来,然后按下Android上的“设置标题”按钮,程序会中断在0x4b1f2c38行,便可进行相应调试。[/align] |
KB, 下载次数: 13)
![](https://attach.52pojie.cn/forum/201611/14/225746oewfjme3ft3km34m.png)
10.png (69.44
KB, 下载次数: 11)
![](https://attach.52pojie.cn/forum/201611/14/225746bwf7mpr5evrjwf5w.png)
转自:http://blog.csdn.net/feibabeibei_beibei/article/details/52740212
相关文章推荐
- 使用IDA调试android下的linux程序
- android调试系列--使用ida pro调试原生程序
- 使用gdb调试android原生程序
- 使用IDA调试android下的linux程序
- android中使用gdbserver调试c程序
- android 学习笔记(五) 调试相关 5.1 android使用wifi进行程序调试
- linux 下使用魅族mx真机调试android程序
- android通过USB使用真机调试程序
- 使用logwrapper调试Android程序
- 如何使用arm-eabi-gdb调试android c/c++程序
- 谈使用Eclipse与DDMS调试Android程序的方法
- android通过USB使用真机调试程序
- ubuntu 使用KindleFire调试Android程序
- 直接使用android通过USB使用真机调试程序
- Android 软件开发之如何使用Eclipse Debug调试程序详解
- Android 软件开发之如何使用Eclipse Debug调试程序详解
- Android开发:一分钟学会使用Logcat调试程序
- 如何使用arm-eabi-gdb调试android c/c++程序
- Android 软件开发之如何使用Eclipse Debug调试程序详解(十二)
- android通过USB使用真机调试程序