文章目录

  • 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处,右键-renamen,可更改所有参考点。

标签

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+f11view-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 memberm键转换,或右键-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...