安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码

 

教我兄弟学Android逆向04 动态调试smali代码:https://www.52pojie.cn/thread-658865-1-1.html

From:Android Studio 3.6 调试 smali:https://blog.csdn.net/jha334201553/article/details/104494732
From:Smalidea+IntelliJ IDEA/Android Studio无源码调试:https://bbs.pediy.com/thread-220743.htm
From:反编译之利用AndroidStudio动态调试smali源码:https://juejin.im/post/5c14622be51d4556c90be796
From:Android Studio动态调试smail源码:https://blog.csdn.net/hp910315/article/details/52790740

smalidea 插件 github 地址:https://github.com/JesusFreke/smalidea

Android Studio Smali 调试:https://www.jianshu.com/p/b9312b056d15

Android调试系列—使用android studio调试smali代码:https://www.cnblogs.com/gordon0918/p/5570811.html

Android Studio动态调试smali:https://zhuanlan.zhihu.com/p/85469186

AndroidStudio+ideasmali动态调试smali汇编:https://www.cnblogs.com/lanrenxinxin/p/4891424.html

Android Studio + smalidea进行smail动态调试:https://blog.csdn.net/u013736724/article/details/53292855

微信APP调试方法AndroidStudio3.2+smalidea+Xposed+BDOpen:http://www.bloguan.com/?id=518

 

 

前言

在开发过程中,debug 版本我们可以跟踪调试,查看bug等信息,但是 release 版本中只能去打 log 进行代码进行猜测,还有就是dump 堆栈等无法与代码直接交互的方法。无源码调试 指的是在没有源代码的情况下可以对 app 进行代码调试,逆向 smali 代码,然后查看其运行逻辑。对发现 release 版本问题的过程中可以让我们更块的定位错误。

 

工具及下载地址:

  • ①、apktool.jar 用于反编译smali,下载地址:    https://ibotpeaches.github.io/Apktool/ 
  • ②、Android Studio 用于 Android 开发调试的 IDE,下载地址: https://developer.android.google.cn/studio/
  • ③、smalidea-0.05.zip (目前最新版 0.05),AS 插件,用来给smali下断点,单步调试,
            下载地址:https://bitbucket.org/JesusFreke/smali/downloads/


 

 

1. AndroidStudio 安装 smalidea 插件:

 

先从官网下载 smalidea zip包,然后在 Android 中依次选择:    File   -->  Setting   将会弹出设置对话框

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第1张图片

然后在设置对话框依次选择:  Plugins   -->  <设置图标>  --> Install Plugin from Disk...

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第2张图片

在弹出选择对话框中,找到下载好的 smalidea 压缩包,选择ok即可

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第3张图片

点击 OK ,会重新启动 Android Studio ,至此,插件安装就完成了。

 

 

2. 反编译

 

目前常用的 Android 反编译工具有:

  • Baksmali:https://github.com/JesusFreke/smali
  • Apktool:https://ibotpeaches.github.io/Apktool/
  • dex2jar:https://sourceforge.net/projects/dex2jar/

 

第一步:当然是要拿到你想 debug 的 apk,这里随机使用一个 app

第二步:就是要把 apk 里面的编译后的代码转成 smali。

 

可以使用 baksmali 进行反编译,也可以使用 apktool 进行反编译

 

使用 Baksmali 反编译 apk 

baksmail 反编译命令:java -jar baksmali-2.2.1.jar  d myapp.apk -o ~/projects/myapp/src

$java -jar baksmali-2.0.5.jar debug.apk -o debug/src

 

使用 apktool 反编译 apk 

apktool 反编译命令:java -jar apktool.jar d myapp.apk -o ~/projects/myapp/src

使用命令 : java.exe -jar  apktool.jar d -f    -o

也可以直接使用 ApkTool 集成环境(如果反编译失败可以替换其中的 apktool.jar 至最新版):

这是使用 AndroidKiller 进行反编译( AK 下载地址:https://down.52pojie.cn/Tools/Android_Tools/

 

让 apk 可调式

这一步很关键,就是让运行在设备中的程序支持 debug。方法有几种:

  • 把设备 root 掉
  • 修改测试机的 /default.prop 文件的 ro.debuggable=1,目测这一步也可能需要 root。
  • 使用模拟器
  • 修改 apk 的 Manifest application 属性 android:debuggable="true",可以用 apktool 解出 Manifest 然后修改,接着重新打包回去。( 反编译 apk,修改 AndroidManifest.xml 的 debug 属性并在程序的入口处添加 waitForDebugger代码进行调试等待。 )
  • 打开系统调试总开关,使用 am 命令,以调试模式启动应用。
  • 终极办法,自己编译一个 debug 版的 rom,这个稍微麻烦一点,自己编一个,想怎么玩就怎么玩。

下面只说明两种方法,一种是 修改 " AndroidManifest.xml " 实现可调试 ,另一种是 打开系统调试总开关

 

修改 " AndroidManifest.xml " 实现可调试

使用 AndroidKiller 进行反编译,然后在反编译出的 AndroidManifest.xml 添加 debug 属性

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第4张图片

如果有说明可调试,如果没有设个属性的话,需要自己添加 android:debuggable="true" 然后编译安装 可调试的 apk

 

不添加代码的方法:

修改 AndroidManifest.xml 之后不用在程序的启动界面添加代码也行,只要以 am 命令运行程序就行了。

以调试状态启动 app

adb shell am start -D -n com.wizardev.testjar/.MainActivity

 并转发8700端口  [app_pid]

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第5张图片

记住这时候需要将DDMS关掉,不然会出现错误

 

添加代码方法:

  • 找到启动 apk 的启动界面,然后在启动界面的 onCreate 方法的第一行添加 invoke-static {}, Landroid/os/Debug;->waitForDebugger()V这句代码。

 

那么问题来了,我们怎么知道程序的启动界面呢?

其实可以通过以下几种方式:

方法 1:

观察 “AndroidManifest.xml” 文件中的代码,看下图

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第6张图片

如果图中 “1” 处的代码,那么程序启动界面的 smail 文件就是 “2” 处的名称。如上图启动界面的 smali 文件就是“MainActivity.smali”。然后在 “MainActivity.smali” 文件中的 onCreate 方法中添加等待调试的代码即可。用 am 命令,使目标程序以调试模式运行。

 

方法 2:

通过 adb 命令来发现 apk 的启动界面,命令:adb shell dumpsys activity top

运行命令后会出现以下界面

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第7张图片

图中用红框标记的就是启动界面的 smali 文件名。注:这种方式找到的启动界面可能不准确,因为有的 app 会有欢迎页,因此推荐用第一种方法来找 app 的启动界面。

主 Activity 中加入  invoke-static {},Landroid/os/Debug;->waitForDebugger()V

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第8张图片

回编译 apk 并签名安装到手机,如果启动 app 出现以下界面,则说明以启动模式运行app成功。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第9张图片

 

(这步如果重新打包失败,可以安装原始包,把手机 root 配置/default.prop 的 ro.debuggable=1 开启全局调试。

然后用命令启动 Activiry : adb shell am start -D -n package属性的值/android:name属性的值  )

 

 

打开系统调试总开关( 不用修改 " AndroidManifest.xml " )

 

  这种方法不用修改 “AndroidManifest.xml”,而且当你打开这个开关后手机中的所有 App 都是可以调试的了。但是这种方法操作起来比较复杂,而且手机必须是已经 root 过的,下面会详细描述怎么打开系统调试的总开关。

  这里会介绍两种方法,第一种方法是大家普遍采用的,但是我使用采用第一种方法没有成功,于是查找资料找到了第二种方法,如果你使用第一种方法不成功,那么可以试下第二种方法。

 

第一种方法

  • 1. 点击这里下载“mprop”文件。

  • 2. 依次运行一下命令设置 “ro.debuggable”

adb push “下载mprop文件所在的位置”\mprop /data/local/tmp/
adb shell su
chmod 755 /data/local/tmp/mprop
data/local/tmp/mprop
setprop ro.debuggable 1
/data/local/tmp/mprop -r
  • 3. 运行 getprop ro.debuggable 命令可以查看 debuggable 的状态,显示为 1,表示更改成功。

注:这种方法在开机后设置的“debuggable”将会失效,需要重新设置

 

第二种方法

这种方法其实说复杂也不复杂,说不复杂呢!还是有一点复杂的。具体操作方法如下:

  • 需要手机刷入“Magisk”,刷入方法就想卡刷手机系统一样,可以到这里下载zip包。
Magisk是什么:简单的说就是集成了root的框架,它强大的是root权限还可以设置对其他软件隐藏。
Magisk的强大远不止这点,想了解Magisk具有哪些功能可以自行搜索。
  • 通过Magisk安装“MagiskHide Props Config”模块,安装的方法可以看下面的动图。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第10张图片

安装完成之后需要重启,才能生效。

打开终端,输入以下命令

adb shell
props

会出现这个界面

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第11张图片

然后,输入3,回车,会出现这个界面

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第12张图片

然后,输入1,回车,出现这个界面

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第13张图片

可以看到图中显示当前的 “ro.debuggable” 的值为0,如果要修改为1的话输入“y”,回车即可修改完成。

接着终端会弹出是否重启,这时继续输入“y”重启,重启后修改的“ro.debuggable”才会生效。

经过以上5步,就可以打开系统调试的总开关,这时我们打开“Monitor”工具就可以看见当前运行的所有的所有进程了。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第14张图片

注:通过这种方式修改的 “ro.debuggable” 值,重启手机后不会还原,就是设置过后,手机重启后不需要再次设置。

 

打开系统调试的总开关后,这时通过 am 命令以调试模式启动应用,即可让目标应用处于可调式状态。

adb shell am start -D -n xxx

这里的 “xxx” 为我们要调试应用的启动界面,如我们要调试应用的启动界面为 com.wizardev.testjar/.MainActivity 则输入以下命令

adb shell am start -D -n com.wizardev.testjar/.MainActivity

这是目标应用就会以调试模式运行,处于等待调试的状态。

 

 

3. 将 反编译后的smali  导入到 Android Studio 

将目标应用的 smali 源码导入 AndroidStudio。将 smali 源码导入AndroidStudio 挺简单的,只需要将反编译出来的 smali 文件夹放在工程项目中的模块的 src 目录下即可。

 

3.1 导入 smali 代码

简单的说一下操作方法吧。有两种方法导入: 

方法 1:新建工程导入 smali 代码

  1. 新建一个Android项目,不新建项目也行,但需要新建一个module。
  2. 将项目切换到project视图,将新建的项目下 app 中 src 目录下的代码删除或将新建的 module 下 src 目录下的代码删除。
  3. 将我们反编译的 smali 文件夹放入 src 目录下。

这样,就将反编译的 smali 文件导入到 AndroidStudio 目中了。操作后的目录界面大致如下。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第15张图片

方法 2:不新建工程导入 smali 代码

步骤总览:

  • Import Project... -> Create project from existing sources
  • 将 Project(ALT+1)里面默认的 Android 视图切换为 Project 视图,将 src 设置为 Sources Root.
  • Project Structure(Ctrl+Shift+ALT+S),Project SDK设置为 Android API 10 Platform
  • 远程调试配置,Run -> Edit Configuration进入Run/Dubug ConfigurationsAdd New Configuration(+符号) -> Remote,将 5005 端口,修改为 8700 端口。

图示说明:

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第16张图片

默认选择 Create project from existing sources ,一路 next ,最后点击 Finish 即可

 

3.2 导入工程后设置 Sources root

用 Project 视图,在项目目录右键  --> Mark Directory as ... --> Sources root

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第17张图片

 

3.3 设置 Project 的 sdk:

如果是通过 "新建项目" 导入的 smali ,则不需要设置 sdk,因为 新建工程 时已经有默认的 sdk

如果是通过 " 导入已经存在的 " 方式导入 smali ,则需要设置 sdk :

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第18张图片

选择 sdk ,这里选择 sdk  1.8

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第19张图片

 

 

3.4 配置 远程调试 ( 远程 debug 配置 )

添加一个 remote 调试,

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第20张图片

或者:

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第21张图片

修改调试的端口:8701 (未占用端口均可)

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第22张图片

安装设置 debug=true 的 APK,在需要的地方打好断点,通过以下命令行启动进程调试等待模式:
启动第一个 Activity 然后等待 debug: adb shell am start -D -S -W 包名/MainActivity(带路径)

命令行启动调试模式,adb shell am start -D -n packagename/ MainActivity
packagename 为进程名,MainActivity 为首页 Activity
启动调试 app,通过 adb shell dumpsys activity top | grep --color=always ACTIVITY 在终端获取包名和页面信息。

进入等待调试

获取运行 apk 的进程(pid): adb shell ps | grep 包名

  • 示例:adb shell ps | findstr "zhuceji" ,如下图所示,可以看到 pid 是 3170

端口映射: adb forward tcp:8701 jdwp:

  • 执行:adb forward tcp:8701 jdwp:3170    建立端口转发,即把端口 8701 上面的信息通过 jdwp 转发到 pid 是 3170 上面

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第23张图片

进入等待调试后,在 Android studio 中执行 Run -> Debug 启动刚才创建的远程调试器,进入动态调试了。

在 Android Studio 选择附加

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第24张图片

图二

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第25张图片

此时,已经 Attach 到进程中,可以快乐的调试了。通过断点可以查看内存的信息。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第26张图片

 

 

设置 AndroidStudio 为远程调试模式

  按下面的步骤操作,将AndroidStudio运行模式设置为远程调试模式。

工程配好了,配置 debug 的端口:即 远程调试配置,Run -> Edit Configuration 进入 Run/Dubug ConfigurationsAdd New Configuration(+符号) -> Remote,将 5005 端口,修改为 8700 端口。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第27张图片

在出现的界面,点击左上角的“+”,在出现的下拉列表中再点击“Remote”,添加一个 remote 调试

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第28张图片

设置远程调试的名称和监听远程的端口

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第29张图片

在图中1处修改远程调试的名称,不修改直接用默认的也行。在2处修改远程调试服务端监听的端口,一般设置为“8700”,当然也可以设置成当前调试项目所在的端口,可以在 “Monitor”工具中查看项目所在的端口。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第30张图片

( 也可以用 8700 端口,然后启动 ddms 去设置端口号映射,然后 apply -> ok。设置端口号映射后 ddms 监听的 8700 端口和转发的端口都可以接收到数据。 好了,project 方面就准备好了! )

可以看到当前调试的项目有两个远程服务端端口,“8700”端口是每个调试程序默认的远程端口,如果不想每次运行程序都重新设置一下端口,2处设置成“8700”就行了,然后点击OK完成修改。这时你会发现可运行的程序中多出了一个你刚才设置的调试项目名称。

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第31张图片

如上图,这里我直接使用默认的调试名称,则可运行的项目中多出了一个“Unnamed”选项,我们选中这个就行了,这时Android Studio就在“8700”端口监听项目的运行了。

 

以调试模式运行并将进程映射到8700端口

  1. 用 am 命令,使目标程序以调试模式运行。
  2. 将进程映射到 “8700” 端口,使用命令:adb forward tcp:8700 jdwp:进程id

进程 id 可以在 “Monitor” 工具中查看,如下图

也可以运行 adb 命令查看,用 adb 命令查看进程 id 的命令如下:adb shell ps | grep 包名

完成了以上两步,接着在AndroidStudio点击Debug选项,如下图

然后就可以打断点调试项目了。

注:在点击Debug选项运行项目之前,需要先将“Monitor”工具关掉,否则会提示8700端口被占用,无法进行动态调试项目。

 

接下来需要准备的就是如何连上设备debug了!过程也很简单,启动DDMS
Tools -> Android -> Android Device Monitor 选择你要调试的 apk 的包名

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第32张图片

最后,开始 debug。Run->Debug Smali

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第33张图片

针对 DDMS 端口转发,也可以手动的制定端口信息,操作如下(smalidea的作者推荐的是ddms的方式):

  1. 拿到 apk 的包名和启动的Activity,把应用启动起来然后等待 debug
    cmd 执行命令:adb shell am start -D -S -W packageName 
    ( packageName 的获取可以反编译 AndroidManifest.xml 里面有包含 )

正常的话,你会看到设备里的应用已经跑起来了,并且有个 Waiting For Debugger 的提示,别关掉它。

  • 1. 拿到程序运行的pid: adb shell ps | grep packageName
  • 2. 端口映射: adb forward tcp:8800 jdwp:5413   这里的 8800 是上一步在配置工程中自定义的端口。

 

官方步骤如图所示:

安卓逆向_13 --- AndroidStudio + Smalidea 动态调试 smali 代码_第34张图片

 

以上就是基于smalidea无源码调试的整个过程,有问题的可留言,我们一起交流学习。

 

 

结束语

  动态调试步骤是有点复杂,其实熟悉之后就没多大感觉了,简单设置几下就行了。可能有的手机不能root,这时就只能修改“AndroidManifest.xml”文件了,修改之后不用在程序的启动界面添加代码也行,只要以 am 命令运行程序就行了。

 

 

 

 

 

 

你可能感兴趣的:(Android,逆向)