1. 前言

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

2. 那些不靠谱的工具

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

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是多么的给力,多么的好用!

3. apktool+idea

正菜来了,apktool 2.0bete9版本推出了-d选项,专门用来重打包apk进行单步调试的,给力!apktool+idea无源码debug apk step 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、android studio这些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.打开android device monitor(终端下敲命令monitor或者ddms),终端下运行命令:adb shell am start -D -n {Package Name}/.{Activity},运行效果如图7;

图 7 命令运行效果

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

图 8 调试设备状态

8.从android device 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

4. 后语

另外,阿呆曾经提到一篇文章用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版本的问题咧,再或者我用的调试设备有问题咧,再或者我的脸有问题咧……以上问题,如果哪位小伙伴知道怎么解,跪求告知!

作者:轩夏

原文地址: http://jaq.alibaba.com/blog.htm?id=52

解密所有APP运行过程中的内部逻辑相关推荐

  1. 关于线程池运行过程中,业务逻辑出现未知异常导致线程中断问题反思

    最近在项目研发中的关于线程池应用过程中由于业务逻辑异常导致的线程中断,但程序未中断导致的脏数据问题  话不多说,在最近最新的一个版本发布过程中,业务需要,我们要定期去给客户预留出可用的资源数据,提供客 ...

  2. 内存管理——程序运行过程中内存的作用以及如何与cpu、os交互

    今年以来,内存条价格暴涨,已经跃升为新的新一代理财产品,所以今天就和大家讨论一下内存条的话题,主要内容就是在程序运行过程中,内存的作用以及如何与CPU,OS交互. 我们先来讨论:计算机的运行究竟是在做 ...

  3. 小程序执行运行过程原理_活性污泥法基本原理、净化反应过程、工艺类型和运行过程中存在的问题...

    ↑ 点击上方"表面活性剂平台"关注我们 活性污泥法实质上是天然水体自净作用的人工强化,能从污水中去除溶解态和胶体态的可生物降解有机物以及能被活性污泥吸附的悬浮固体和其他物质,具有对 ...

  4. java程序中可以如何异常处理?_如何处理罗茨鼓风机在运行过程中出现异常噪音和叶片的运行特性...

    罗茨鼓风机叶片的运行特性: 1.后叶片类型的叶片突出而重要的特点是无过载功率.它消除了对超大电机或其他驱动器的需求.常规叶片的正常工作静态效率范围为65-80%,流线型设计的通常工作静态效率范围为80 ...

  5. STM32运行过程中降低系统时钟频率

    目录 1. 概述 2. 直接修改外部时钟 2.1 生成时钟函数 2.1.1 设置系统时钟为16M: 2.1.2 配置时钟72M: 2.2 测试降频 3. 借助内部时钟 3.1 生成时钟函数 3.2 测 ...

  6. java在程序运行过程中_Java内存管理-程序运行过程(一)

    做一个积极的人 编码.改bug.提升自己 我有一个乐园,面向编程,春暖花开! 勿在浮沙筑高台,出来混迟早要还的. 相信在做Java开发的伙伴一定知道 JVM(Java Virtual Machine( ...

  7. 操作系统中进程并发运行的过程_三种电磁流量计运行过程中常见故障解决详情!...

    原标题:三种电磁流量计运行过程中常见故障解决详情! 昨天给大家介绍了电磁流量计的一些典型故障,今天我们继续来谈电磁流量计的故障问题!电磁流量计在正常的保养与维护之后,在正常使用的过程中依旧是会因为当时 ...

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

    程序运行过程中遇到"ORA-03114: not connected to ORACLE"的问题解决 参考文章: (1)程序运行过程中遇到"ORA-03114: not ...

  9. python运行过程中会被编译成二进制_Python代码在运行过程中,会被编译成二进制代码。_学小易找答案...

    [单选题]1. ( )是违反设备安全操作规程的错误做法. [单选题]Thank you for your letter ___________ 24th March. (1.0分) [单选题]超外差接 ...

最新文章

  1. easyUI样式之easyui-switchbutton
  2. python装饰器实例-python 装饰器的使用示例
  3. 18_使用react脚手架构建应用
  4. RabbitMQ—集群原理
  5. CodeForces - 1535C Unstable String(思维)
  6. 求关系模式r的所有候选码_2_1关系数据库的基本概念
  7. CodeVs——T 4919 线段树练习4
  8. Python中 类和对象调用其他类中的变量和方法
  9. 因低俗色情网络文学作品 多个知名小说平台停更整改
  10. 字节流和字符流的读写
  11. 大数据时代移动营销的十大趋势
  12. c# 服务器打印word文档,C#中5步完成word文档打印的方法
  13. js中ajax提交表单提交表单提交,JS中ajax请求提交form表单
  14. 跟着Cell学作图| 11.Ingenuity Pathway Analysis(IPA)
  15. 如何去掉vi下面显示的[converted]标志
  16. python爬虫-北京租房可视化分析
  17. Linxu-解压压缩命令
  18. 怎样将收藏的网址导入到搜狗账号中
  19. 基于PSO工具箱的函数寻优算法
  20. 253:丛林中的路——最小生成树Prim

热门文章

  1. [zz]jQuery.extend 函数详解
  2. Go 语言框架 Gin 练习1
  3. Django入门:DoesNotExist: User matching query does not exist.
  4. Python学习笔记: Python 标准库概览
  5. apt-get 与 yum的区别 (转)
  6. 详解C++移动语义std::move()
  7. [云炬创业基础笔记]第一章创业环境测试11
  8. [云炬python3玩转机器学习] 5-7,8 多元线性回归正规解及其实现
  9. 基于贝叶斯决策理论的分类器
  10. JavaScript中判断是否存在某属性