×

AndroidStudio无源码动态调试apk

96
奋斗der小鸟
2017.10.27 15:52* 字数 2198

其实说白了就是AndroidStudio动态调试Smali,一直在用的方法,挺有效的逆向分析方法。把apk反编译成Smali然后倒入AndroidStudio中,然后通过jdwp调试相关进程。

基本技能

  • 会使用AndroidStudio的debug的功能,不会的看这里
  • 能够理解简单的Smali语法看这里
  • 能够使用apktool反编译apk,并且重新打包,不会的看这里

工具

  • AndroidStudio 最好是最新版本,我用的是2.3 最近好像3.0的正式版出来了
  • smaliidea-x.x.x.zip这个是AndroidStudio的插件,从这个链接的列表中下载那个,最新版本的zip文件插件的官网
  • apktool 反编译apk->Smali 并且重新打包修改后的Smali到apk
  • jadx 用了查看Smali对应的java代码,增加可读性

插件安装:上面那个zip包下载完成后,打开AndroidStudio选择
Android Studio -> Preferences -> Plugins -> Install plugin from disk -> 选择 smalidea.x.x.x.zip 插件 ->重启 -> 插件就安装好了。

动态调试Smali文件

1. 调试的前提条件 使app可调试

开发过Android的都知道,要想调试一个apk的前提是这个apk是可调式,一般我们发版的时候,会发release版。(在一开始的时候,我们开发Android是没有gradle的,那时候发release版不像现在在gradle配置好就行了,是直接操作AndroidManifest.xml文件中 <application>标签的 属性 android:debuggable="true")因为在一般的手机上,release版本的应用是不可以被调试的,相对来说起到了保护app的作用。

上面说了是在一般的手机上,从上面来看,可以在AndroidManifest文件中设置debuggable开关,那么这个开关是被谁来验证的呢?答案是系统,Android系统会通过debuggable 验证一个app是不是可以调试。可以不可以关掉系统的验证?答案是可以的。不过很麻烦,据说有两种方式可以修改,一种是重新刷入boot.img 修改方法,另一种是通过xpost修改。

而我们平常用的最多的就是,修改AndroidManifest.xml 中的android:debuggable="true",然后重新打包apk。

逆向工程不是普通的反编译,一般来说逆向都是带有目的的。我们拿最近我用到的WPS 的Android版(WPSOffice_206.apk)来测试,在这里不讨论逆向的目的。我们来处理这个apk,使它可以被被debug。

  • 首先 通过apktool d WPSOffice_206.apk来反编译
  • 然后 在生成的目录中找到AndroidManifest.xml,用AS或者文本编辑器打开修改里面的<application>标签,如果有debuggable属性,修改为true,如果没有,给<application>标签添加android:debuggable="true"
  • 最后 apktool b WPSOffice_206 这时候会在./WPSOffice_206/dist目录下生成重新打包好的apk。(注意这个地方会出现重新打包的错误,文章最后给出解决方法)然后要给这个apk签名。文章开始给出的相应的文章。
  • 然后我们把这个自签名后的apk安装到手机就可以了

2. 导入Smail源码到AndroidStudio中

打开as后,通过File-->Open ...选择我们刚才反编译处理的那个目录,WPSOffice_206,然后等待as建立完索引。
注意左侧选择Project视图,如下所示:

2.0-Project视图.png

然后右键工程主目录:Mark Directory As -> Sources Root

2.1-SourcesRoot视图.png

然后设置sdk,最后和测试手机的系统版本一致:项目目录-->右键-->Open ModuleSettings:

2.3-设置sdk.png

3. Android Studio 的配置

接下来配置:Run/Debug Configurations里面的配置文件:

3.0-配置文件入口.png

打开后我们点击上面的+符合,然后选择Remote,添加一个远程调试如下图:

3.1-添加remote调试.png

然后配置远程调试的端口和一些其他信息,如下图:

3.2-配置远程调试端口.png

注意,上面的Name可以随便写,因为每一个Remote配置都对应手机app上的一个进程,每一个手机app可能有多个进程,所有名字上我们做下区分。另一个需要配置的地方是Port,这个port也可以随便写,只要当前电脑上没有是用这个端口就好,如果要同时调试手机上的某个app的多个进程,这个每次配置Remote的时候,port不能一样。我们这里是用默认的5005。

4. 打通AndroidStudio和可调试apk之间的通道

手机上已经安装了我们前面重新打包的可调试的wps的apk。运行它

4.1 查看wps的所有的进程信息

然后命令行运行adb shell ps | grep cn.wps.moffice_eng

4.1-查看当前WPS的进程.png

4.2 判断你要debug的那个页面(Activity)在哪个进程里面

首先打开这个页面,然后命令行运行:
adb shell dumpsys activity | grep mFocusedActivity
这会得到当前显示的Activity的名字,然后去AndroidManifest.xml中去查看这个Activity的信息,里面会有进程信息。

4.3 端口映射

adb forward tcp:5005 jdwp:29685

设置端口转发,这条命令的含义可以认为是在本地5005端口与手机29685进程之间建立一条通道,当开始调试时,AS连接本地的5005端口,通过这条通道控制程序的运行。这个5005是前面(图3.2)中配置的端口,这个29685是wps在手机上运行的一个进程的进程id。(图4.1)中获取的。

4.4 下断点

这个随便下,和平常一样,只要下到你想要程序暂停的地方就好,我们把断点下到wps的首页,通过adb shell dumpsys activity | grep mFocusedActivity这个命令可知道首页叫cn.wps.moffice.main.local.HomeRootActivity

4.4.1-测试断点.png

注:这里把断点下到了首页的onResume方法中是为了测试用,因为onResume方法会被调用很多次,当我们按home键,然后在打开wps的时候这个方法就会被调用。不说了,如果连onResume的调用时机都不知道还搞什么逆向。

4.5 启动debug

4.5-启动调试.png

首先选择要调试的配置,然后点击那个调试按钮。如果左下角出现下图说明启动成功:

4.5-启动调试成功.png

试试打开个别的应用,然后再切回wps,这时候程序会停在断点处。

5 举个例子

举个例子:以WPS的创建ppt为例,我们来把断点打到创建ppt上,然后调试这个ppt的创建流程。

我们打开WPS后,右下角有个很大的红色加号,点击这个后会有创建选项,我们选中创建PPT,然后选择新建空白文档。会看到如下图所示

5.1-wps创建ppt.png

这个时候我们运行adb shell dumpsys activity | grep mFocusedActivity
会得到

mFocusedActivity: ActivityRecord{50a4e0a u0 cn.wps.moffice_eng/cn.wps.moffice.presentation.multiactivity.Presentation1 t306}

还是截图来看吧:

5.2.1-获取栈顶wps.png

现在拿到这个Activity的名字了,我们再来看这个Activity在哪个进程里面,这就需要通过AndroidManifest.xml了。

        <activity android:name="cn.wps.moffice.presentation.multiactivity.Presentation1"
            android:configChanges="fontScale|keyboard|keyboardHidden|navigation|orientation|screenLayout|screenSize|smallestScreenSize|uiMode"
            android:hardwareAccelerated="true" android:icon="@drawable/public_icon_activity_ppt"
            android:label="@string/activity_label_ppt" android:launchMode="singleTask"
            android:process=":presentation1" android:taskAffinity="cn.wps.moffice_eng.presentation1"
            android:theme="@style/PptTheme"
            android:windowSoftInputMode="adjustNothing|stateHidden" />

看到android:process的值了没,就是这个Activity所在的进程。然后我们拿大这个进程号就可以调试了。

命令行运行adb shell ps | grep cn.wps.moffice_eng如下图:

5.2.2-wps创建ppt的进程信息.png

然后配置debug config

5.3-pptdebug配置.png

设置端口转发:
adb forward tcp:5006 jdwp:31333

然后运行debug:

5.4-运行ppt debug.png

运行成功视图:

5.5-运行ppt debug结果.png

这是后在点击创建一个ppt,然后程序就会在断点处暂停如下图:

5.6-调试创建ppt成功示意图.png

剩下的调试面板的使用和普通的Android调试一样,前面给出的文章已经有啦。通过这个调试面板可以跟踪变量,查看调用堆栈,类之间的跳转。等等非常有用。

最后一个bug处理

在修改完 wps的 AndroidManifest.xml 然后执行apktool b WPSOffice_206的时候。apktool会抛出下面的错误:

981B2FE0-3916-4AA3-B090-96E924A5A341.png

可以看到打了一大堆乱七八糟的log,其实都没用,只看第一行就行,说在 AndroidManifest.xml 的第61行有个不能被识别的资源标识符'resizeableActivity',打开AndroidManifest.xml 然后全局搜下这个字符串:

屏幕快照 2017-10-27 15.50.52.png

这玩意不知道有啥用,把这个属性删了就行,好像是为了简单组织重打包的一个混淆操作。

Android逆向
Web note ad 1