IDA Pro基础

发布于 2018-07-18  1.31k 次阅读


测试代码

#include <stdio.h>

int check (int num) {
    if (num == 10) {
        printf("Correct\n");
        return 1;
    }    
    return -1;
}

int main() {
    int num;
    printf("Please input a number:\n");
    scanf("%d", &num);
    while (1) {
        if (check(num) == 1) {
            break;
        }
        else {
            printf("Wrong number\n");
            printf("Please input a number:\n");
            scanf("%d", &num);
        } 
    }
}

IDA Pro界面

打开后有New(新建), Go(运行), Previous(上一个),一般选Go就可以了。
然后直接把要分析的文件拖进IDA里面,在Load a new file界面里默认设置就可以,直接点ok。可能会弹出一个DWARF info found界面,也是直接ok就可以了。

加载成功后的界面

IDA Pro基础

上面是菜单栏,下面是Output window(消息窗口),左边的Functions window(函数表) Graph overview(流程图),主窗口里面还有
IDA View-A(分析视图窗口)
Hex View-1(十六进制视图窗口)
Structures(添加结构体信息窗口)
Enums(添加枚举信息窗口)
Imports(分析文件中的导入函数信息窗口)
Exports(分析文件中的导出函数信息窗口)

IDA代码段

通常IDA对一个PE文件逆向出来的代码中,
存在四个最基本的段text、idata、rdata、data,
四个段为PE文件的结构中对应的段。

text段

该段位程序代码段,在该段一开始就可以看到:

.text:00401000 ; Segment type: Pure code
.text:00401000 ; Segment permissions: Read/Execute

这里的段类型跟权限说明很清楚: 分别为代码段和可读可执行。需要注意的是,borland这里叫做code,而不是text

idata、rdata、data段

从命名上可以看出,三个段全为存放特殊数据的段,但IDA根据PE文件的格式将数据段中不同类型的数据区分开来。
VC开发工具将INC,LIB,RES放在数据段,DELPHI也类似,同时由于Delphi的窗体文件*.dfm在源代码中使用编译指令{$R *dfm}作为res资源放在数据段中,因此像delphi的反汇编工具dede就根据这些窗体资源数据,分析出相当清晰的源代码与窗体事件的对应地址,当然实现代码还是汇编代码。
1) idata段:
该段在一开始一般有类似下面的说明:

.idata:0049B000 ; Section 2. (virtual address 0009B000)
.idata:0049B000 ; Virtual size : 0001717E ( 94590.)
.idata:0049B000 ; Section size in file : 00018000 ( 98304.)
.idata:0049B000 ; Offset to raw data for section: 0009B000
.idata:0049B000 ; Flags 40000040: Data Readable
.idata:0049B000 ; Alignment : default
.idata:0049B000 ;
.idata:0049B000 ; Imports from ADVAPI32.dll
.idata:0049B000 ;
.idata:0049B000 ; ===========================================================================
.idata:0049B000
.idata:0049B000 ; Segment type: Externs
.idata:0049B000 ; _idata

明显是一个Imports函数的代码段,这里集中所有外部函数地址,代码中会先跳到该地址后再执行,PE文件加载器在开始会获取真实的函数地址来修补idata段中的函数地址。
与之对应的exports是edata,
表面上看PE文件对该段的定位是特殊数据段。
2)rdata段
名字上看就是资源数据段,程序用到什么资源数据都在这里,资源包括你自己封包的,也包括开发工具自动封包的。
3)data段
这个段存放程序的全局数据、全局常量等。

简单分析

分析的时候我们要先找到主函数,可以在函数表里面找到main函数,
也可以在分析视图窗口里点击main函数后按下空格进入汇编代码窗口,
进入后可以按下f5查看伪代码(不能f5时就只能看汇编代码了)
伪代码和实际代码可能有些不同,但逻辑都一致。
按下'/'对代码进行注释。
点击变量或者函数名
按下'N'可以修改变量或者函数的名字,
按下'X'可以看到哪些地方使用了改变量或者函数,
按下'G'可以看到该变量或者函数的地址
双击函数名可以进入该函数。
IDA pro快捷键

main函数汇编代码

汇编语言基础

.text:00401486 ; =============== S U B R O U T I N E =======================================
.text:00401486
.text:00401486 ; Attributes: bp-based frame
.text:00401486
.text:00401486 ; int main()
.text:00401486                 public _main
.text:00401486 _main           proc near               ; CODE XREF: sub_4011B0+D3p
.text:00401486                 push    ebp
.text:00401487                 mov     ebp, esp
.text:00401489                 and     esp, 0FFFFFFF0h
.text:0040148C                 sub     esp, 20h
.text:0040148F                 call    ___main
.text:00401494                 mov     dword ptr [esp], offset aPleaseInputANu ; "Please input a number:"
.text:0040149B                 call    _puts
.text:004014A0                 lea     eax, [esp+1Ch]
.text:004014A4                 mov     [esp+4], eax
.text:004014A8                 mov     dword ptr [esp], offset aD ; "%d"
.text:004014AF                 call    _scanf
.text:004014B4
.text:004014B4 loc_4014B4:                             ; CODE XREF: _main+70j
.text:004014B4                 mov     eax, [esp+1Ch]
.text:004014B8                 mov     [esp], eax      ; num
.text:004014BB                 call    __Z5checki      ; check(int)
.text:004014C0                 cmp     eax, 1
.text:004014C3                 setz    al
.text:004014C6                 test    al, al
.text:004014C8                 jnz     short loc_4014F8
.text:004014CA                 mov     dword ptr [esp], offset aWrongNumber ; "Wrong number"
.text:004014D1                 call    _puts
.text:004014D6                 mov     dword ptr [esp], offset aPleaseInputANu ; "Please input a number:"
.text:004014DD                 call    _puts
.text:004014E2                 lea     eax, [esp+1Ch]
.text:004014E6                 mov     [esp+4], eax
.text:004014EA                 mov     dword ptr [esp], offset aD ; "%d"
.text:004014F1                 call    _scanf
.text:004014F6                 jmp     short loc_4014B4
.text:004014F8 ; ---------------------------------------------------------------------------
.text:004014F8
.text:004014F8 loc_4014F8:                             ; CODE XREF: _main+42j
.text:004014F8                 nop
.text:004014F9                 mov     eax, 0
.text:004014FE                 leave
.text:004014FF                 retn
.text:004014FF _main           endp

汇编代码

main函数伪代码

和原代码差不多

int main()
{
  int v1; // [sp+1Ch] [bp-4h]@1

  __main();
  puts("Please input a number:");
  scanf("%d", &v1);
  while ( check(v1) != 1 )
  {
    puts("Wrong number");
    puts("Please input a number:");
    scanf("%d", &v1);
  }
  return 0;
}

字符串搜索

在IDA里也可以利用字符串搜索的方式来找到特定的函数,按下Shift+F12 IDA就会在Strings window列出所有的字符串,然后按下Alt+T进行精确搜索想要的字符串,Ctrl+T重复上一次的搜索(程序里多个地方用到该字符串),选中的3个字符串就是我们程序用的的字符串

IDA Pro基础

双击任意一个字符串就会自动跳转到分析视图窗口的rdata段,并且前面地址会高亮显示,在Hex view里也可以看到字符串对应的16进制码

IDA Pro基础

双击DATA XREF:后面的函数名就可以跳转到对应的函数

代码修改

如果我们想要把check函数里的if(num == 10)修改成if(num == 1),可以利用Hex view窗口来进行修改。
先找到这一条语句相对应的地址,单击这个地址,然后转到Hex view窗口,高亮显示的就是我们需要修改的地方了。

IDA Pro基础

10对应的16进制是0A,所以只要修改0A就可以了,右键选择Edit或者按下F2,把光标移动到0A的位置,
然后直接输入数值,修改后的地方会变成红色,修改完成后右键选择Apply changes或者按下F2保存修改。
这时候回到分析视图窗口就会发现10变成1了伪代码里也修改了。在IDA中验证修改正确后,可以使用UltraEdit或010Editor来修改原始程序文件。

IDC脚本

在IDA里按下Shift+F2可以打开IDC脚本编辑界面或者在菜单栏中File->Script file载入idc文件
IDC脚本语法

auto str = 0x00405064; // Correct字符串第一个字符的地址
auto i, x; // 定义2个变量
for(i = 0; i < 8; i++) { // for循环
    x = Byte(str); // 每次取一个Byte
    Message("%s", x); // 打印这个Byte的字符
    str = str + 1; // 更新到下一个字符的地址
}

点击run后在Output window中会显示运行结果

IDA Pro基础

IDA动态调试

在IDA里可以对汇编代码进行动态调试
先在菜单栏里找到Debugger选项,然后在下拉框里选择Switch debugger然后选择Local Win32 Debugger。或者在工具栏里的下拉框里直接选择Local Win32 Debugger。

IDA Pro基础

在分析视图窗口中的左边可以单击蓝色的小圆点来设置断点,设置后那一整条语句会被红色高亮显示。
在工具栏的Open breakpoints window里可以看到设置的所有断点。
按下F9或者点击工具栏里的绿色箭头就可以对汇编代码进行动态调试了。
F7单步步入调试会进入函数内部。
F8进行单步步过调试不进入函数内部。
F9让程序继续运行直到遇到断点。

汇编代码动态调试界面

IDA Pro基础

工作区

工作区一共有3个主窗口,2个副窗口,我们主要用到的是第一个主窗口(Debug view)和它的两个副窗口IDA View-EIP(汇编代码窗口),Breakpoints(断点窗口)。

IDA Pro基础

寄存器窗口

这个窗口里会显示每个寄存器里放的数据
寄存器介绍

IDA Pro基础

十六进制视图窗口和栈窗口

IDA Pro基础