文章目录
- 0x00. 配置
- 0x01. 主窗口
- 跳转
- 交叉参考
- 0x02. 操作
- 注释
- 修改
- api帮助
- 重命名
- 标签
- FLIRT
- 0x03. 数据识别
- 格式化指令操作数
- 指令数据转换
- 字符串
- 数组
- 结构体
- 嵌套结构体
- union
- 枚举类型
- 位成员
- 变量
- 0x04. 脚本和插件
- 输出导入表
- SMC
- 0x05. 调试
ida按照区块加载PE。
打开时生成4个文件:
- .id0,二叉树形式数据库
- .id1,每个程序字节的标记
- .nam,与ida的names窗口中显示的给定程序位置有关的索引信息
- .til,存储与给定数据库本地类型定义有关的信息
关闭后,打包(store)成idb数据库文件,之后不再需要可执行文件。
压缩(deflate)并清理垃圾(collect garbage),idb会小一些,直接打包会很大。
如果目录中有这4个文件,说明数据库意外关闭。
0x00. 配置
/cfg/ida.cfg
和/cfg/idagui.cfg
,需要UE等编辑工具编辑。
对应options-general
ida.cfg可导致错误。
0x01. 主窗口
view-open subviews
,可打开字符串窗口,及多个反汇编窗口。
view-toolbar-navigator
显示线性颜色图。
跳转
g
esc或工具栏左箭头
ctrl+enter, 或 工具栏右箭头
交叉参考
j
jump
o
offset
p
procedure,子程序
enter跳转到调用处。
x
打开交叉参考窗口。
0x02. 操作
注释
普通注释:
,可重复注释 ;
都有时只显示普通注释。
修改
edit - patch program
,可以修改字节,assemble
可输入指令。
或者hexview窗口直接修改。
api帮助
idagui.cfg的HELPFILE关联至本地文档,即可关联。
分析时ctrl+f1
,获得帮助信息。
重命名
loc_xxxx处,右键-rename
或n
,可更改所有参考点。
标签
jump-mark position
jump-jump to marked position
FLIRT
fast library identification and recognition technology。
许多反汇编器函数名称注解仅限于dll函数。
静态编译(#include)的函数,ida根据字节特征可能解析不出来,比如printf(),,可能显示为call sub_xxx
。
若flirt没有识别,view - open subview - signatures
,右键,添加签名(insert),添加编译器特征文件,如d5vcl.sig。之后#func数字会变为已经解析的delphi函数数量。
若没有解析,则option - general - analysis - reanalyse program
。
ida官网提供了flair创建flirt签名文件。
0x03. 数据识别
格式化指令操作数
常量-右键,可显示各种进制值,以及user standard symbolic constant
。
指令数据转换
数据->代码:edit-code
或c键,知道遇到未定义的指令,或者鼠标选择一个范围。
代码->数据:edit-undefine
或u键
d键:db,dw,dd之间转换。
options-setup datatype
设置数据类型。
字符串
若确认某段为字符串,在第一个字节处,edit-strings-ascii
或A键,即可解析为字符串,并添加前缀“a”的变量名,view-open subviews-names
或按钮N可查看变量名。
options-ascii string style
设置格式。
ida无法确定字符串的原因是字符串没有被引用。
数组
ida可以将一串数据声明变成一个反汇编行。
edit-array
或*
键
结构体
ida可以加载常用文件类型的库,如vc6win, mssdk(windos.h), ntddk(ntddk.h)
。这些库中有相应的结构体。
shift+f11
或view-open subview - type libraries
,选择库,右键-load type library
或insert,就可以加载库。
查看内置结构体:view- open subview - structure
或shift+f9,打开结构体管理窗口,回车/鼠标悬浮/双击
可以查看结构体。insert - add standard structure
,就可以列出/添加结构体。
若ida不了解结构体布局,使用时会显示offset unk_xxxx
(结构体地址),此时用户可以添加结构体。
假设为unk_407030
转到结构体地址407030,d/a/*
键,重新定义数据。
d键可以在db,dw,dd (byte, word, dword)
间切换。
结构体窗口,insert加入类型,d
键加入数据,重复按d可切换类型。a
加入数组。ida会自动给成员命名field_x
。
如果创建可变大小的结构体,则设置数组元素大小为0。
回到407030处,edit - structs - struct var
,选择结构体类型。
unk_407030
就会变成stru_407030
。
.text:00401001 mov esi, offset stru_407030
.text:00401006 mov ecx, [esi+18h]
在[esi + 18h]
处,edit - operand type - offset - offset(struct)
或T
,就会变成下面这样。
.text:00401006 mov ecx, [esi+student.field_18]
成员多时,选定代码,可以批处理。
嵌套结构体
选定数据。
.data:00407030 dword_407030 dd 1 ; DATA XREF: _main+1o
.data:00407034 aMary db 'Mary',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
.data:00407048 dd 0Eh
edit - structs - create struct from selection
alt+q嵌入inside_struct成员。
00000000 struct_0 struc ; (sizeof=0x19, mappedto_23) ; XREF: .data:stru_407030/r
00000000 anonymous_0 dd ?
00000004 aMary db 20 dup(?) ; string(C)
00000018 anonymous_1 inside_struct ?
00000019 struct_0 ends
00000019
00000000 ; ---------------------------------------------------------------------------
00000000
00000000 inside_struct struc ; (sizeof=0x1, mappedto_24) ; XREF: struct_0/r
00000000 field_0 db ?
00000001 inside_struct ends
union
insert时,勾选create union
。
枚举类型
#include <stdio.h>
int main(void)
{
enum weekday { MONDAY, TUESDAY, WEDNESDAY, THUSDAY, FRIDAY, SATURDAY, SUNDAY };
printf("%d,%d,%d,%d,%d,%d,%d",MONDAY,TUESDAY, WEDNESDAY, THUSDAY, FRIDAY, SATURDAY, SUNDAY );
return 0;
}
.text:00401000 push 6
.text:00401002 push 5
.text:00401004 push 4
.text:00401006 push 3
.text:00401008 push 2
.text:0040100A push 1
.text:0040100C push 0
.text:0040100E push offset aDDDDDDD ; "%d,%d,%d,%d,%d,%d,%d"
.text:00401013 call _printf
edit - open subviews - unumerations
,insert,新建weekday枚举类型。n
添加成员。
FFFFFFFF ; enum weekday, mappedto_19
FFFFFFFF MONDAY = 0
FFFFFFFF TUESDAY = 1
FFFFFFFF WEDNESDAY = 2
FFFFFFFF THURSDAY = 3
FFFFFFFF FRIDAY = 4
FFFFFFFF SATURDAY = 5
FFFFFFFF SUNDAY = 6
然后在数据处edit - operand types - enum member
或m
键转换,或右键-symbolic constant
。
.text:00401000 push SUNDAY
.text:00401002 push SATURDAY
.text:00401004 push FRIDAY
.text:00401006 push THURSDAY
.text:00401008 push WEDNESDAY
.text:0040100A push TUESDAY
.text:0040100C push MONDAY
位成员
ida也支持bit-fields
成员。
变量
选定结构体变量, ctrl + k
打开栈窗口,鼠标悬停,可显示成员。
0x04. 脚本和插件
ida自带脚本语言idc,语法与c类似。
必要的标准库为idc.idc
,变量定义auto var;
ida 6.8开始支持python。
深入学习请参考帮助文档。
输出导入表
//Imports.idc 列出当前程序的输入函数
//(c) www.PEDIY.com 2000-2008
#include <idc.idc>
static GetImportSeg()
{
auto ea, next, name;
ea = FirstSeg();
next = ea;
while ( (next = NextSeg(next)) != -1) {
name = SegName(next);
if ( substr( name, 0, 6 ) == ".idata" ) break;
}
return next;
}
static main()
{
auto BytePtr, EndImports;
BytePtr = SegStart( GetImportSeg() );
EndImports = SegEnd( BytePtr );
Message(" \n" + "Parsing Import Table...\n");
while ( BytePtr < EndImports ) {
if (LineA(BytePtr, 1) != "") Message("\n" + "____" + LineA(BytePtr,1) + "____" + "\n");
if (Name(BytePtr)!= "") Message(Name(BytePtr) + "\n");
BytePtr = NextAddr(BytePtr);
}
Message("\n" + "Import Table Parsing Complete\n");
}
SMC
self modifying code,流程:
call ModifyProc
call Proc
解密前反汇编窗口会飘红。
这种情况需要用脚本解密。
.text:00401026 call sub_401080
.text:0040102B call loc_401060
.text:00401080 mov eax, offset loc_401060
.text:00401085
.text:00401085 loc_401085: ; CODE XREF: sub_401080+14j
.text:00401085 mov bl, [eax]
.text:00401087 xor bl, 1
.text:0040108A mov [eax], bl
.text:0040108C inc eax
.text:0040108D cmp eax, (offset loc_401070+4)
.text:00401092 jg short locret_401096
.text:00401094 jmp short loc_401085
.text:00401096 ; ---------------------------------------------------------------------------
.text:00401096
.text:00401096 locret_401096: ; CODE XREF: sub_401080+12j
.text:00401096 retn
.text:00401096 sub_401080 endp
idc:
//encrypted.idc
//(c) www.PEDIY.com 2000-2008
#include <idc.idc>
static decrypt(from, size, key ) {
auto i, x;
for ( i=0; i < size; i=i+1 ) {
x = Byte(from);
x = (x^key);
PatchByte(from,x);
from = from + 1;
}
Message("\n" + "Decrypt Complete\n");
}
加载脚本后,idc command,输入decrypt(0x00401060, 0x15, 0x1)
复杂的任务idc不能完成,需要插件。
插件的sdk位于/plugins
0x05. 调试
debugger - select debugger
debugger - start/attach process
远程调试组件位于/dbgsrv
,将组件放在服务器上运行,接收参数调试。
-p <port>
-P <password>
-v 详细模式
ida中select debugger - remote...
。