热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

动态调试Android程序

最近好几天来一直在看动态调试。首先是这一篇(http:www.52pojie.cnforum.php?modviewthread&tid293648

最近好几天来一直在看动态调试。首先是这一篇(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(附加后程序会中断)。

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

动态调试Android程序

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  )
        fputc(Byte(dex_addr), fp);
}

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

 

 

 

 

 

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

 

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

例:adb [-d|-e|-s ] 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:
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


推荐阅读
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • 自动轮播,反转播放的ViewPagerAdapter的使用方法和效果展示
    本文介绍了如何使用自动轮播、反转播放的ViewPagerAdapter,并展示了其效果。该ViewPagerAdapter支持无限循环、触摸暂停、切换缩放等功能。同时提供了使用GIF.gif的示例和github地址。通过LoopFragmentPagerAdapter类的getActualCount、getActualItem和getActualPagerTitle方法可以实现自定义的循环效果和标题展示。 ... [详细]
  • 如何自行分析定位SAP BSP错误
    The“BSPtag”Imentionedintheblogtitlemeansforexamplethetagchtmlb:configCelleratorbelowwhichi ... [详细]
  • 知识图谱——机器大脑中的知识库
    本文介绍了知识图谱在机器大脑中的应用,以及搜索引擎在知识图谱方面的发展。以谷歌知识图谱为例,说明了知识图谱的智能化特点。通过搜索引擎用户可以获取更加智能化的答案,如搜索关键词"Marie Curie",会得到居里夫人的详细信息以及与之相关的历史人物。知识图谱的出现引起了搜索引擎行业的变革,不仅美国的微软必应,中国的百度、搜狗等搜索引擎公司也纷纷推出了自己的知识图谱。 ... [详细]
  • http:my.oschina.netleejun2005blog136820刚看到群里又有同学在说HTTP协议下的Get请求参数长度是有大小限制的,最大不能超过XX ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • 解决VS写C#项目导入MySQL数据源报错“You have a usable connection already”问题的正确方法
    本文介绍了在VS写C#项目导入MySQL数据源时出现报错“You have a usable connection already”的问题,并给出了正确的解决方法。详细描述了问题的出现情况和报错信息,并提供了解决该问题的步骤和注意事项。 ... [详细]
  • 本文详细介绍了Java中vector的使用方法和相关知识,包括vector类的功能、构造方法和使用注意事项。通过使用vector类,可以方便地实现动态数组的功能,并且可以随意插入不同类型的对象,进行查找、插入和删除操作。这篇文章对于需要频繁进行查找、插入和删除操作的情况下,使用vector类是一个很好的选择。 ... [详细]
  • 猜字母游戏
    猜字母游戏猜字母游戏——设计数据结构猜字母游戏——设计程序结构猜字母游戏——实现字母生成方法猜字母游戏——实现字母检测方法猜字母游戏——实现主方法1猜字母游戏——设计数据结构1.1 ... [详细]
  • 怎么在PHP项目中实现一个HTTP断点续传功能发布时间:2021-01-1916:26:06来源:亿速云阅读:96作者:Le ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
author-avatar
10651s
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有