IDA操作知识记录
前言
本文大部分内容节选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 控制打开关闭。
调试快捷栏
IDA View-PC, 反编译窗口
Stack view 栈视图,显示进程运行时栈的数据内容
General registers 通用寄存器窗口
Hex View 十六进制代码块,通常可以通过操作这里,nop命令或对数据进行操作。
Modules 模块窗口,显示进程镜像中当前加载的模块列表
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);
原文链接:kingerwu.com
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)