Debugging Dalvik programs with IDA

翻译:无名侠 

 

引言

自从IDA v6.6 开始就能够调试安卓应用程序,也包括一个源码级的调试器。这个教程将会讲解如何建立并且开始一个Dalvik调试会话。


安装Android SDK

首先,我们应该安装安卓SDK,可以通过官方网站下载 http://developer.an droid.com/sdk

我们不需要ADT Bundle,所以选择”SDK Tools Only”,只要下载它就可以了。

 

环境变量

IDA 需要知道 adb模块在什么地方,并且尝试各种各样的方法去在本地自动的寻找它。通常IDA通过路径去寻找adb,但是如果失败了,我们就需要定义环境变量 ANDROID_SDK_HOME或者ANDROID_HOM 来指定Android SDK的安装目录。

Android 设备

运行安卓仿真器或者通过USB来连接一个安卓设备。

 

关于创建AVDsAndroid Virtual Devices)的信息和如何运行仿真器可以在这里找到:Using the Emulator.

 

关于准备一个物理设备的信息可以在这里找到:Using Hardware Devices.

检查设备是否能被计算机识别,通过adb:

$ adb devices

List of devices attached

emulator-5554 devic

 

安装应用程序

IDA  认为被调试的应用程序已经安装在安卓虚拟机或者安卓设备上。

请在我们的网站上下载 MyFirstApp.apk MyFirstApp.src.zip我们将要用这个应用程序来讲解后面的教程。

 

我们将要使用adb来安装应用程序:

adb –s emulator-5554 install MyFirstApp.apk


加载应用程序到IDA

我们能把apk或者dex文件拖入IDA。如果我们拖入的是apk文件,IDA会显示该文件的内容并且询问我们选择我们需要反汇编的文件。我们选择 classex.dex 文件:


Dalvik debugger options

在启动调试之前,调试器允许我们检查调试配置。 到“Debugger/Debugger Options/Set specific options”

译者补充图:


原版图:


ADB执行文件

正如上面提到的,IDA试图定位adb 的位置,如果IDA失败了,那么我们可以在这里设置adb的路径。

 

Fill from AndroidManifest.xml

按下这个按钮,然后给IDA指明一个APK(这个就是要调试的APK)。IDA获取包名和应用程序的activity 名字来启动。

 

预处理 BPTs

IDA 能帮助我们在启动调试前为activity 类的方法设置断点。

 

 

源码路径

为了 使用源码源码级调试器,我们需要设置应用程序的源码路径。我们能在Options/Sources path … 菜单项中设置。

Dalvik 调试器认为应用程序的源文件在当前目录.下。如果这不是实际的情况,我们能指定源码路径到源码的真实路径。

 

 

设置断点

在启动应用程序以前,设置一些合理的断点。我们可以依赖IDA的决定也可以自己设置断点。一个非常好的候选断点是 activity的“onCreate”方法。

我们能使用一个activity 的名称和方法的名称 “onCreate”来设置一个断点:


 自然地,我们设置其他的断点可以在任何时间,比如,我们能稍后来完成它,当我们暂停应用程序的时候。

 


开始调试

至少我们现在可以启动调试了。检查Dalvik 调试器 被选中,通常它是IDA自动选择的:



如果调试器选择正确了,我们就准备启动调试会话。 这里有两种方式来启动:

1. 启动一个新进程(Start process)

2. 附加进程(Attach to process)


1. 启动进程

 为了启动一个新的进程,只用按F9或者选择“Debugger/Start process” 菜单项。

Dalvik调试器会启动应用程序,等待直到应用程序已经准备好并且打开一个调试会话。

 

我们可能会等待执行程序接收到断点或者按下“Cancel”按钮来暂停应用程序

在我们的例子里,让我们等待,直到onCreate()  方法的断点停下来。

 


2. 附加进程

代替启动进程的是附加进程,我们能够附加一个正在运行的进程并且调试它。可以在“Debugger/Attach to process…” 找到。 IDA会显示活动进程的列表。


我们只选择我们想调试的进程


Dalvik 调试器的细节

所有传统的调试动作比如步过,步入,运行到返回和一些其他的操作都能使用。如果应用程序的源程序能被访问,IDA会自动的切换到源码级调试器。

以下是Dalvik虚拟机调试器特性:

Dalvik中,这里没有栈,也没有SP寄存器,唯一可用的寄存器是IP寄存器。

IDA把方法框架中的寄存器 (v0,v1,v2...) 是作为局部变量。我们能够在Debugger/Debugger Windows/Locals window (见后文)中看到它们的身影。


栈跟踪可以在 “Debugger/Windows/Stack trace” 中看到,或者按下<Ctrl-Alt-S>调出。

 

当应用程序运行的时候,它可能执行一些系统代码。如果我们通过“Cancel”按钮打断程序的执行,经常会发现我们在应用程序的外部,在系统代码中。 在这种情况下,IP寄存器的值是0xFFFFFFFF ,并且栈跟踪器只显示了系统调用和许多的0xFFFFFFFF 。这意味着IDA不能定位程序当前的位置。我建议你多在程序中设置一些断点,重新开始执行,并且通过点击窗口,选择菜单等方式与应用程序交互。当我们步出了应用程序,这样的情况也会发生。

 

使用 “Run until return” 命令来返回源码级调试器,如果你不小心单步进入了一个方法,并且IP寄存器的值是0xFFFFFFFF

 

局部变量窗口

IDA把方法框架中的寄存器(v0.v1.v2...)当作局部变量。可以在

“Locals” window from the “Debugger/Debugger windows/Locals” 菜单功能中查看它们的值。


此时此刻,调试器暂停在程序的“onCreate”方法断点上。让我们打开“Locals”窗口,我们能够看到如下东西:


如果这个框架的信息是有用的(符号表是完整的),那么IDA会显示方法的参数,这个方法的局部变量以及一些没有符号的变量。另外,一些变量的值不会显示,因为IDA不知道它们的类型。

 

 

没有类型的变量会被标记为“Bad Type”在局部变量窗口 

为了看见这些变量的值,在这种情况下请用“Watch view” 窗口(见下文)

 

Watch view window

 

为了打开“Watch view”窗口,请选择“Debugger/Debugger windows/Watch view”菜单。

在这个窗口,我们能添加任何变量来查看它的值,如图:


请注意,我们需要为变量指定类型,如果这个变量是未知的。使用C风格:

(Object*)v0

(String)v6

(char*)v17

(int)v7

 

我们不需要为对象变量指定真实的类型,“(Object*)”就足够了。IDA能够推导出真正的对象类型。

 

注意!一个错误的类型可能或造成Dalvik虚拟机崩溃

我们的建议是:不要把integer变量 设置为object类型。Dalvik虚拟机通常会崩溃,如果我们这样做。 在实际应用中,整数(int)是安全的。如果“object ID safety check”选项选中的话,IDA会防止这种情况,唯一的缺点是这个选项增加更多的开销。记住下面这句话,请不要把这些留在“Watch view” 太多时间。 在其他能改变它们类型的指令执行前删掉它们。

 

如果遇到一些错误

· 在“Debugger specific options”设置中检查adb的路径。

   检查包名和activity 名称。

· 检查模拟器/设备 是否被adb 识别,尝试重启adb守护程序。

   检查这个应用程序是否成功安装在模拟器或者设备上。

· 检查 IDA 的 output 窗口,查看所有错误和警告。

    打开更多的调试输出。在启动IDA时用 -z50000 命令行开关打开






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《debugging with gdb》是一本关于使用GDB进行调试的指南。GDB(GNU调试器)是一个强大的调试工具,可以用于调试各种编程语言,如C、C++、Fortran等。 这本书详细介绍了GDB的安装和配置,并提供了许多示例来说明如何使用它来调试程序。它从基本的调试命令开始,如设置断点、单步执行、查看变量的值等。然后,它介绍了更高级的调试功能,如条件断点、观察点、跟踪函数调用等。 书中还介绍了如何使用GDB来调试多线程程序和动态库。它解释了如何设置线程断点、查看线程状态和跟踪线程的执行路径。此外,它还介绍了如何对动态链接库进行调试,包括加载和卸载库、查看库中的符号和调用库中的函数等。 此外,《debugging with gdb》还介绍了如何使用GDB进行内存调试。它涵盖了诸如检测内存泄漏、跟踪指针问题和查找内存错误等主题。通过这本书,读者可以学习如何使用GDB来诊断和解决各种程序错误和问题。 总之,《debugging with gdb》是一本全面而详细的关于使用GDB进行调试的指南。无论是有经验的开发人员还是初学者,都可以从中学习到如何使用GDB来快速定位和解决程序中的错误。 ### 回答2: GDB是一个调试器,用于帮助开发者在程序中找出错误并进行调试。它提供了许多功能和命令,可以让开发者在程序运行过程中获取各种有用的信息。 在使用GDB进行调试之前,首先需要将程序编译成可调试的二进制文件。可以使用编译器的参数“-g”来生成包含调试信息的可执行文件。编译完成后,可以通过终端命令"gdb <可执行文件名>"启动GDB,并载入要调试的程序。 一旦进入GDB调试界面,可以使用各种命令来控制程序的执行。例如,可以使用"break <函数名>"命令在特定的函数内设置断点,当程序执行到该函数时会触发断点,并暂停程序的执行。可以使用"run"命令来运行程序,当程序遇到断点时会暂停,并在终端显示相关的调试信息。 一旦程序暂停在断点处,就可以使用GDB提供的许多命令来检查程序状态和寻找错误。例如,可以使用"print <变量名>"命令来打印特定变量的值,以确定其是否符合预期。还可以使用"step"命令来逐行执行程序,并跟踪程序的执行流程,以查找错误所在。 在调试过程中,还可以使用其他命令来查看函数调用栈,设置条件断点,监视特定变量的值等。通过这些命令的使用,可以逐步分析程序的执行过程,找出其中的问题,并进行修复。 在调试完成后,可以使用"quit"命令退出GDB调试界面。调试信息和步骤可以记录下来并与其他开发者共享,以便更好地协作解决问题。 总之,GDB是一个功能强大的调试器,它可以帮助开发者定位和修复程序中的错误。通过使用GDB,开发者可以更加高效地进行程序调试,提高开发效率。 ### 回答3: 《debugging with gdb》是一本介绍使用GDB进行调试的书籍。GDB是GNU工具链中的一个强大的调试工具,用于分析和修复程序中的错误。 该书详细介绍了GDB的各种功能和用法,并通过实例演示了如何利用GDB进行程序调试。它提供了许多实用技巧和建议,帮助读者快速定位和解决程序中的bug。 书中首先介绍了GDB的基本用法,包括启动程序、设置断点、执行程序、查看变量值等。接着,它详细阐述了GDB的高级功能,例如条件断点、观察点、内存调试等。 此外,书中还介绍了GDB调试多线程程序、动态链接程序和嵌入式程序的方法。针对不同的调试需求,它还介绍了GDB的执行控制、堆栈跟踪和源代码级别的调试等高级特性。 《debugging with gdb》还提供了一些常见问题的解决方案,如内存泄漏、数组越界、死锁等。它还解释了一些常见错误的原因和调试技巧,帮助读者更好地理解和定位程序中的问题。 通过阅读《debugging with gdb》,读者可以更好地理解和掌握GDB的使用方法,提高程序调试的效率和准确性。无论是新手还是有经验的程序员,都可以从中受益,提升自己的调试能力。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值