zoukankan      html  css  js  c++  java
  • 动态调试Android程序

    最近好几天来一直在看动态调试。首先是这一篇(http://www.52pojie.cn/forum.php?mod=viewthread&tid=293648)里面介绍了多种IDA动态调试的情形,比如调试JNICALL,调试JNI_Onload等等。步骤大概都是这样:

    执行android_server
    端口转发 adb forward tcp:23946 tcp:23946
    调试模式启动程序 adb shell am start -D -n 包名/类名
    IDA附加
    静态找到目标函数对应所在模块的偏移地址
    Ctrl+S找到对应模块的基地址,两个地址相加得到最终地址
    G跳转至地址,然后下断
    F9运行
    执行jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700
    断下,进行调试。

    但我一直不太懂,接下来说的「进行调试」是干什么。

    后来又看了http://1.xbalien.sinaapp.com/?p=342这篇,assest目录下存在两个jar包,分析说可能是dex加密保存在了这里。执行真正代码的时候会进行解密那就可以直接dump出明文dex了。(修复结构反调试在这题并不考虑)

    文中介绍了两种初级dump的方法,第一种是gcoredump。第二种是通过在dvmDexFileOpenPartial断点dump。

    关于dvmDexFileOpenPartial:

    int dvmDexFileOpenPartial(const void* addr, int len, DvmDex** ppDvmDex);

    第一个参数就是dex内存起始地址,第二个参数就是dex大小。所以在这个函数下断点可以直接dump出明文dex。


    我脑补一下原理,大概就是说它解密完了之后在内存里打开这个明文dex,然后我们要拿到它的这两个参数,就可以保存成解密后的dex了!(还是不太明白它的适用性

    用这种方法调试的步骤跟前面列出的步骤基本一致,过程中遇到很多问题,首当其冲是输入jdb -connect com.sun.jdi.SocketAttach:hostname=127.0.0.1,port=8700的时候,提示「致命错误,无法附加到指定VM」。我看到很多人都没有用到这个jdb指令,也不知道这个指令到底什么时候用。后来看到一些文章他们没用这个命令,而且不用算地址。比如:http://blog.sina.com.cn/s/blog_92b6d74d0102uyds.html#cmt_3043762

    我提问:

    请问你是怎么在G中填写dvmDexFileOpenPartial就跳转到dvmDexFileOpenPartial函数的?是不是应该先在libdvm.so中找到dvmDexFileOpenPartial函数的偏移地址,再用偏移地址加上调试程序的libdvm.so的基址,再用G跳转,下断吗?

    人家说他用的是正版IDA6.6。我用的是IDA6.5。

    操作jni_onload是成功了,但我仍不知道下面该怎么调试。因为jni_onload里面保存了一些信息所以也去dump出来?可那个不是dex吧。

    为什么无法附加指定VM,我还是觉得自己的地址算错了,因为在调试Jni_Onload的时候,jdb就成功attach了,这里却不行。但是,我分别用了2.3(Ray),4.0.4(Ray),4.2.2(Nexus 4)和4.4.4(L36h)的不同的libdvm.so测试,皆不行。回想调试Jni_Onload的时候,跟这个的区别是1.开了Eclipse,2.先F9+JDB 再下的断点。等会儿再试试。

    刚才试了一下,这次我像调试jni_onload一样,步骤是F9 ——JDB命令(成功attach后程序中断)——G到目标地址下断点——再按一次F9触发断点,断在了下的那个断点的地方。这时候之前下断点的地方呈现出libdvm.so中那个方法调用的地方一样的汇编代码,为什么之前同样的地址什么都没有呢。但是,这时候对应R0的地址是0,显然是错误的。

    而帖子中的顺序是:下断点,F9,JDB(附加后程序会中断)。

    还有个疑点,出现了这个:

    destination可以指定就算了,source竟然也可以指定。。醉了。暂时不弄了。感觉好蠢,纠结于各个IDA各个版本和android各个版本的细微差别之间,试图将所有的耦合全部尝试一遍,却仍然拿不到想要的东西。百度上没有任何相关的资料。

    好的,我假装自己已经定位到那个dex的起始位置了,下面开始dump:

    {
        auto fp, dex_addr, end_addr;
        fp = fopen("F:\dump.dex", "wb");
        end_addr = r0 + r1;
        for ( dex_addr = r0; dex_addr < end_addr; dex_addr ++ )
            fputc(Byte(dex_addr), fp);
    }

    下面用smailview看dex。对于:http://1.xbalien.sinaapp.com/?p=342这道题,后面要学一下webview。

    ---------------------------------------

    adb  forward  tcp:<本地机器的端口号>  tcp:<模拟器或是真机的端口号>

    例:adb [-d|-e|-s <serialNumber>] forward tcp:6100 tcp:7100 表示把本机的6100端口号与模拟器的7100端口建立起相关,

    当模拟器或真机向自己的7100端口发送了数据,那们我们可以在本机的6100端口读取其发送的内容,这是一个很关键的命令,

    以后我们使用jdb调式apk之前,就要用它先把目标进程和本地端口建立起关联。

    jdb是一个支持java代码级调试的工具,它是由java jdk提供的,存在于xxxJavajdk1.6.0_21in之下

    通过attach方式进行调试

    adb jdwp显示所有可供调试的用户进程
    adb forward tcp:xxx jdwp:<pid>
    jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=xxx

    调试模式启动intent,手机上显示waiting for the debugger to attach,这时候attach的时候ida显示:

    protocol version is 14 expected 17。

    我是这样做的,把android_server重新push到手机里,权限改成777,运行。

    这时候用64bit的IDA打开提示类似address 4 epected 4

    我是这样做的,用32bitIDA打开。可以attach了。

    ----------一些摘自书上的内容----------

    DDMS  

    DDMS(Dalvik Debug Monitor Server)就是动态调试的一个工具(不知Android L之后会不会改名--!)。DDMS提供文件浏览、Logcat、Method Profiling等功能。

    定位关键代码

    1.代码注入法

    用Apktool反编译得到smali,查找onClick(),比如要找程序注册码,仔细阅读之后发现比对注册码与用户输入的函数

    invoke-virtual {v1, v0},Ljava/lang/String;->equalsIgnoreCase(Ljava/lang/String;)Z

    move=result v3

    if-eqz v3, :cond_2

    那么加入Log.v()来输出v0寄存器:

    const-string v3, "SN"

    invoke-static {v3, v0},Landroid/util/Log;->v(Ljava/lang/String;Ljava/lang/String;)I

    然后用Apktool打包、签名,

    用"adb logcat -s SN:v"输出SN。

      

    2.栈追踪法

    代码注入配合Logcat好用但是需要阅读大量反汇编代码来找「输出点」。

    栈追踪法也属于注入的范畴。

    比如要找一个Toast是啥时候被调用的,不用阅读太多反汇编代码,而是定位到Toast,然后在这一段之后加入

    new Exception("print trace").printStackTrace();

    对应smali在书上就不写了。

    然后打包签名运行,

    在CMD输入"adb logcat -s System.err:V *:W"

    会以堆栈的方式,先输出java.lang.Exception print trace

    然后输出从程序启动到printStackTrace()执行期间所有被调用过的方法。

    3.Method Profiling 4.AndBug 5.IDA Pro..

     另外参考:http://www.blogbus.com/riusksk-logs/271566148.html

  • 相关阅读:
    length()
    matlab mod()&rem()
    tf调试函数
    64位win7+PCL1.6.0+VS2010,64位win10+PCL1.6.0+VS2010
    pcl 1.8 + VS 2010 在win7 x64下的配置
    Qt在vs2010下的配置
    VS2010 win7 QT4.8.0,实现VS2010编译调试Qt程序,QtCreator静态发布程序
    [POI2012]ROZ-Fibonacci Representation (贪心)
    CF 666C & 牛客 36D
    数位dp练习
  • 原文地址:https://www.cnblogs.com/larrylawrence/p/3850708.html
Copyright © 2011-2022 走看看