使用IDA Pro调试Android原生程序一般有远程运行与远程附加两种方式,远程运行调试用来调试原生可执行程序,远程附加调试用来调试Android原生动态链接库。
1. 调试原生可执行程序
过程:
(1).将本次实验的原生可执行程序实例test复制到Android设备或者模拟器中,我们的实验以目录data/local/tmp为例,同时将IDA Pro软件目录的android_server也复制到同一目录data/local/tmp中。
复制如下:
adb push E:\eclipse\eclipseworkspace\JNI\libs\armeabi-v7a\test (原生可执行程序位置) /data/local/tmp
adb push F:\ida\dbgsrv\android_server(IDA Pro软件目录下的android_server) /data/local/tmp
执行完后可以查看一下是否复制成功:
给两个文件加上可执行权限
adb shell chmod 755 /data/local/tmp/test
adb shell chmod 755 /data/local/tmp/android_server
接着执行“/data/local/tmp/android_server”,启动IDA Pro的Android调试服务器,如下图所示
调试服务器已经启动,并且监听了23946号端口
打开另一个命令行进行端口转发:
adb forward tcp:23946 tcp:23946
执行后,启动IDA Pro,点击菜单栏“Debugger->Run->Remote AmLinux/Android debugger”,打开调试程序对话框。在Application栏输入“/data/local/tmp/test”,在Directory栏输入“/data/local/tmp”,在Hostname栏输入“localhost”或者“127.0.0.1”,如下图所示
设置完成后点击OK按钮,IDA Pro就会远程执行test,并自动切换到调试界面,如下图所示。
此时我们就可以对原生可执行程序进行调试。
2. 调试原生动态链接库
(1). 编写实例程序JavaCTest,界面如右图所示。点击“Change Text”按钮后,程序会调用动态链接库libjavac.so库中的stringFromJNI()方法返回一个字符串“Java C Test!”,并且更改字符串“Hello Xidain!”为此字符串。源代码附下:
package com.example.javactest;
import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
public native String stringFromJNI();
public native String unimplementedStringFromJNI();
static
{
System.loadLibrary("javac");
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Button button1=(Button)findViewById(R.id.button1);
button1.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
TextView tv=(TextView) findViewById(R.id.tv);
tv.setText(stringFromJNI());
}
});
}
(2)}执行命令:adb shell /data/local/tmp/android_server
adb forward tcp:23946 tcp:23946
(3)在虚拟机中打开javactest.apk
(4)启动IDA Pro,点击菜单项“Debugger→Attach→Remote ARMLinux/Android debugger”,打开调试程序设置对话框。在HostName栏中输入localhost,如下图所示。
(5)选择com.example.javactest进程,点击OK按钮,然后IDA会进入调试器界面。
(6)此时,代码没有运行在动态链接库部分,要想调试动态链接库就得为动态链接库中的函数设置断点。将JavaCTest.apk解压,找到libjavac.so文件,开启另一个IDA实例并载入它,找到stringFromJNI()方法的代码如下图所示
(7)从上图反汇编的代码中可以看出stringFromJNI()方法的代码起始处位于0xEF8,回到IDA调试窗口,按下“Ctrl+S”快捷键打开段选择对话框,查找libjavac.so动态链接库的基地址,此处的基地址为0x48CA3000,如下图所示。
(8)内存地址等于基地址加上偏移地址,由此可以计算出stringFromJNI()方法的内存地址为0x48CA3EF8。关闭段选择对话框,按下快捷键G,打开地址跳转对话框,在“Jump address”栏中输入0x48CA3EF8,如下图所示。点击OK按钮,程序会跳转到stringFromJNI()方法所在的代码行,并自动分析出了方法的代码。在0x5447AC34行按下快捷键F2设置一个断点,被设置断点的代码行会被红色标记,如下图所示。
(9)设置好断点后,回到程序中点击“Change Text”按钮,程序就会中断在0x5447AC34行上,接下来就可以调试动态链接库中的原生程序了。
(10)实验结束。
出错问题: