您的位置:首页 > 其它

How to debug Dalvik and ARM code together

2014-11-05 16:16 483 查看
转:http://www.hexblog.com/?p=809

Let us have a look at application that uses a native library. On a button press, the function
stringFromJNI()
implemented in the native library is called.

package ida.debug.hellojni;
public class MainActivity extends Activity {
public native String stringFromJNI();
static {
System.loadLibrary("hello-jni");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
final TextView tv = new TextView(this);
final Button btn = new Button(this);
btn.setText("Press me to call the native code");
btn.setOnClickListener(new Button.OnClickListener() {
public void onClick(View v) {
tv.setText(stringFromJNI());
}
});
LinearLayout layout = new LinearLayout(this);
layout.setOrientation(LinearLayout.VERTICAL);
layout.setLayoutParams(new LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
layout.addView(btn);
layout.addView(tv);
setContentView(layout);
}
}

Native library function returns a well-known string.

jstring Java_ida_debug_hellojni_MainActivity_stringFromJNI(
JNIEnv* env,
jobject thiz)
{
return (*env)->NewStringUTF(env, "Hello, JNI world!");
}

So, we have application packaged in
hellojni.apk
file and installed in Android Emulator.

Because IDA cannot analyse or debug both Dalvik and native (ARM) code at the same time, we’ll need to use two IDA instances to perform debugging in turns.

To prepare the first IDA instance:

load
hellojni.apk
into IDA, select
classes.dex
to analyze.

go to the native function call and set breakpoint there.

CODE:0000051C  iget-object         v0, this, MainActivity$1_val$tv
CODE:00000520  iget-object         v1, this, MainActivity$1_this$0
CODE:00000524  invoke-virtual      {v1},
<ref MainActivity.stringFromJNI() imp. @ _def_MainActivity_stringFromJNI@L>
CODE:0000052A  move-result-object  v1


change the default port in “Debugger/Process options” to any other value.

start the Dalvik debugger and wait until breakpoint is hit.

Then prepare the second IDA instance:

prepare to debug native ARM Android application (copy and start
android_server
and so on).

load
hellojni.apk
into IDA, and now select
lib/armeabi-v7a/libhello-jni.so
to analyze.

the name of the native function was formed by special rules and in our case it is
Java_ida_debug_hellojni_MainActivity_stringFromJNI()
, so go to to it and set a breakpoint:

.text:00000BC4 EXPORT Java_ida_debug_hellojni_MainActivity_stringFromJNI
.text:00000BC4 Java_ida_debug_hellojni_MainActivity_stringFromJNI
.text:00000BC4
.text:00000BC4 var_C  = -0xC
.text:00000BC4 var_8  = -8
.text:00000BC4
.text:00000BC4        STMFD   SP!, {R11,LR}
.text:00000BC8        ADD     R11, SP, #4
.text:00000BCC        SUB     SP, SP, #8
.text:00000BD0        STR     R0, [R11,#var_8]
.text:00000BD4        STR     R1, [R11,#var_C]
.text:00000BD8        LDR     R3, [R11,#var_8]
.text:00000BDC        LDR     R3, [R3]
.text:00000BE0        LDR     R2, [R3,#0x29C]
.text:00000BE4        LDR     R0, [R11,#var_8]
.text:00000BE8        LDR     R3, =(aHelloJniWorld - 0xBF4)
.text:00000BEC        ADD     R3, PC, R3 ; "Hello, JNI world!"
.text:00000BF0        MOV     R1, R3
.text:00000BF4        BLX     R2
.text:00000BF8        MOV     R3, R0
.text:00000BFC        MOV     R0, R3
.text:00000C00        SUB     SP, R11, #4
.text:00000C04        LDMFD   SP!, {R11,PC}
.text:00000C04 ; End of function
Java_ida_debug_hellojni_MainActivity_stringFromJNI


select “Remote ARM Linux/Android debugger” and attach to the application process.

press
F9
to continue.

Now switch to the first IDA session and press, for example, F8 to call native function. If we return back to the second IDA session then we can notice the breakpoint event.





Now we can continue to debug the native code. When we finish, press
F9
and return to the first IDA session.

The full source code of the example you can download from our
site.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: