IDA使用

前言

  • 先说说反汇编软件IDA原理,反汇编软件去识别二进制文件格式,比如文件的格式是PE,那么它会利用其针对PE的内置“规则“(当然还有一些其它格式的文件比如ELF)对该二进制文件进行分析,最终将其转换为“好看”一点儿,方便人们阅读的格式(其中包括视图展现形式、伪c代码、汇编代码等),其本身并不会像ollydbg去加载程序执行。(当然IDA也能动态调试)
  • IDA(Interactive Disassembler Professional)交互式反汇编专业版,是一款目前最棒的静态反编译软件,可以用来分析pe、elf等格式程序。
  • 较od的动态分析IDA提供了F5键(F5功能是一个插件)查看伪代码的功能,使用非常方便,在ctf的reverse题目中应用很多。

    常见操作

    在介绍常见操作之前,先来看一下用ida加载一个文件的时候,默认的展示窗口有哪些

    注意在反汇编代码的窗口可以输入空格切换到Graphic View,可以更清楚的看清流程
  • 跳转到指定内存地址 快捷键G,可以调到相应的地址
  • 寻找关键特征字符串,打开字符串参考窗口 shift+f12 ,类似于od中plugins中的中文搜索引擎中的智能搜索功能
  • 函数的收缩和展开功能
  • 在vc6中main()不是程序运行的第一个函数,而是程序员编写程序的第一个函数,main()函数是由启动函数来调用的,vc6中入口点是_mainCRTStartup()函数,如下图所示

    双击即可到达这个函数的位置,
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    .text:00401130                 push    ebp
    .text:00401131 mov ebp, esp
    .text:00401133 push 0FFFFFFFFh
    .text:00401135 push offset stru_422130
    .text:0040113A push offset __except_handler3
    .text:0040113F mov eax, large fs:0
    .text:00401145 push eax
    .text:00401146 mov large fs:0, esp
    .text:0040114D add esp, 0FFFFFFF0h
    .text:00401150 push ebx
    .text:00401151 push esi
    .text:00401152 push edi
    .text:00401153 mov [ebp+ms_exc.old_esp], esp
    .text:00401156 call ds:__imp__GetVersion@0 ; GetVersion()
    .text:0040115C mov __osver, eax
    .text:00401161 mov eax, __osver
    .text:00401166 shr eax, 8
    .text:00401169 and eax, 0FFh
    .text:0040116E mov __winminor, eax
    .text:00401173 mov ecx, __osver
    .text:00401179 and ecx, 0FFh
    .text:0040117F mov __winmajor, ecx
    .text:00401185 mov edx, __winmajor
    .text:0040118B shl edx, 8
    .text:0040118E add edx, __winminor
    .text:00401194 mov __winver, edx
    .text:0040119A mov eax, __osver
    .text:0040119F shr eax, 10h
    .text:004011A2 and eax, 0FFFFh
    .text:004011A7 mov __osver, eax
    .text:004011AC push 0
    .text:004011AE call __heap_init
    .text:004011B3 add esp, 4
    .text:004011B6 test eax, eax
    .text:004011B8 jnz short loc_4011C4
    .text:004011BA push 1Ch
    .text:004011BC call fast_error_exit
    .text:004011C1 ; ---------------------------------------------------------------------------
    .text:004011C1 add esp, 4
    .text:004011C4
    .text:004011C4 loc_4011C4: ; CODE XREF: _mainCRTStartup+88j
    .text:004011C4 mov [ebp+ms_exc.registration.TryLevel], 0
    .text:004011CB call __ioinit
    .text:004011D0 call ds:__imp__GetCommandLineA@0 ; GetCommandLineA()
    .text:004011D6 mov __acmdln, eax
    .text:004011DB call ___crtGetEnvironmentStringsA
    .text:004011E0 mov __aenvptr, eax
    .text:004011E5 call __setargv
    .text:004011EA call __setenvp
    .text:004011EF call __cinit
    .text:004011F4 mov ecx, __environ
    .text:004011FA mov ___initenv, ecx
    .text:00401200 mov edx, __environ
    .text:00401206 push edx ; envp
    .text:00401207 mov eax, ___argv
    .text:0040120C push eax ; argv
    .text:0040120D mov ecx, ___argc
    .text:00401213 push ecx ; argc
    .text:00401214 call _main_0

如上所示,是进入这个函数后的汇编代码,可以看到main函数在00401214位置处,启动函数从00401130地址处开始,期间调用了GetVersion()函数获得了系统版本号,调用__heap_init函数初始化了程序所使用的堆空间,调用了GetCommandLineA()函数获取了命令行参数,调用_crtGetEnvironmentStringsA()获取了环境变量字符串,在完成一系列启动所需的工作之后,终于在00401214处调用了main()函数。

  • 在调用printf时候的指令为call printf,而调用像是MessageBoxA时候的指令是call ds:impMessageBoxA@16 ; MessageBoxA(x,x,x,x),printf函数在stdio.h头文件中,该函数是c语言的静态库,在链接的时候会将其代码接入到二进制文件中(静态包含),而MessageBoxA的函数实现是在user32.dll这个动态链接库中,在代码中,这里只是留了进入MessageBoxA函数的一个地址,并没有具体的代码,MessageBoxA的具体地址存放在数据节区中,因此在反汇编代码中给出了提示,使用了前缀”ds”,imp表示导入函数,@16表示16个字节,16/4即函数又4个参数。注意 在od中汇编代码是这样call dword ptr ds:[<&USER32.MessageBoxA>],感觉没有ida的友好。
  • switch case default结构的特征
  • 名称与命名
    在进行样本分析时,ID A识别出来的函数名都是sub_xxxxxx,这种命名方式不适合我们阅读和分析,在我们进行分析后,知道函数或者变量的意义,那么我们可以对其进行重命名。方法是鼠标点击函数名或者变量,然后按下键盘上的N键,在弹出的窗口中写入新的名字即可。
  • 交叉引用
    IDA提供了大量显示和访问交叉引用数据的机制,它以更加直观的方式显示代码和数据之间的关系。在IDA中有两种交叉引用,一种是代码交叉引用,一种是数据交叉引用。如下就是一个代码交叉引用

    在图中可以知道被引用者是?test@@YAXXZ,_main+18是引用者,向下的键条表示引用者的地址要比?test@@YAXXZ的地址高,上行反之。还有其后面的P表示由函数调用导致的交叉引用使用后缀↓p(看做是Procedure)。而跳转交叉引用使用后缀↑j(看做是Jump)。此外还有数据的交叉引用又分为数据读取交叉引用、数据写入交叉引用、数据偏移量交叉引用。
  • 快捷键R 将数字串转换为char字符串
  • IDA是一款非常复杂且非常非常强大,更多见《IDA Pro权威指南》

    Objdump工具

  • objdump也是一款反汇编工具,用于将二进制文件反汇编成汇编语言,不同于ida的图形界面,objdump是命令行的,但是一般的反汇编功能是有的也是比较常用的。比如 objdump -d binaryfile -M interl 按照intel语法进行反汇编,objdump -R binaryfile 显示程序一些动态链接函数的入口地址。

    readelf工具

  • 与objdump类似,显示elf格式的目标文件信息,-S 显示每节头信息

    Reference

    IDA简易教程
    《IDA Pro权威指南》入门笔记
    IDA-XREF(交叉引用)概述