IDA实例教程.DOC

上传人:天*** 文档编号:1341194 上传时间:2019-02-09 格式:DOC 页数:33 大小:379.50KB
下载 相关 举报
IDA实例教程.DOC_第1页
第1页 / 共33页
IDA实例教程.DOC_第2页
第2页 / 共33页
IDA实例教程.DOC_第3页
第3页 / 共33页
IDA实例教程.DOC_第4页
第4页 / 共33页
IDA实例教程.DOC_第5页
第5页 / 共33页
点击查看更多>>
资源描述

1、IDA 实例教程作者:笨笨雄邮箱:1 软件环境静态分析有很多好处,例如加壳的程序(尽管对于高手来说这并不会耗费太多时间) ,我们不需要寻找 OEP,也不需要解除自校验,只要修复 IAT,DUMP 下来就可以动手分析了。假如你需要修改程序,可以使用内存补丁技术。动态与静态,调试器与反汇编器结合可以简化分析任务,帮助我们理解代码。因此掌握一种反汇编器是非常必要的。IDA 可以说是这方面的首选工具,它为我们提供了丰富的功能,以帮助我们进行逆向分析。这从IDA 复杂的工作界面便可以知道。种类繁多的工具栏在分辨率不高的情况,这些工具栏与反汇编窗口挤在小屏幕里,看起来不爽。我一般把它关闭(查看=工具栏=主

2、工具栏)以获得更好的视觉效果。当我们需要这些功能的时候,直接使用快捷键就可以了。下面是常用快捷键的清单:快捷键 功能 注释C 转换为代码D 转换为数据A 转换为字符一般在 IDA 无法识别代码时使用这两个功能整理代码N 为标签重命名; 添加注释方便记忆,避免重复分析。R 把立即值转换为字符H 把立即值转换为 10 进制Q 把立即值转换为 16 进制B 把立即值转换为 2 进制便于分析立即值G 跳转到指定地址X 交叉参考 便于查找 API 或变量的引用SHIFT+/ 计算器ALT+ENTER 新建窗口并跳转到选中地址ALT+F3 关闭当前分析窗口ESC 返回前一个保存位置CTRL+ENTER 返

3、回后一个保存位置这四个功能都是方便在不同函数之间分析(尤其是多层次的调用)。具体使用看个人喜好在工具栏下面的便是工作窗口。主要的窗口分页有“IDA View-A”、 “Name”、“Strings”、 “Exports”和“Imports ”。对于后面 3 项相信大家都不会陌生了,它们分别是字符参考,输出函数参考和输入函数参考。Name 是命名窗口,在那里可以看到我们命名的函数或者变量。这四个窗口都支持索引功能,可以通过双击来快速切换到分析窗口中的相关内容,使用起来十分方便。简单输入几个字符即可定位目标IDA View-A 是分析窗口,支持两种显示模式,除了常见的反汇编模式之后,还提供图形视图

4、以及其他有趣的功能。IDA 的反汇编窗口一般我们在分析的时候,并不关心程序的机械码,所以 IDA 为我们自动隐藏了这些信息。如果你有需要,可以通过以下步骤来设置:选项=常规=反汇编= 显示反汇编行部分=机械码字节数=修改为你允许显示的大小现在让我们以论坛脱壳版块置顶帖的那个经典为例,看看图形视图的表现。首先我们到以下连接下载:http:/ 40EA0E 便是壳的出口代码的地址。在 OD 中直接跳到该地址,下断点,然后运行到该处,再单步便能看到 OEP 了。假如希望通过跳转法找 OEP,相信图形视图比你在 OD 一个一个跳转跟随,要快得多。再来看看这个壳的另类脱法。直接运行该程序, DUMP 下

5、来,再使用 IMPORTREC的 IAT AutoSearch 功能修复输入表。用 IDA 打开修复了输入表的 DUMP 文件。在IMPORT 窗口随便选一个 API,随便通过交叉参考跳转到一个函数的代码。此处为文件输入表的位置我选了 RegQueryValueExA,通过交叉参考,来到 Sub_402488 处的函数代码。用鼠标拖动缩略图中的虚线框到上方,便能看到该 CALL 的头部了。然后按下图指示操作:在函数标记上点击鼠标右键处于最上层的函数,便是 OEP 了,使用 PE 工具修改文件入口为 10CC。现在函数可以正常工作了。这个方法的原理是通常我们写程序都有如下流程:Main proc

6、 /代码CALL FUN1/代码CALL FUN2/代码END proc所以处于函数调用最上层的便是 MAIN 函数了。当然这个方法局限性很大,这里只是对该功能的一种介绍。我们留意到图表功能有两个选项,在上面的例子中,我们使用的是“交叉参考到” 。我想细心的朋友大概能通过“交叉参考来自”左边的小图标猜出它的用途了。该功能可以显示目标函数调用了什么函数,当然也包括 API。这样除了观察函数的输入参数来判断是否关键 CALL 之外,又多了一个参考途径。2 强大的 IDC有时我们需要分析一些非文件格式的代码,例如 ShellCode,远线程注入和病毒。这些代码的特点便是动态获取 API,这给静态分析

7、带来困难。尽管 IDA 支持分析 2 进制文件,但是缺少 IAT 的情况下,分析起来跟不方便。频繁的切换调试器查看并不是一个好方法。IDC 是 IDA 的脚本语言,它功能强大,为我们提供了另一条与调试器交互的途径。如何使调试器获得 IDA 分析得出的符号?IDA 提供多种文件格式输出,调试器可以通过解释这些文件获得一些符号。你可以通过文件菜单中的“创建文件”获得更多的信息。以 OD 为例,它的 GODUP 插件支持解释 MAP 文件(还能加载 IDA 的 SIG) 。在 IDA 中使用如下步骤:菜单: 文件=创建文件=创建 MAP 文件即可创建 MAP 文件,然后切换到 OD,使用如下步骤便能

8、获得符号了:菜单: 插件=GODUP Plugin=Map Loader=Load labels仍然以那个经典的 UPX 加壳的 NOTEPAD 为例子,这次我们用 OD 打开,在到达OEP 之后 DUMP 下来,不修复输入表,直接用 IDA 载入后看到下图:丰富的文件载入选项需要注意的是 Make imports segment 是 PE 文件特有的选项,该选项会隐藏输入表区域的所有数据,同时你获得的好处便是能在图表功能中看到 API 的调用。假如你希望查看在输入表的范围内的代码或者数据,你需要使用从菜单中选择“编辑”=“区段”以删除遮挡数据的部分区段。为了更真实的模拟从内存中截取代码的情况

9、,在这里选择 Binary file,载入偏移量选400000(根据实际代码在内存中的基址来选择) ,然后 IDA 就开始尝试分析可能存在于该文件中的代码了。对照 OD 中的 OEP 地址,在 IDA 中可以看到以下代码:seg000:004010CC push ebpseg000:004010CD mov ebp, espseg000:004010CF sub esp, 44hseg000:004010D2 push esiseg000:004010D3 call ds:dword_4063E4seg000:004010D9 mov esi, eaxseg000:004010DB mov a

10、l, eaxseg000:004010DD cmp al, 22hseg000:004010DF jnz short loc_4010FCOEP 处的部分代码OD 中对应的显示:004010D3 FF15 E4634000 call dword ptr 4063E4 ; kernel32.GetCommandLineA使用以下 ollyscript (附件中的 ollyGetSym.txt)提取 IAT 的符号:var eavar Ecount /0 分隔号的记数器var oFileask “请输入 IAT 起始地址“cmp $RESULT, 0je ECancelmov ea, $RESUL

11、Task “输出文件? “cmp $RESULT, 0je ECancelmov oFile, $RESULTTryGetSym:GN ea /获取该地址的符号cmp $RESULT,00000000 /OLLYSCRIPT 是区分 00000000 和 0 的je ETestWRTA oFile,$RESULT_2 mov Ecount,0add ea,4jmp TryGetSymECancel:msg “无效输入“retETest:cmp Ecount,1 /不同模块的地址以 0 分隔je Send /若存在两个 DWORD 的 0 则认为是末尾add Ecount,1add ea,4jm

12、p TryGetSymSEnd:Ret使用下面 IDC 脚本获取符号并对相应地址重命名:#include static main() auto Sbuffer,ea,zcount,filehandle,fileName,CustEa;fileName = AskFile (0,“*.*“,“打开 IAT 符号文件“);CustEa = AskAddr(0,“目标 IAT 地址“);filehandle = fopen(fileName,“r“);for (ea = CustEa; zcount 加载文件=加载 FLIRT 签名文件=Delphi7 RTL/VCL/CLX现在 IDA 将会根据

13、Delphi 的函数特征识别出一些库函数,这样可以减少很多工作量。函数较长,这里只列出关键代码。判断这部分为关键代码主要是因为整个函数就只有该处是循环。解密是对一定长度的数据进行运算,因此会有一个循环对字符中的数据逐一解密。然后从输入参数与寄存器或者堆栈的关联便可以理解函数的关键部分是如何工作的。由于 IDA 已经为我们识别出 Delphi 的库函数,所以这里很容易便知道解密的方便是对目标字符的每个字节都加上 80h。下面来看看我如何使用 IDC 来完成解密字符的工作。CODE:00404C2C mov ebp+var_8,1 /已处理字符记数器CODE:00404C2CCODE:00404C

14、33CODE:00404C33 loc_404C33: ; CODE XREF: sub_404BEE+6AjCODE:00404C33 mov eax, ebp+var_4CODE:00404C36 mov edx, ebp+var_8CODE:00404C39 mov bl, eax+edx-1 /单字节取字符解密CODE:00404C3D add bl, 80hCODE:00404C40 lea eax, ebp+var_CCODE:00404C43 mov edx, ebxCODE:00404C45 call SystemLStrFromChar$qqrr17SystemAnsiStr

15、ingcCODE:00404C45CODE:00404C4A mov edx, ebp+var_CCODE:00404C4D mov eax, ediCODE:00404C4F call SystemLStrCat$qqrvCODE:00404C4FCODE:00404C54 inc ebp+var_8 CODE:00404C57 dec esi /字符长度 =0 跳出循环,解密完毕CODE:00404C58 jnz short loc_404C33Decode.idc#include “idc.idc“static main() auto ea,x,y,z,zbyte,SRange,TStr

16、Len,DeCodeBuffer,DeCodeCounter,NotTarget;x = 0x404bee;for ( y=RfirstB(x); y != BADADDR; y=RnextB(x,y) ) /通过交叉参考取得函数调用地址for (SRange = 4; SRange 0x50; SRange+)z = y - SRange;zbyte = Byte(z);if (zbyte = 0xb8) /mov eax,mem32 的机械码是 b8zbyte = Dword(z + 1);ea = Dword(zbyte);if (ea != 0xFFFFFFFF) /判断 mem32

17、是否有效,防止识别错指令if (Byte(zbyte - 1) = 1) /在字符指针前一个字节写入处理标记break; /避免重复处理PatchByte (zbyte - 1,1);TStrLen = 0;while (TStrLen 0x30) /解密的循环DeCodeCounter = zbyte + TStrLen;DeCodeBuffer = Byte(DeCodeCounter) + 0x80;if (DeCodeBuffer = 0x80) break;PatchByte (DeCodeCounter,DeCodeBuffer);TStrLen+;MakeUnknown (zbyte,TStrLen,0); /取消 IDA 原来的分析结果MakeStr (zbyte, DeCodeCounter); /把该位置标记为字符break;

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 重点行业资料库 > 1

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。