- A+
下面列举了本次攻击演示所需要的所有工具:
Java(推荐1.7版本)
IDE(Eclipse,IntelliJ IDEA,Android Studio,三者任选其一)
Android SDK(https://developer.android.com/sdk/index.html?hl=i)
APKTool(https://code.google.com/p/android-apktool/)或者APK Studio(http://apkstudio.codeplex.com)
安卓设备/模拟器
Dex2Jar(https://code.google.com/p/dex2jar/)
JD-GUI(http://jd.benow.ca/)
在这篇博文中,我将使用Windows8系统、APKStudio和IntelliJIDEA来演示。我所使用的安卓手机是普通的Nexus4,系统版本是Android4.4.4。推荐大家将所有工具都添加到path环境变量中,这样用起来比较方便。
接下来我们就先设置一下手机,为下面的步骤做好准备。
首先我们需要做的就是确保我们的安卓手机启用了USB调试功能,这也是我们可以使用AndroidSDK工具集来与手机通信的前提条件。要做到这一点,我们需要启用开发者选项功能。
下一步,我们通过进行“Settings”=>“Developeroptions”=>”USBdebugging”来访问开发人员选项并启用USB调试功能。
将手机与电脑通过USB数据线连接之后,会提示“USB调试已经连接上设备”。接下来,我们要确保ADB(安卓调试桥)可以连接到手机。ADB是AndroidSDK工具集内包含的一个软件工具。我们在Windows系统控制台(cmd)上输入以下代码:
正常情况下将会出现下图所示的结果:
如果你的电脑上没有提示上图中的内容,那么很可能是系统中没有安装正确的驱动程序。你需要重新安装该驱动,驱动程序可以从AndroidSDK或者手机制造商的网站获得。
当调试安卓应用程序的时候,我们首先要检查该应用程序是否开启了调试功能。可以通过以下几种方法来检查是否开启了调试功能。
如果安卓手机里面的某个应用设置为可调试,那么该应用程序会出现在该列表中。在这里我创建了一个测试应用程序,我们可以看到该程序并没有出现在该列表中,表明该程序我设置为了不可调试。
如果你没有目标应用的APK文件,那么就必须先从手机中导出该APK文件。每当我们从GooglePlay商店中下载应用时,系统都自动下载了该应用的APK文件,并将其存储在了安卓设备上。这些APK文件的位置通常在手机中/data/app目录下。如果你的手机还没有root过,可能你将不能查看该目录下的文件。然而,如果你知道目标APK的名字,那么也可以通过adb工具将该APK文件转存到电脑中。为了查找目标APK文件,我们可以打开一个Windowsshell并输入以下指令:
这时将产生一个连接安卓设备的shell,然后输入:
这条指令将列出安卓设备上所有应用的安装包。
通过查看结果列表,我们就能找到目标应用。
接下来,需要将该APK文件导入到电脑中。为此,我们需要新打开一个shell并输入以下指令:
到这里,我们已经得到了目标APK文件。然后我们将打开该文件并检查里面的AndroidManifest.xml文件。不幸的是,我们不能直接解压该APK并查看xml文件,因为它是经过二进制编码处理过的,所以首先必须解码才可以。目前针对该问题最受欢迎的工具是apktool。不过,最近我一直在使用APKStudio软件,因为它有一个易于操作的友好界面。所以,在接下来的演示中我都使用APKStudio。
为了开始使用APKStudio,单击绿色的安卓小图标。然后在弹出的窗口中填写项目名称并选择待分析的APK文件,最后设置文件保存的位置。
apktool和APKStudio比较好的一点是,可以编辑任何反编译的APK文件并重新编译它们。接下来,我们通过添加“android:debuggable”标记来启用该应用的调试功能。编辑AndroidManifest.xml文件,然后在里面添加‘android:debuggable=”true”’。
添加该标记之后,通过单击菜单上的锤子图标重新创建APK文件。我们重建的APK文件会被保存在build/apk目录中。
重建的APK文件只有在签名之后才能够安装到设备上。所有的安卓应用都需要签名,但大多数应用程序并不检查它们是否是用原始的证书进行签名的。如果此时应用程序检查了证书的原始性,那么直接签名可能就没效果了,除非我们同时也编辑了验证数字证书的相关代码。
接下来,我们需要安装刚刚重建的APK文件。首先,卸载手机中原有的应用程序。然后使用adb重新安装重建的APK文件,输入以下指令:
然后检查并确保重新安装的应用在安卓设备上正确地运行。如果一切正常,那么我们回到安卓设备监视器界面并刷新一下,此时可以看到我们的应用已经显示在列表中了。
既然现在我们的应用已经可以调试了,那么接下来可以将调试器附加在它上面。在做这之前,我们需要设置一下IDE。在这篇博文中,我使用IntelliJIDEA。首先,我创建一个新的安卓项目,该项目名字可以随意取,但是包名字必须跟APK文件的包结构相同。
以上这些都很容易实现。但是,如果你还不确定,可以查看下APKStudio中该APK文件的包结构。对于我的这个应用来说,包结构就是APK的名字“com.netspi.egruber.test”。可以在APKStudio中查看如下图所示。
取消选中“CreateHelloWorldActivity”项,其它的地方使用默认设置,这就完成了项目的创建。此时,你的项目结构看起来应该是这样:
现在已经创建好了项目,就可以将APK文件的源代码导入到该项目中。我们之所以要这么做,是因为调试器知道关于该应用的所有符号名字、方法、变量等信息。安卓应用程序比较好的一点是,它们可以轻松地通过反编译来得到正确的java源代码。接下来我们就需要这么做,然后将源代码导入到IDE项目中。
首先,为了得到源代码,需要将APK文件转换到jar文件。然后,可以使用一个java反编译器来恢复到java源代码,我们使用dex2jar工具来进行此步骤。Dex2jar包含一个d2j-dex2jar.bat文件,通过执行该文件就可以将APK文件转换成jar文件。它的语法很简单:
到这里,你应该得到了一个jar文件。下一步,我们将使用工具JD-GUI来打开该jar文件。
现在你应该可以看到jar文件的包结构啦,包里面都是可读的java源代码文件。接下来我们通过选择“文件”=>“保存所有文件”来将源代码保存为一个zip文件。
保存源代码之后,将其解压到当前目录中。
现在我们需要将这两个目录导入到之前创建的安卓项目中。对于IntelliJIDEA来说,进入到项目的src文件夹并将这两个目录粘贴到这里。
在IntelliJ中,如果我们返回到项目中,则项目结构将会刷新。
单击其中一个导入的活动文件将会在右边的窗口中显示该文件中的源代码。在下面的截图中可以看到,我导入的源代码是使用ProGuard混淆过的。
现在我们的项目中已经填充了应用程序的源代码,我们就可以开始设置断点。在这个例子中,我在一个方法处设置一个断点,当向一个文本输入框中输入内容的时候程序就会调用该方法。即使代码是经过混淆过的,也可以正常工作。
设置断点后,单击主界面右上角的小屏幕图标弹出安卓设备中的进程列表,该列表只列出可以调试的进程,然后单击目标进程将调试器附加到该进程。当然,不同的IDE对应的功能图标不同。
选中目标进程之后,调试器就连接到了安卓设备。
在我测试的应用中,我将向文本输入框中输入数字42,别忘了之前我们在这里设置了断点。
在单击“EnterCode”按键后,进程执行到断点处时会暂停。之所以这样能够正常工作,原因是调试器知道在安卓设备上该调用什么程序。编译后的安卓应用中包含了调试信息,例如变量名字,任何理解java调试线协议(JDWP)的调试器都可以识别这些信息。如果一个安卓应用允许调试,那么一个兼容JDWP的调试器,例如大多数的JavaIDE,将能够连接安卓虚拟机并读取和执行调试指令。
此时,我们就能够在变量区域窗中查看到我们向应用中输入的内容。
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫