转贴地址:http://www.freebuf.com/tools/54562.html

0×01前言

这年头,apk 全都是加密啊,加壳啊,反调试啊,小伙伴们表示已经不能愉快的玩耍了。静态分析越来越不靠谱了,apktool、ApkIDE、jd GUI、dex2jar等已经无法满足大家的需求了。那么问题就来了,小伙伴们真正需要的是什么?好的,大家一起呐喊出你内心的欲望吧,我们的目标是—— “debug apk step by step”。

0×02那些不靠谱的工具

先来说说那些不靠谱的工具,就是今天吭了我小半天的各种工具,看官上坐,待我细细道来。

2.1 IDA pro

IDA pro6.6之后加入了dex动态调试功能,一时间普天同庆、喜大普奔。兴奋之后你才会发现IDA这东西在动态调试方面真的是很挫,就算他是静态反编译之王,我也不得不说他的动态调试功能还非常需要加强。先说说使用ida调试dex的方法。

IDA pro调试dex流程:

1.用apktool反编译apk,添加android:debuggable=”true”,重打包apk并签名
2.从apk文件中扣出class.dex文件,不管你用什么方法,7zip、unzip…whatever
3.用ida打开这个dex文件,直到output window窗口显示“xxxx finished”
4.设置debugger选项,debugger->debugger options->set specific options,按如图1所示进行设置,然后一路确定返回
5.找到要下断点的位置,光标移到要下断点的那一行,按f2下断点
6.手机开启调试选项,链接usb到电脑
7.选中IDA pro窗口,按f9走起,不出意外的话应该会出现如图2的画面,成功啦~

图 1 ida debug配置

图 2 ida动态调试apk

触发断点,在watch view和Locals窗口都能看到内存变量的值,简直就是画美不看啊,是不是有点小兴奋?!我只能说高兴的太早了,小伙伴们还是太天真了,仔细观察下,就算你勾选了“Hex display”,你还是无法以hex格式显示变量的值,就是说不可显示字符你都看不到值是什么,而且我找了很久也没找到类似windbg、od、 vc6、gdb、lldb那样以各种姿势或者命令直接查看某内存地址值的功能,然后就出现了如图3的画面……WTF!我特么忙活了半天居然还不如直接logcat来得痛快!

图 3  Locals窗口

2.2 apktool+eclipse

其实小生一直还是很支持eclipse的,毕竟伴我度过了无数不眠之夜和懵懂的年华(当然苍老师和windbg可能占的更多),可是这次我真的有点小失望哈。由于使用 apktool+eclipse和apktool+android studio的调试方法跟apktool+idea一样,调试方法后面一起说,这里我就先纯吐槽了。

当小伙伴们成功设置调试选项,带着嗨翻的心情进入调试界面的时候,我们看到了如图4的画面,细细观察和各种尝试之后,我保证你的心里一定有一万头草泥马奔腾而过!!!。

图 4 eclipse单步调试apk

我们都看到了啥:

1.debug窗口表示命中第30行的断点

2.variables窗口没有任何本地变量的值,寄存器的值也没有

3.单步步入、单步步过等调试按钮都是灰色的,快捷键F5678都没反应

我就想知道这你让我怎么debug,难道我要设无限个断点,拼命f9来调试?就算是这样,我该去哪儿看变量的值?

2.3 apktool+android studio

android studio这个东西本来是蛮不错的,就是稍微有点卡,习惯了也还好。其实android studio本身就是用idea改的,但是好像给改挫了。调试方法还是后面再说,直接上成功挂载到调试界面的图,如图5。

图 5 android studio单步调试apk

这次情况是这样的:

1.可以看到现在程序停在哪一行,虽然不明显

2.本地变量能看到,但是寄存器还是木有啊

3.单步按钮还有单步快捷键都能用了,看起来好多了啊

我还是想说,问题是寄存器的值还是没法直观的看到啊,对于有强迫症的我还是无法接受这种设定啊,想当年vc6、od、windbg、gdb、lldb是多么的给力,多么的好用!

0×03 apktool+idea

正菜来了,apktool 2.0bete9版本推出了-d选项,专门用来重打包apk进行单步调试的,给力!apktool+idea无源码debug apkstep by step简直不要太好用,这也是我跟小波请教之后才弄好的,这个选项也是小波等人建议apktool作者这样做的,不禁感叹一句,波神你为何这么屌!

3.1调试基础

本小节内容引用自看雪论坛@火翼[CCG]的文章,原文链接:http://www.kanxue.com/bbs/showthread.php?p=1291716

根据android的官方文档,如果要调试一个apk里面的dex代码,必须满足以下两个条件中的任何一个:

1.apk中的AndroidManifest.xml文件中的Application标签包含属性android:debuggable=”true”
2./default.prop中ro.debuggable的值为1

由于正常的软件发布时都不会把android:debuggable设置为false(当然也不排除某些很2的应用偏偏就是true),所以要达成条件1需要对app进行重新打包,这不仅每次分析一个apk都重复操作,而且很多软件会对自身进行校验,重打包后执行会被检测到,所以想办法满足第2个条件是个一劳永逸的办法。

由于default.prop是保存在boot.img的ramdisk中,这部分每次重新启动都会重新从rom中加载,所以要到目的必须修改boot.img中的ramdisk并重新刷到设备中。修改步骤如下(我没试过,有兴趣的倒腾下):

1.从Google官方网站下载到boot.img
2.使用工具(abootimg,gunzip, cpio)把boot.img完全解开,获取到default.prop
3.修改default.prop
4.把修改后的文件重新打包成boot_new.img
5.使用fastboot工具把boot_new.img刷入设备(fastboot flash boot boot_new.img)

3.2调试方法

这里我们还是用第一种方法来进行测试:

1.下载apktool2.0b9版本,下载地址:http://connortumbleson.com/2014/02/06/apktool-2-0-0-beta-9-released/

2.使用apktool反编译apk:

java -jar apktool_2.0.0b9.jar d -d xxx.apk -o out

加上-d选项之后反编译出的文件后缀为.java,而不是.smali,每个.java文件立马都伪造成了一个类,语句全都是“a=0;”这一句,smali语句成为注释,小伙伴们自己看看打开就知道了,做这些都是为了后面欺骗idea、eclipse、androidstudio这些ide的;

3.加入android:debuggable=”true”选项;

4.重打包apk,一定记得也使用-d选项:

java -jar apktool_2.0.0b9.jar b -d out -o debug.apk

5.对apk进行签名并安装apk到调试设备(这个不用我说怎么操作吧);

6.下载安装并打开idea,新建一个空的java项目,本例中项目名为“DebugOnly”,将apk反编译后的smali目录下的所有文件拷贝到刚才新建的java项目的src/目录下,刷新,如图6;

图 6拷贝文件

7.打开androiddevice monitor(终端下敲命令monitor或者ddms),终端下运行命令:adb shell am start -D -n {Package Name}/.{Activity},运行效果如图7;

图 7命令运行效果

此时在调试设备上会显示等待调试器接入:

图 8调试设备状态

8.从androiddevice monitor上发现需要调试的程序已经显示在列表里面了,记下端口号,本例中为8700;

图 9 android device monitor

9. 新建远程调试:依次点击run->edit configuration->“+”号->Remote,选中第6步中新建的项目,填写第8步中获得的端口号,如图10;

图 10 debug设置

10.找到相应位置设置断点(在想设断点的位置前后多设置几个断点),点击run->debug->unnamed,其中unnamed是第9步中新建的远程调试的名字;

图 11远程调试名字

11.不出意外的话,小伙伴们应该能看到如图12所示的画面,恭喜你,已经成功了!此时此刻兴奋之情简直能以言表哈~good luck! have fun! enjoy~

图 12 idea单步调试apk

0×04后语

另外,阿呆曾经提到一篇文章用jdb远程调试android程序的文章,链接为:http://resources.infosecinstitute.com/android-hacking-security-part-6-exploiting-debuggable-android-applications/,我没有尝试过,主要是我比较懒,用apktool+idea已经够用了,就没去倒腾,有兴趣的小伙伴请自行倒腾,别忘了分享!

最后,其实我也不确定ida是不是真的不能以hex格式显示变量值,或许是我不会用ida咧;我也不确定eclipse到底能不能看寄存器的值,单步按钮和快捷键到底能不能用,或许是我eclipse版本的问题咧;我也不确定android studio到底能不能看到寄存器的值,或许是我android studio版本的问题咧,再或者我用的调试设备有问题咧,再或者我的脸有问题咧……以上问题,如果哪位小伙伴知道怎么解,跪求告知!

[作者/阿里聚安全-轩夏 Jason_HZ,转载须注明来自FreeBuf.COM]

解密所有APP运行过程中的内部逻辑(转)的更多相关文章

  1. ionic 运行过程中动态切换API服务器地址

    ionic 运行过程中动态切换API服务器地址 keywords: ionic,phonegap,cordova,网络制式,动态切换,变更,API,服务器地址,$resource,localstora ...

  2. HOWTO - Basic MSI安装包在安装运行过程中如何获取完整源路径

    有朋友问到如何在一个Windows Installer安装包中获取安装包源路径,就是在安装包运行过程中动态获取*.msi所在完整路径. 这个问题分两类,如果我们的安装包只是一个*.msi安装文件,那么 ...

  3. (转)在.NET程序运行过程中,什么是堆,什么是栈?什么情况下会在堆(栈)上分配数据?它们有性能上的区别吗?“结构”对象可能分配在堆上吗?什么情况下会发生,有什么需要注意的吗?

    转自:http://www.cnblogs.com/xiaoyao2011/archive/2011/09/09/2172427.html 在.NET程序运行过程中,什么是堆,什么是栈? 堆也就是托管 ...

  4. Jmeter运行过程中如何让Fiddler同时可以抓获到服务器的应答报文

    在默认情况下,Jmeter运行过程中,Fiddler是抓不到对应的应答报文的. 但是,在某些时候,我们希望分析Jmeter执行失败的原因,想了解Jmeter获取到的应答报文是否有问题,就需要同服务器返 ...

  5. Torch-RNN运行过程中的坑 [2](Lua的string sub函数,读取中文失败,乱码?)

    0.踩坑背景 仍然是torch-rnn/LanguageModel.lua文件中的一些问题,仍然是这个狗血的LM:encode_string函数: function LM:encode_string( ...

  6. Torch-RNN运行过程中的坑 [1](读取Lua非空table,size为0)

    0.踩坑背景 执行Torch-RNN的时候,在LanguageModel.lua中的encode_string函数中,对start_text的各个character进行id映射编码,实现功能类似“北京 ...

  7. Torch-RNN运行过程中的坑 [0](一些基础概念)

    0.Lua & LuaJIT简介 Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴 ...

  8. 程序运行过程中遇到“ORA-03114: not connected to ORACLE”的问题解决

    c#,winform程序,数据批量入oracle库时用到DataAdaper的.FillSchema函数,如:da.FillSchema(dt2, SchemaType.Mapped); 程序运行一段 ...

  9. Android APP 调试过程中遇到的问题。

    调试过过程中APP安装完启动后有的时候会异常退出,报这个错误.有的时候可以直接启动.查找不到原因.网上说把commit方法替换成commitAllowingStateLoss() 也无效. Andro ...

随机推荐

  1. Spring学习--通过注解配置 Bean (三)

    组件装配: <context:component-sacan> 元素还会自动注册 AutowiredAnnotationBeanPostProcesser 实例 , 该实例可以自动装配具有 ...

  2. event loop 小记

    水平不够,只能整理一下知乎大神的回答,勉强度日这样子 在一个事件循环里,会有两个主要的队列:task queue 和 micro-task quene. 其中 task 包括: script(整体代码 ...

  3. css3 新旧伸缩盒的异同

    由于不需要理会IE浏览器,伸缩盒(flexible box)移动端开发中非常好用! 工作中使用APICLOUD开发手机App,老板要求兼容到安卓2.3(新版的需要安卓4.4以上),所以一直使用的是旧版 ...

  4. NET中IL理解(转)

    .NET CLR 和 Java VM 都是堆叠式虚拟机器(Stack-Based VM),也就是說,它們的指令集(Instruction Set)都是採用堆叠运算的方式:执行时的资料都是先放在堆叠中, ...

  5. 动态规划:树形DP

    典型例题有三道: 没有上司的舞会 选课 景点中心 我们可以把动态规划的状态和转移描述成DAG 对于有根树来说,如果我们规定边的方向由父节点指向叶子节点 或者是由叶子节点指向父节点(奇葩) 那么它也是一 ...

  6. [BZOJ1024][SCOI2009]生日快乐解题报告

    Description windy的生日到了,为了庆祝生日,他的朋友们帮他买了一个边长分别为 X 和 Y 的矩形蛋糕.现在包括windy,一共有 N 个人来分这块大蛋糕,要求每个人必须获得相同面积的蛋 ...

  7. android ARM 汇编学习 —— hello world

    android ARM 汇编学习—— 在 android 设备上编译c/cpp代码并用objdump/readelf等工具分析 adb putty 连上手机,用busybox vi 写一个 hello ...

  8. python学习笔记 序列化

    在程序运行的过程中,所有的变量都是在内存中,比如,定义一个dict: d = dict(name='Bob', age=20, score=88) 可以随时修改变量,比如把name改成'Bill',但 ...

  9. kuangbin带你飞 后缀数组 题解

    2份模板 DC3 . 空间复杂度O3N 时间复杂度On #define F(x) ((x) / 3 + ((x) % 3 == 1 ? 0 : tb)) #define G(x) ((x) < ...

  10. Xcode升级到7之后 发现速度超级慢

    Xcode升级到7之后 发现速度超级慢 转自:http://www.jianshu.com/p/608803eb1e12 解决方法,慢google了一下是由于插件造成饿,于是乎将Alcatraz安装的 ...