zoukankan      html  css  js  c++  java
  • IDA远程调试Android中so文件

                                    IDA远程调试Android中so文件

    前言:

      使用IDA进行动态调试so,有两种方式进行调试,一种是调试启动方式,调试启动可以调试jni_onload ,init_array 处的代码,可以在较早的时机得到调试权限,一般反调试会在较早的时候进行启动; 而另一种则是附加调试,附加调试是在APP已经运行起来的时候进行附加调试,这两种方式与Windows上的调试启动和附加调试概念很相似;下面我们来进行实践把...

     

    实践环境:Windows 10 IDA Pro 7.0 + Nexus5(4.4.4)

     

    正文:

    第一种调试启动:

     

    1. 以调试的方式启动程序(这样可以在jni_onload ,init_array 处断下来)

    adb shell am start -D -n com.yaotong.crackme/.MainActivity

     

    2. 在IDA的主目录 dbgsrv 目录下 ,找到 android_server拷贝到手机的 data/local/tmp/ 目录下

    adb push android_server的目录) /data/local/tmp

     

    3. 使用chmod修改android_server程序的执行权限并执行:

    adb shell chmod 755 /data/local/tmp/android_server

    执行android_server

    adb shell

    su

    cd data/local/tmp

    ./android_server

     

    4. 新开一个cmd窗口使用forward程序进行端口转发:

    adb forward tcp:23946 tcp:23946 

     

    5. 打开方法调试:

    打开IDA,选择菜单Debugger -> Attach -> Remote ARM Linux/Android debugger

     

    6.  Hostname 填写 127.0.0.1或者locahost (都是一个意思)

    Port 自动填的23946

     
    7. 选择要进行调试的APP
     
    ok 则进入调试界面,注意,这时候还不能进行动态调试...
     

    8. 点击菜单Debugger->Debugger Opitions 在弹出的Debugger setup窗口的Events中选择 Suspend on Process entry和Suspend on thread start/exit 以及 Suspend on library load/unload,再点击OK退出。通过此操作可以设置程序在创建新线程和加载so时自动中断。

     

    通过DDMS获取相应进程的端口号,然后使用jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=XXXX(DDMS查询到的端口号,一般ddms进行转发后的端口都是8700)

     
    如果成功执行jdb -connect DDMS上虫子图标会变成绿色...
     

    连接成功后,在IDA按F9后手机上的“waiting for debugger"提示会自动消失,这个时候应该已经断在新线程,或者加载so处了。

     

    9. 现在就可以在IDA中按下快捷键CTRL + S来查看要调试的so是否已经加载了,如果没有就F9,直到加载了为止;如果已经有了,就记下该so的start位置,然后另开一个ida分析.so库,找到JNI_ONLOAD的偏移地址,那么该JNI_OnLoad函数在进程中的真实地址就是so.start + JNI_OnLoad_Offset。

     

     
     
    0x753030000 + 0x1B9C = 0x75304B9C (JNI_OnLoad在APP进程中的地址)
     

    这里需要说明的是:有可能在快捷键CTRL + S跳出的窗口中有两个同名的so,我们应当选择权限为RX的这个,RX一般是代码段,RW一般是数据段。

     

    10. 得到真实地址后,在IDA中按下快捷键G跳转到这个地址,然后按下快捷键F2就完成在JNI_OnLoad函数入口处下断点了。如果想直接在native函数下断点,那么另开一个IDA 进行静态查看函数地址然后转换成为动态加载起来的地址,接着G到该地址下断点即可


     

    11. 再次按下F9,则在JNI_OnLoad断了下来,接着就可以进行调试等系列操作了...

     
     
    接着我们讲的是第二种,附加方式调试so:
     
    1. 拷贝android_server
    adb push android_server的目录) /data/local/tmp
     
    2. 修改执行权限并执行
    adb shell chmod 755 /data/local/tmp/android_server

    adb shell

    su

    cd data/local/tmp

    ./android_server

     
    4. 转发端口
    adb forward tcp:23946 tcp:23946
     
    5. 启动android_server
        这里我发现一个小问题,就是退出调试以后再次调试,android_server没有close,按道理是可以再一次连接的,但是我这里则是无法进行再次连接调试,所以需要重新启动一下android_server
    如下:(14061是pid)
    root@android:/ # ps | grep android_server
    root 14061 13574 11180 9504 ffffffff 40183da0 S /data/local/tmp/android_server 
    root@android:/ # kill -s 9 14061 
     

    6打开IDA,选择菜单Debugger -> Attach -> Remote ARM Linux/Android debugger

     

    Hostname 填写 127.0.0.1或者locahost (都是一个意思)

    Port 自动填的23946


    选择要进行调试的APP
     
    得到进程中地址后,在IDA中按下快捷键G跳转到这个地址,然后按下快捷键F2就完成在JNI_OnLoad函数入口处下断点了。如果想直接在native函数下断点,那么另开一个IDA 进行静态查看函数地址然后转换成为动态加载起来的地址,接着G到该地址下断点即可:
     
    运行程序指定功能,触发断点,接着就可以到达该函数进行调试了,嘿嘿...
     

     
     
  • 相关阅读:
    C++STL之vector用法总结
    [ZOJ 4016] Mergable Stack
    [ZOJ 4024] Peak
    关于C++中ios::sync_with_stdio(false)
    [CodeForces 567C] Geometric Progression
    [CodeForce 450A] Jzzhu and Children
    c++的动态绑定和静态绑定及多态的实现原理(摘)
    C++创建对象的3种方式(转载)
    C++虚函数与纯虚函数用法与区别
    C++深入理解虚函数
  • 原文地址:https://www.cnblogs.com/ddms/p/8820044.html
Copyright © 2011-2022 走看看