动态调试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提供的,存在于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程序的更多相关文章
- IDA动态调试Android的DEX文件
Android程序的dex文件的动态调试确实是个大问题,网上也有一些教程但是不是特别的详细,今天用到了IDA动态调试Android的DEX文件,特此记录一下. IDA 6.6新添加了对dex文件的调试 ...
- 在ubuntu下真机调试android程序出现设备没有访问权限
今天把android的开发环境从windows平台切换到了ubuntu上. java jdk android-adt android-ndk都下好,环境变量都配好之后, 在调试程序的时候,出现设备没有 ...
- 谈使用Eclipse与DDMS调试Android程序的方法
在Eclipse开发工具中调试程序的方法很多,但是使用Eclipse调试Android程序时需要注意一些细节上的问题.许多刚接触 Android的开发者,在调试Android程序时总是不能迅速地找到程 ...
- Ida动态修改android程序的内存数据和寄存器数值,绕过so文件的判断语句
我们继续分析自毁程序密码这个app,我们发现该程序会用fopen ()打开/proc/[pid]/status这个文件,随后会用fgets()和strstr()来获取,于是我们在strstr()处下个 ...
- 真机在wifi下调试android程序
大家好,最近在学习android程序由于手机接口问题,调试程序的时候老是接触不良而不能正常调试,因此感到相当苦恼,于是在网上查找无线调试android的方法.经过研究和尝试现已成功无线调试程序,方法分 ...
- 使用visual studio 调试android 程序 ,真机调试
1 使用visual studio 2015 新建 blank android APP , 2 安卓手机调整到开发者模式 3 通过USB链接到PC 4 自动检测 设备(这一步貌似没有立即检测到真机设备 ...
- 通过wifi调试Android程序
原文:http://www.cnblogs.com/sunzhenxing19860608/archive/2011/07/14/2106492.html 1.首先让android手机监听指定的端口: ...
- eclipse下使用Genymotion调试Android程序出现的问题
一. The connection to adb is down, and a severe error has occured. You must restart adb and Eclipse. ...
- Eclipse开发工具的使用之-使用Eclipse的Debug调试Android程序
1.设置断点,双击Eclipse编辑界面的边界,或者右击编辑界面的边界,快捷键Ctrl+Shift+B. 2.F11键开始调试程序,程序安装到手机之后,并不会自动运行,需要你手动运行到断点处. 3.运 ...
随机推荐
- Android动画中Interpolator 详解和演示
遇到一个项目需求,想让动画变得更活泼一点,于是想到了动画属性中的Interpolator,写了基本例子测试一下Android提供给我们现成的加速器的效果: 效果 代码中方法 xml中属性 越来越快 A ...
- 浮窗WindowManager view返回和Home按键事件监听
出于功能需求,需要在所有的view之上显示浮窗,于是需要在WindowManager的View上处理返回键的响应, mFloatingWindowView = layoutInflater.infla ...
- [Servlet&JSP] 从JSP到Servlet
JSP与Servlet是一体的两面,JSP最后都会被容器转译为Servlet源码,自己主动编译为.class文件,载入.class文件然后生成Servlet对象. 由容器转译后的Servlet类具有_ ...
- (二)MVVMLight 关联View和ViewModel
在我们按照(一)中的步骤,安装好MMVLight的环境后, 会多出一个文件夹ViewModel,里面有两个.cs文件MainViewModel.cs和ViewModelLocator.cs MainV ...
- hdu5296(2015多校1)--Annoying problem(lca+一个公式)
Annoying problem Time Limit: 16000/8000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
- win7-64bit下基于VMware12.5安装rhel-server-6.3-i386
/************************************************************************************* 宿主PC:win7-64b ...
- TXT文本写入数据库
load data local infile "D:/abc.txt" into table lee; leedabao.txt内容如下,中间用Tab隔开: 2 yuanpeng ...
- MYSQL 5.6修改密码
忘记了超级用户root密码的时候怎么办呢? 1. 修改配置文件跳过密码 (1)编辑mysql主配置文件my.cnf # vim /etc/my.cnf 在[mysqld] 字段下添加参数 skip-g ...
- mac下执行文件出现Permission Denied的解决
mac 下终端访问文件出现“Permission Denied”解决方案: 一个文件有3种权限,读.写.可执行,你这个文件没有可执行权限,需要加上可执行权限. 1. 终端下先 cd到该文件的目录下 2 ...
- 一致性Hash简单介绍和使用
背景: 一致性Hash用于分布式缓存系统,将Key值映射到详细机器Ip上,而且添加和删除1台机器的数据移动量较小,对现网影响较小 实现: 1 Hash环:将节点的Hash值映射到一个Hash环中.每一 ...