在信安大赛的准备过程中,主要通过 Android Studio 动态调试 apk 反编译出来的 smali 代码的方式来对我们分析的执行流程进行验证。该技巧的主要流程在此记录。以下过程使用 Android Studio 3.0.1 和 smalidea 0.0.5 进行演示。

smali动态调试简述

  使用 Android Studio 调试 apk 反编译出的 smali 代码,需要 PC 端和移动端的合作。在 PC 端通过 Android Studio 导入反编译出的完整的 smali 代码,并设置好调试所需的条件,并设置断点。随后将移动设备连接至 PC 端,并正常运行调试的 apk 应用,当待调试的 apk 应用执行流程运行至 PC 端上对应的 smali 代码设置的断点处时,则会触发断点,从而可以进行进一步的分析和调试等。

  上述方法可以与静态流程分析相结合,以确认所分析流程的正确性( 会触发选定的断点 )。

动态调试所需的条件

  想要通过 Android Studio 进行 smali 代码的动态调试,至少需要满足以下条件之一:

  (1) 将待调试的应用设置为可调试的。apk 的 release 版本均为不可调试的,故需将 apk 中的 AndroidManifest.xml 文件中的  android:debuggable 设置为 true ,再将 apk 重打包,再进行安装后,即可进行调试。若原 AndroidManifest.xml 文件不含有 debuggable 字段,则在合适的位置添加即可;( 但该方法会破坏源apk的完整性,可能无法通过 apk 的完整性检查,且仅针对一款应用 )

  (2) 将移动设备的 / /default.prop 中的 ro.debuggable 设置为 1;(需要手机 root 权限 ,设置后即可对所有应用进行调试 )

  笔者采用的是第二种方案,该方案相对来说最简单,且不会破坏源 apk 的完整性,设置借助的是 xposed 框架,简单过程可见文末

安装 smalidea

  (1)在这里下载最新的 smalidea 安装包(.zip)。

  (2)在 Android Studio 的 File -> Settings -> Plugins 中,选择 Install plugin from disk ,选中之前下载的 .zip 格式的文件,确定;

  (3)重新启动 Android Studio 即可;

  不同的Android Studio 版本可能上述路径有所不同,但过程大致相同。

获取 apk 反编译出的完整的 smali 代码

  一般借助 apktools 进行完整 apk 的反编译操作。

在 Android Studio 中导入和配置项目

  (1) 选择 import project -> 选择 apk 反编译出的完整的 smali 文件夹 -> Create project from existing sources ,并一路选择 next 即可。导入完成后,将目录结构切换为 project 。

  

  (2) 选中项目目录,右键 -> Mark Directory as -> Sources root.

  

  (3) 配置项目使用的 JDK 版本,选中 项目目录 -> 右键 -> Open Module Settings -> Project ,在右侧 Project SDK 栏中选择安装待调试 apk 的移动设备所使用的 JDK 版本。(在笔者使用的 Android Studio 3.0.1 版本的导入过程中,Android Studio 会询问项目将会使用的 SDK 版本,直接在该提示界面中选择所需的 JDK 版本即可.)

  

  

  (4) 对调试选项进行编辑,点击 Android Studio 界面上的图示按钮,选择 Edit Configurations。

  

  通过添加按钮  添加一个 Remote 调试。可根据需要对该调试的 Name 和 Port 进行修改,通过 apply 进行确认。

  

启动调试

  调试的方法有两种,一种是通过 DDMS 启动调试,一种是通过命令行 adb 命令启动调试。( 以下为 Android Studio 3.0.1 中的操作)

  通过 DDMS 启动调试

  (1) 通过 Tools -> Android -> Android Device Monitor ,在 DDMS 左侧的列表中,选中所需要调试的包名;

  (2) 切回 Android Studio 界面,点击选择菜单 run -> debug "xxx" (xxx 为设置的 remote 调试的名字),即开始调试过程,此时 DDMS 界面的包名前面会出现一个绿色小虫标志;

  

  使用该方法进行调试的缺点在于,需要将 remote 调试中的端口号设置为 DDMS 包名后面显示的两个端口号之一。其中 8700 端口总是固定的,建议使用。

  使用命令行启动调试

  ( 注:使用该方法时需要关闭 DDMS,因为 DDMS 也使用了 adb ,同时开启会有冲突 )

  (1) 使用 adb shell 以调试模式运行待调试的应用,关于以命令行方式运行 adb shell ,可以参考笔者在这里的记录。

    adb shell am start -D -S -W packageName/mainActivity    //以调试状态运行目标应用,参数为 包名/主activiy 名。

  所需找到的包名和主活动名在 apk 的 AndroidManifest.xml 中均有记录。在 AndroidManifest.xml 中, package 字段对应的值即为包名,而带有 LAUNCHER 关键字的 activity 即为主 activity。

    a.包名:

    

    b.主 activity 名

    

  所以对于图示 apk ,需要执行的命令即为

    adb shell am start -D -S -W com.tencent.mm/com.tencent.mm.ui.LauncherUI 

  若上述命令运行成功,则在手机终端上会显示 Waiting For Debugger 提示,不要关闭该提示框。

  

  (2) 通过 adb shell ps 命令显示所有移动设备上运行的进程,并找到目标进程的pid ( 也就是刚启动的应用的 pid )。

    adb shell ps | grep "com.tencent.mm"      //非Windows环境下,可以使用 grep 命令以包名为参数进行字符串筛选
adb shell ps | findstr "com.tencent.mm" //Windows环境下,通过 findstr 命令以包名为参数进行字符串选择
adb shell "ps | grep "com.tencent.mm"" //使用 android 环境下的 grep 命令,而不是主机上的命令

  查询结果如下,即找到对应进程的pid。

  

  (3) 进行端口映射

     adb forward tcp:port_A jdwp:pid    //其中,port_A 为添加 remote 调试时指定的端口号,pid 即为第二步中获得对应调试进程的 pid 

  对于笔者的示例,即为

     adb forward tcp:5005 jdwp:12144

  由于执行了端口映射,所以 remote 调试中的端口号可以为任意未被占用的端口号。

  (4) 使用 run -> attach debugger to Android Process 选项,根据提示选择待调试进程即可。正确操作时,移动设备上的 waiting for debugger 对话框会消失。

 

  通过上述方法启动调试之后,即可进行正常的调试过程。常见的方案是在经过分析所得的可能执行路径上事先设置断点,之后在移动设备上进行对应的 app 操作,若分析正确,则 app 会执行对应的流程,从而触发断点,从而可以进行进一步的分析。  

一些可能错误

  通过 Android Studio 的菜单栏 run -> debug "xxx" 启动调试时,报错"unable to open debugger port java.net.socketexception connection reset"

  网上相关资料较少,但出现该问题时,需要注意是否待调试应用是处于可调试状态的,对于以 adb shell am start -D 命令运行的应用,需要 ro.debuggable=1 或 android:debuggable=”true”,在不满足上述条件时,adb shell am start -D 命令不会报错,但是通过 adb shell "ps -t | grep -A 8 package" 进行验证时,会发现目标应用进程中不含有 JDWP 线程,此时不论如何进行设置,都无法使得调试顺序进行,Android Studio 中也会报上述错误。

  将移动设备的 ro.debuggable 设置为 1 的方法,比较简单的无需刷机的方法是安装 xposed 框架( 需要 root 权限 ),之后通过已开发好的 xposed 模块如 BuildProp Enhancer设置 ro.debuggable 位,该方法一次重启后即可生效,之后即可对应用进行调试。( 注意使用上述方法后,使用诸如 adb shell "getprop ro.debuggable"命令时,返回的结果仍为0,但是所有的应用确实处于可调试状态)

  xposed 框架的安装可以参考 xposed 中文网站xposed 英文论坛,也可参考网上资料。

  

参考资料:

  (1) 简要介绍:Smalidea+IntelliJ IDEA/Android Studio无源码调试

  (2) 完整过程介绍 : 使用Smalidea对无源码APK调试简介

Android Studio 动态调试 apk 反编译出的 smali 代码的更多相关文章

  1. Android Studio动态调试smali代码

    工具: Android Studio版本: 3.0.1 smalidea插件: https://github.com/JesusFreke/smali/wiki/smalidea. 反编译工具:本节先 ...

  2. Android studio动态调试

    Reference:  http://cstsinghua.github.io/2016/06/13/Android%20studio%E5%8A%A8%E6%80%81%E8%B0%83%E8%AF ...

  3. android逆向基础:apk 反编译 重打包 重签名

    apk 反编译大家都比较熟悉,这里只做一个笔记. 1 反编译 apk apktool d perfect.apk 这样就把资源文件解压缩了, classes.dex 也反编译成了 smali 文件 2 ...

  4. Android studio动态调试smali

    前面介绍了使用IDA动态调试smali,这种方法设置简单,不用重打包,用起来方便,但是如果变量类型设置错误则会马上退出调试,这是让人不爽的地方,而使用Android studio则不会.   0x01 ...

  5. apk反编译之二——smali学习

    在apk被反编译后,原来的java程序会以smali文件呈现.这就需要补充smali的知识.依旧参考官方文档,择日我将把官方文档做一下翻译.今日先贴出链接地址: 1:了解smali字节码的寄存器 请参 ...

  6. 使用AndroidKiller进行APK反编译

    安装环境 JDK 最好用JDK8,问就是坑太多了 Android Studio 官网安装即可,安装教程如下 https://www.runoob.com/android/android-studio- ...

  7. Android apk反编译基础(apktoos)图文教程

    本文主要介绍了Android apk反编译基础,使用的工具是apktoos,我们将用图文的方式说明apktoos工具的使用方式,你可以参考这个方法反编译其它APK试试看了 很久有写过一个广工图书馆主页 ...

  8. Android APK反编译(一)

    apk是安卓工程打包的最终形式,将apk安装到手机或者模拟器上就可以使用APP.反编译apk则是将该安卓工程的源码.资源文件等内容破解出来进行分析. 一.APK反编译基本原理 1.APK分析 apk文 ...

  9. Android: apk反编译 及 AS代码混淆防反编译

    一.工具下载: 1.apktool(资源文件获取,如提取出图片文件和布局文件) 反编译apk:apktool d file.apk –o path 回编译apk:apktool b path –o f ...

随机推荐

  1. 【转】NuGet学习笔记

    关于NuGet园子里已经有不少介绍及使用经验,本文仅作为自己研究学习NuGet一个记录. 初次认识NuGet是在去年把项目升级为MVC3的时候,当时看到工具菜单多一项Library Package M ...

  2. 记录一次nginx502/504问题解决过程

    最近自己在阿里云购买有段时间的服务器,一访问就出现nginx 504 Gateway Time-out. 想起以前是可以访问的,细想最近改动的配置应该不会涉及到这块啊. 就网上各种百度谷歌,最后终于找 ...

  3. Java根据国家二字码获取国家英文名称,中文名称实例

    import org.apache.commons.lang.StringUtils; public class CountryUtil { /** * 根据国家二字码获取国家对应的中文(英文,cod ...

  4. hadoop classpath 的作用

    HADOOP_CLASSPATH 是设置要运行的类的路径.否则当你用hadoop classname [args]方式运行程序时会报错,说找不到要运行的类.用hadoop jar jar_name.j ...

  5. react框架 Dva & Umi

    概念 // http://localhost:3000/ //models import IndexPage from './routes/IndexPage'; import Products fr ...

  6. BZOJ3600:没有人的算术

    传送门 如果能给每个 \(pair\) 按照权值编号就好了 假设之前已经有了所有的权值的编号,现在考虑编号新的 \(pair\) 如果看过了陈立杰的论文的话,不难得到一个重量平衡树的做法 给树上每个子 ...

  7. css3 伪元素和伪类选择器详解

    转自脚本之家:http://www.jb51.net/css/213779.html 无论是伪类还是伪元素,都属于CSS选择器的范畴.所以它们的定义可以在CSS标准的选择器章节找到.分别是 CSS2. ...

  8. vue2.0路由写法

    // 0. 如果使用模块化机制编程,導入Vue和VueRouter,要调用 Vue.use(VueRouter) // 1. 定义(路由)组件. // 可以从其他文件 import 进来 var Fo ...

  9. 全面认识Docker和基本指令

    Docker逐渐成为虚拟化技术的佼佼者,Java架构师之路接下来会推出一系列的Docker相关技术文章,Docker技术也是架构师的必备技能. 什么是Docker Docker 是一个开源的应用容器引 ...

  10. android热加载随记

    在我们日常的开发过程中,程序难免会出现BUG,一般有集中处理方式,发布新版本APP让用户来升级,或者打补丁来修复bug 前者本文在这里不错讨论,打补丁升级又分为两种一种是需要重启应用,一种是不需要.不 ...