IDA操作知识记录

6,743 阅读10分钟
原文链接: kingerwu.com

前言

本文大部分内容节选IDA Pro权威指南,部分内容节选看雪论坛。

常用视图

  • Function window:列举了IDA识别的每一个函数,双击函数可实现跳转。
  • IDA View-A :反汇编窗口,分为图形模式与文本模式,通过空格可以进行切换。
  • Hex View-1 :十六进制窗口,与IDA View进行配套,通过右键可以调整数据展示,F2快捷键可以修改数据(常用于动态调试 nop 命令 – 00 00 A0 E1)。
  • Exports:导出窗口,列出文件的入口点,双击导出条目可实现跳转。
  • Strings window 或 Shift + F12:显示从文件中提取出来的字符串以及字符串所在地址,双击导出条目可实现跳转。右键Setup 可以修改匹配条件(Ignore instructions/data definitions 忽略指令/数据定义,勾选此项,会使IDA扫描指令和现有数据定义中的字符串)
  • Function Calls : 函数调用窗口,可以看到所有调用该函数的位置和当前函数做出的全部调用

以上视图均可以通过 View-Open subviews 控制打开关闭。
部分窗口,Ctrl + F可以快速检索条目。

部分自动生成的名称前缀含义:

  • sub_xxxxxx: 地址xxxxxx处的子例程
  • loc_xxxxxx:地址xxxxxx处的一个指令
  • byte_xxxxxx:位置xxxxxx处的8位数据
  • word_xxxxxx:位置xxxxxx处的16位数据
  • dword_xxxxxx:位置xxxxxx处的32位数据
  • unk_xxxxxx:位置xxxxxx处的大小未知的数据

函数内自动生成的名称前缀含义:

  • var_xxxxxx:局部变量名称
  • arg_xxxxxx:函数形参参数名称(R0-R3表示形参1-4,第5个形参才会用arg表示)

反汇编导航

  • Jump-Jump to Address 或 G快捷键,可以打开地址跳转对话框。
  • Jump-Jump to Previous Position 或 ESC,后退按钮,跳转到前一个位置。
  • Jump-Jump to Next Position 或 Ctrl+Enter,前进按钮,跳转到下一个位置。
  • 图形话的快捷键如下图所示,下拉可以查看历史记录,方便快速访问。
  • Search-Text 或 Alt + T,弹出文本搜索框,Search-Next Text 或 Ctrl + T, 可重复前一次搜索操作,以找到下一个匹配结果。

栈帧、入栈、出栈规则

反汇编操作

  • IDA 不提供撤销功能,所以经常保存数据库,才能恢复到最近保存的数据库版本。
  • 选中一个函数名、局部变量名、参数名、寄存器名、地址名,通过右键-Rename 或 快捷键N,可以修改对应的名字,修改完成后,如果需要还原,只需要重命名时输入空字符串即可。
  • Edit-Comments 或 快捷键‘:’、‘;’:可为函数,代码行进行注释,‘:’与‘;’的区别是被‘;’注释的函数,在调用处也会显示注释内容。
  • Edit-Code 或 快捷键C,在指定代码行进行操作,IDA将尝试反编译所有字节为指令。(常用于反编译时,遇到DCB…什么等数据)
  • Edit-Data 或 快捷键D,在指定代码行进行操作,IDA将指令批量转换为数据。

Options-General… Disassembly选项卡

常用的勾选内容有:

部分名词解析:

  • Line prefixes 行前缀
  • Stack pointer 栈指针
  • Auto Comments 自动注释

数据类型与数据结构

我们在反编译安卓应用的时候,常常需要用的数据结构 IDA无法识别,故需在反编译过程导入jni.h文件才行。

  • File - Load file - Parse C header file… 或 快捷键Ctrl + F9, 即可弹出导入弹窗。
  • 在我们F5反编译出来的源码中,IDA无法正常识别的数据结构,可以通过右键-Convert to struct* 进行转换。

交叉引用

代码交叉引用

代码交叉引用的前缀为:CODE XREF
如下图显示,doSetShellState 被JNI_OnLoad +24 、 JNI_OnLoad+A0调用了,箭头方向表示引用位置的相对方向。

每一个交叉引用的最后一位后缀表示引用的类型:

  • o 普通流 ,表示一条指令到另一条指令的顺序流
  • p 调用流,表示控制权被转交给目标函数,如BL等命令
  • j 跳转流,表示分支操作,常见于if等操作

数据交叉引用

数据交叉应用的前缀为:DATA XREF
如下图所示,数据交叉引用

每一个交叉引用的最后一位后缀表示引用的类型:

  • r 读取交叉引用,表示访问的是某个内存位置的内容
  • w 写入交叉引用,指出了修改变量内容的程序位置
  • o 偏移量交叉引用,表示引用的是某个位置的地址(而非内容)

交叉引用列表

Jump - Jump to xref 或快捷键X,将光标放在一个交叉引用的目标地址上,通过该快捷键可弹出交叉引用列表。

动态调试配置

前提

一台已经root的Android设备,一根数据线, DDMS, mprop,apktool等工具;开好调试模式,连接上电脑。

环境配置步骤

  • 打开DDMS(Android Device Monitor)。
  • Shell命令,查看当前的debugable属性值。其中0是不能调试,1是能调试

    angler:/ $ getprop ro.debuggable
    0
    angler:/ $
  • 如果debugable不能调试,进入root shell, 执行mprop, 设置 debuggable 为 1

    angler:/ $ su
    angler:/ # cd /data/local/tmp/
    angler:/data/local/tmp # ./mprop ro.debuggable 1
    start hacking ...
    target mapped area: 0x400000-0x527000
    >> inject position not found, may be already patched!
    -- setprop: [ro.debuggable] = [1]
    ++ getprop: [ro.debuggable] = [1]
    angler:/data/local/tmp #
  • Nexus手机有selinux安全机制问题,需要关闭, 否则attach进程时,会报错误–Bogus or irresponsive remote server

    angler:/data/local/tmp # setenforce
    usage: setenforce [enforcing|permissive|1|0]

    Sets whether SELinux is enforcing (1) or permissive (0).

    setenforce: Needs 1 argument
    angler:/data/local/tmp # setenforce 0
    angler:/data/local/tmp # getenforce
    Permissive
    angler:/data/local/tmp #

调试配置步骤

  • 开启IDA调试工具android_server 输出以下内容(部分反调试,监控了23946,建议是换一个端口)

    angler:/data/local/tmp # ./as_debug -p1440
    IDA Android 32-bit remote debug server(ST) v1.19. Hex-Rays (c) 2004-2015
    Listening on port #1440...
  • 新启一个Shell,使用ApkTool,获取应用的入口,通过am 以 debug方式启动

    am start -D -n 包名/应用名
  • 新启一个Cmd,设置端口的转发, 用于连接调试

    adb forward tcp:1440 tcp:1440

这个时候,我们就可以通过IDA 关联到调试进程了,IDA 启动调试,有两种界面:

直接进入桌面的情况

执行路径:Debugger - Attach - Remote ARMLinux/Android debugger

因为配置过端口转发,所以直接设置127.0.0.1 1440(需要与android_server端口匹配)是能直接连到手机上的。

选择自己对应的进程,点击OK 即可。

已经加载过的情况

  • Attach to process… 操作同上述一样,直接可以选择挂载的进程了
  • Process options… 调试配置,通常需要修改里面的Hostname 与 Port,匹配本地的ip与调试端口
  • Debugger options… 一些调试的选项,一般用于操作挂载JNI_Onload等

开始调试

  • 通过DDMS获取 应用的调试端口号, 然后在cmd命令行中调用jdb进行调试(目的是让程序继续运行,不卡在Waiting For Debugger的界面)
    jdb -connect com.sun.jdi.SocketAttach:hostname=localhost,port=调试端口

其中DDMS的端口是指带有调试标志的那个进程的端口。

上述所有操作完成时,就能对程序进行调试了。

动态调试界面

这些视图可以通过 Debugger - Debugger windows 控制打开关闭。

  1. 调试快捷栏
  2. IDA View-PC, 反编译窗口
  3. Stack view 栈视图,显示进程运行时栈的数据内容
  4. General registers 通用寄存器窗口
  5. Hex View 十六进制代码块,通常可以通过操作这里,nop命令或对数据进行操作。
  6. Modules 模块窗口,显示进程镜像中当前加载的模块列表
  7. Threads 线程窗口,显示当前进程中的线程列表

调试快捷栏


所有操作都可以通过 Debugger 选项卡-列表子项中进行操作。

操作图标 快捷键 内容
F9 继续执行
暂停一个正在运行的进程
Ctrl+F2 终止一个正在运行的进程
打开断点列表,增加一个断点与删除一个断点操作
F7 步入操作,仅执行下一条指令,如果下一个指令是一个函数调用,则在目标函数的第一条指令停止执行
F8 跨过操作,仅执行下一条指令,但不跳入子函数的调用
Ctrl+F7 运行至返回,继续执行当前函数,直到该函数返回(或遇到一个断点)时才停止
F9 继续执行进程,直到该函数到达当前光标(或遇到一个断点)时才停止

General registers 通用寄存器窗口

在对应寄存器上右键,可以修改相应的寄存器值,如下图所示:

点击寄存器旁的图标,可以快速跳转到寄存器对应的Address。

Hex View 十六进制代码块

如下图,操作,我们可以右键调整HexView的显示内容。

主要操作有:

  • Synchronize with - IDA View-PC + PC, 勾选上述操作,可以查看当前IDA View-PC指令对应的16进制内容
  • Synchronize with - R0, 勾选上述操作,可以查看当前R0寄存器对应的16进制内容
  • Edit… 或 F2, 编辑修改当前的16进制内容,如nop一条命令(在0xE3156634操作):

    其中 ESC 可以取消改动,Apply changes 或 F2即可使修改内容生效。

    附生效后效果:

Modules模块窗口

Modules窗口显示所有加载到进程内存空间中的可执行文件和共享库,双击任何模块名称,可将打开该模块导出的符号列表。(通过双击符号列表子项,可以跳转地址,常用于挂载函数)

跟踪

跟踪是一种记录方法, 用于记录一个进程在执行过程中发生的特定事件。跟踪分为两类:指令跟踪和函数跟踪。

指令跟踪


Debugger-Tracing-Instruction Tracing,IDA将记录被指令更改的地址、指令和任何寄存器的值。(指令跟踪将大大减慢被调试进程的执行速度,因为调试器必须单步执行这个进程,以监视和记录所有寄存器的值)

函数跟踪


Debugger-Tracing-Function Tracing,函数跟踪是指令跟踪的子集,它仅记录函数调用(并选择性地记录返回值),而不记录寄存器的值。

Trace window


Debugger-Tracing-Trace window, 可以查看跟踪的结果。

栈跟踪


快捷栏,栈跟踪显示的是当前调用栈或函数调用序列。

监视


Debugger-Watches-Watch list,可以打开并调整监视列表。

调试进程时,你需要持续监视一个或几个变量的值。你不需要在每次进程暂停时都导航到相关的内存位置,许多调试器都能让你指定内存位置列表,每次进程在调试器中暂停没,这些内存位置的值都将显示出来。这样的列表叫做监视列表。

IDA脚本

一般我们常用的操作就是导出dex。File - Script command…。输入脚本后,点击Run即可。

脚本示例如下:

auto fp, begin, end, dexbyte;  
fp = fopen("D:\\dump.dex", "wb");
begin =起始地址(如0xaaa0000);
end =结束地址(如0xaba0000);
for ( dexbyte = begin; dexbyte < end; dexbyte ++ )
fputc(Byte(dexbyte), fp);

附件

百度云

这个作者很懒,是真的很懒。 打赏 巫小胖 微信支付

微信支付

巫小胖 支付宝

支付宝