最近好几天来一直在看动态调试。首先是这一篇(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提供的,存在于xxx\Java\jdk1.6.0_21\bin之下

通过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

动态调试Android程序的更多相关文章

  1. IDA动态调试Android的DEX文件

    Android程序的dex文件的动态调试确实是个大问题,网上也有一些教程但是不是特别的详细,今天用到了IDA动态调试Android的DEX文件,特此记录一下. IDA 6.6新添加了对dex文件的调试 ...

  2. 在ubuntu下真机调试android程序出现设备没有访问权限

    今天把android的开发环境从windows平台切换到了ubuntu上. java jdk android-adt android-ndk都下好,环境变量都配好之后, 在调试程序的时候,出现设备没有 ...

  3. 谈使用Eclipse与DDMS调试Android程序的方法

    在Eclipse开发工具中调试程序的方法很多,但是使用Eclipse调试Android程序时需要注意一些细节上的问题.许多刚接触 Android的开发者,在调试Android程序时总是不能迅速地找到程 ...

  4. Ida动态修改android程序的内存数据和寄存器数值,绕过so文件的判断语句

    我们继续分析自毁程序密码这个app,我们发现该程序会用fopen ()打开/proc/[pid]/status这个文件,随后会用fgets()和strstr()来获取,于是我们在strstr()处下个 ...

  5. 真机在wifi下调试android程序

    大家好,最近在学习android程序由于手机接口问题,调试程序的时候老是接触不良而不能正常调试,因此感到相当苦恼,于是在网上查找无线调试android的方法.经过研究和尝试现已成功无线调试程序,方法分 ...

  6. 使用visual studio 调试android 程序 ,真机调试

    1 使用visual studio 2015 新建 blank android APP , 2 安卓手机调整到开发者模式 3 通过USB链接到PC 4 自动检测 设备(这一步貌似没有立即检测到真机设备 ...

  7. 通过wifi调试Android程序

    原文:http://www.cnblogs.com/sunzhenxing19860608/archive/2011/07/14/2106492.html 1.首先让android手机监听指定的端口: ...

  8. eclipse下使用Genymotion调试Android程序出现的问题

    一. The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. ...

  9. Eclipse开发工具的使用之-使用Eclipse的Debug调试Android程序

    1.设置断点,双击Eclipse编辑界面的边界,或者右击编辑界面的边界,快捷键Ctrl+Shift+B. 2.F11键开始调试程序,程序安装到手机之后,并不会自动运行,需要你手动运行到断点处. 3.运 ...

随机推荐

  1. mysql主从一致问题

    https://www.cnblogs.com/gomysql/p/3662264.html

  2. 关于JavaScript禁止点击事件

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  3. C语言-二维背包问题

    二维费用背包问题 问题: 二维费用的背包问题是指:对于每件物品,具有两种不同的费用:选择这件物品必须同时付出这两种代价:对于每种代价都有 一个可付出的最大值(背包容量).问怎样选择物品可以得到最大的价 ...

  4. 转 Python Selenium设计模式-POM

    前言 本文就python selenium自动化测试实践中所需要的POM设计模式进行分享,以便大家在实践中对POM的特点.应用场景和核心思想有一定的理解和掌握. 为什么要用POM 基于python s ...

  5. Linux 中如何查询和卸载已安装的软件

    Linux 中如何查询和卸载已安装的软件 Linux软件的安装和卸载一直是困扰许多新用户的难题.在Windows中,我们可以使用软件自带的安装卸载程序或在控制面板中的“添加/删除程序” 来实现.与其相 ...

  6. LINUX创建用户的命令

    LINUX创建用户的命令useradd -g test -d /home/test1 -s /etc/bash -m test1注解:-g 所属组 -d 家目录 -s 所用的SHELL 删除用户命令u ...

  7. OI知识体系

  8. 1.新手上路:Windows下,配置Qt环境

    个人体会: 我最初只是想看看C++除了"黑窗口"之外,怎么才能做一些"更好看的东西".之后在网上看到有人推荐Qt,就看了一下官网(https://www.qt. ...

  9. iOS开发:Toast for iPhone

    iOS开发:Toast for iPhone   分享一个我写的类似于android的toast的提示框 主要特点: 1,支持屏幕Y轴任意位置显示,设置距离顶/底端距离 2,支持多行文本 3,支持设置 ...

  10. 横向卷轴(side-scrolling)地图的canvas实现

    标题有点小题大作了,实际上是实现一张看起来连续的运动背景图片. 效果如下:   // 实现原理: 图片1与图片2是两张首尾衔接的图片,图片1以一定速度移出canvas,图片2慢慢移进canvas,当图 ...