How to debug Dalvik and ARM code together

转: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:

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

  2. 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
    
  3. change the default port in “Debugger/Process options” to any other value.

  4. start the Dalvik debugger and wait until breakpoint is hit.

Then prepare the second IDA instance:

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

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

  3. 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
    
  4. select “Remote ARM Linux/Android debugger” and attach to the application process.

  5. 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.

dalvik_blog_pict2

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.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值