2022年IDA实例教程 .pdf
《2022年IDA实例教程 .pdf》由会员分享,可在线阅读,更多相关《2022年IDA实例教程 .pdf(32页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、IDA 实例教程作者:笨笨雄邮箱: 1 软件环境静态分析有很多好处,例如加壳的程序(尽管对于高手来说这并不会耗费太多时间),我们不需要寻找OEP,也不需要解除自校验,只要修复IAT,DUMP 下来就可以动手分析了。假如你需要修改程序,可以使用内存补丁技术。动态与静态,调试器与反汇编器结合可以简化分析任务, 帮助我们理解代码。因此掌握一种反汇编器是非常必要的。IDA 可以说是这方面的首选工具,它为我们提供了丰富的功能,以帮助我们进行逆向分析。这从IDA 复杂的工作界面便可以知道。种类繁多的工具栏在分辨率不高的情况,这些工具栏与反汇编窗口挤在小屏幕里,看起来不爽。 我一般把它关闭(查看 =工具栏
2、=主工具栏)以获得更好的视觉效果。当我们需要这些功能的时候,直接使用快捷键就可以了。下面是常用快捷键的清单:快捷键功能注释C 转换为代码一般在 IDA 无法识别代码时使用这两个功能整理代码D 转换为数据A 转换为字符N 为标签重命名方便记忆,避免重复分析。;添加注释R 把立即值转换为字符便于分析立即值H 把立即值转换为10 进制Q 把立即值转换为16 进制B 把立即值转换为2 进制G 跳转到指定地址X 交叉参考便于查找API 或变量的引用SHIFT+/ 计算器ALT+ENTER 新建窗口并跳转到选中地址这四个功能都是方便在不同函数之间分析(尤其是多层次的调用) 。具体使用看个人喜好ALT+F3
3、 关闭当前分析窗口ESC 返回前一个保存位置CTRL+ENTER 返回后一个保存位置名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 1 页,共 32 页 - - - - - - - - - 在工具栏下面的便是工作窗口。主要的窗口分页有“ IDA View-A ” 、 “ Name” 、 “Strings” 、“Exports”和“ Imports” 。对于后面3项相信大家都不会陌生了,它们分别是字符参考,输出函数参考和输入函数参考。Name 是命名窗口, 在那里可以看到我们命名的函数
4、或者变量。这四个窗口都支持索引功能,可以通过双击来快速切换到分析窗口中的相关内容,使用起来十分方便。简单输入几个字符即可定位目标IDA View-A 是分析窗口,支持两种显示模式,除了常见的反汇编模式之后,还提供图形视图以及其他有趣的功能。IDA 的反汇编窗口名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 2 页,共 32 页 - - - - - - - - - 一般我们在分析的时候,并不关心程序的机械码,所以IDA 为我们自动隐藏了这些信息。如果你有需要,可以通过以下步骤来设置:选
5、项 =常规 =反汇编 =显示反汇编行部分=机械码字节数 =修改为你允许显示的大小现在让我们以论坛脱壳版块置顶帖的那个经典为例,看看图形视图的表现。首先我们到以下连接下载:http:/ 标签 40EA0E 便是壳的出口代码的地址。在 OD 中直接跳到该地址,下断点,然后运行到该处,再单步便能看到OEP 了。假如希望通过跳转法找OEP,相信图形视图比你在 OD 一个一个跳转跟随,要快得多。再来看看这个壳的另类脱法。直接运行该程序,DUMP 下来,再使用IMPORTREC 的IAT AutoSearch 功能修复输入表。用IDA 打开修复了输入表的DUMP 文件。在IMPORT 窗口随便选一个API
6、,随便通过交叉参考跳转到一个函数的代码。此处为文件输入表的位置我选了 RegQueryValueExA ,通过交叉参考,来到Sub_402488 处的函数代码。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 3 页,共 32 页 - - - - - - - - - 用鼠标拖动缩略图中的虚线框到上方,便能看到该CALL的头部了。然后按下图指示操作:在函数标记上点击鼠标右键处于最上层的函数,便是OEP 了,使用 PE工具修改文件入口为10CC。现在函数可以正常工作了。这个方法的原理是通常
7、我们写程序都有如下流程:Main proc /代码CALL FUN1 /代码CALL FUN2 /代码END proc 所以处于函数调用最上层的便是MAIN函数了。当然这个方法局限性很大,这里只是对该功能的一种介绍。 我们留意到图表功能有两个选项,在上面的例子中, 我们使用的是 “交叉参考到”。我想细心的朋友大概能通过“交叉参考来自”左边的小图标猜出它的用途了。该功能可以显示目标函数调用了什么函数,当然也包括API 。这样除了观察函数的输入参数来判断是否关键CALL 之外,又多了一个参考途径。名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - -
8、- - - 名师精心整理 - - - - - - - 第 4 页,共 32 页 - - - - - - - - - 2强大的 IDC 有时我们需要分析一些非文件格式的代码,例如ShellCode,远线程注入和病毒。这些代码的特点便是动态获取API ,这给静态分析带来困难。尽管IDA 支持分析2 进制文件,但是缺少IAT 的情况下,分析起来跟不方便。 频繁的切换调试器查看并不是一个好方法。IDC是 IDA 的脚本语言,它功能强大,为我们提供了另一条与调试器交互的途径。如何使调试器获得IDA 分析得出的符号?IDA 提供多种文件格式输出,调试器可以通过解释这些文件获得一些符号。你可以通过文件菜单中
9、的“创建文件”获得更多的信息。以 OD 为例,它的GODUP 插件支持解释MAP 文件(还能加载IDA 的 SIG) 。在 IDA 中使用如下步骤:菜单:文件 =创建文件 =创建 MAP 文件即可创建 MAP 文件,然后切换到OD,使用如下步骤便能获得符号了:菜单:插件 =GODUP Plugin=Map Loader=Load labels 仍然以那个经典的UPX 加壳的 NOTEPAD 为例子,这次我们用OD 打开,在到达OEP之后 DUMP 下来,不修复输入表,直接用IDA 载入后看到下图:丰富的文件载入选项名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - -
10、 - - - - - - - - 名师精心整理 - - - - - - - 第 5 页,共 32 页 - - - - - - - - - 需要注意的是Make imports segment 是 PE 文件特有的选项,该选项会隐藏输入表区域的所有数据,同时你获得的好处便是能在图表功能中看到API 的调用。假如你希望查看在输入表的范围内的代码或者数据,你需要使用从菜单中选择“编辑”=“区段”以删除遮挡数据的部分区段。为了更真实的模拟从内存中截取代码的情况,在这里选择Binary file ,载入偏移量选400000(根据实际代码在内存中的基址来选择),然后 IDA 就开始尝试分析可能存在于该文件
11、中的代码了。对照OD 中的 OEP 地址,在IDA 中可以看到以下代码:seg000:004010CC push ebp seg000:004010CD mov ebp, esp seg000:004010CF sub esp, 44h seg000:004010D2 push esi seg000:004010D3 call ds:dword_4063E4 seg000:004010D9 mov esi, eax seg000:004010DB mov al, eax seg000:004010DD cmp al, 22h seg000:004010DF jnz short loc_4010
12、FC OEP 处的部分代码OD 中对应的显示:004010D3 FF15 E4634000 call dword ptr 4063E4 ; kernel32.GetCommandLineA 使用以下ollyscript (附件中的ollyGetSym.txt )提取 IAT 的符号:var ea var Ecount /0 分隔号的记数器var oFile ask 请输入 IAT 起始地址 cmp $RESULT, 0 je ECancel mov ea, $RESULT ask 输出文件? cmp $RESULT, 0 je ECancel mov oFile, $RESULT TryGet
13、Sym: GN ea /获取该地址的符号cmp $RESULT,00000000 /OLLYSCRIPT是区分 00000000 和 0的je ETest WRTA oFile,$RESULT_2 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 6 页,共 32 页 - - - - - - - - - mov Ecount,0 add ea,4 jmp TryGetSym ECancel: msg 无效输入 ret ETest: cmp Ecount,1 /不同模块的地址以0分隔je
14、 Send /若存在两个DWORD 的 0 则认为是末尾add Ecount,1 add ea,4 jmp TryGetSym SEnd: 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; zco
15、unt 2; ea = ea + 4) if (Dword(ea) !=0) Sbuffer = readstr(filehandle); if(strlen(Sbuffer) 加载文件 =加载 FLIRT 签名文件 =Delphi7 RTL/VCL/CLX 现在 IDA 将会根据 Delphi 的函数特征识别出一些库函数,这样可以减少很多工作量。函数较长, 这里只列出关键代码。判断这部分为关键代码主要是因为整个函数就只有该处是循环。解密是对一定长度的数据进行运算,因此会有一个循环对字符中的数据逐一解密。然后从输入参数与寄存器或者堆栈的关联便可以理解函数的关键部分是如何工作的。由于IDA 已经
16、为我们识别出Delphi 的库函数,所以这里很容易便知道解密的方便是对目标字符的每个字节都加上80h。下面来看看我如何使用IDC 来完成解密字符的工作。CODE:00404C2C mov ebp+var_8,1 /已处理字符记数器CODE:00404C2C CODE:00404C33 CODE:00404C33 loc_404C33: ; CODE XREF: sub_404BEE+6Aj CODE:00404C33 mov eax, ebp+var_4 CODE:00404C36 mov edx, ebp+var_8 CODE:00404C39 mov bl, eax+edx-1 /单字节取
17、字符解密CODE:00404C3D add bl, 80h CODE:00404C40 lea eax, ebp+var_C CODE:00404C43 mov edx, ebx CODE:00404C45 call SystemLStrFromChar$qqrr17SystemAnsiStringc CODE:00404C45 CODE:00404C4A mov edx, ebp+var_C CODE:00404C4D mov eax, edi CODE:00404C4F call SystemLStrCat$qqrv CODE:00404C4F CODE:00404C54 inc ebp+
18、var_8 CODE:00404C57 dec esi /字符长度 =0 跳出循环,解密完毕CODE:00404C58 jnz short loc_404C33 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 9 页,共 32 页 - - - - - - - - - Decode.idc #include idc.idc static main() auto ea,x,y,z,zbyte,SRange,TStrLen,DeCodeBuffer,DeCodeCounter,NotTar
19、get; x = 0 x404bee; for ( y=RfirstB(x); y != BADADDR; y=RnextB(x,y) ) /通过交叉参考取得函数调用地址for (SRange = 4; SRange 0 x50; SRange+) z = y - SRange; zbyte = Byte(z); if (zbyte = 0 xb8) /mov eax,mem32 的机械码是b8zbyte = Dword(z + 1); ea = Dword(zbyte); if (ea != 0 xFFFFFFFF) /判断 mem32 是否有效,防止识别错指令if (Byte(zbyte
20、- 1) = 1) /在字符指针前一个字节写入处理标记break; /避免重复处理 PatchByte (zbyte - 1,1); TStrLen = 0; while (TStrLen 0 x30) /解密的循环DeCodeCounter = zbyte + TStrLen; DeCodeBuffer = Byte(DeCodeCounter) + 0 x80; if (DeCodeBuffer = 0 x80) break; PatchByte (DeCodeCounter,DeCodeBuffer); TStrLen+; MakeUnknown (zbyte,TStrLen,0); /
21、取消 IDA 原来的分析结果MakeStr (zbyte, DeCodeCounter); /把该位置标记为字符break; 名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 10 页,共 32 页 - - - - - - - - - 既然可以通过加密字符定位目标函数,那么也可以通过加密函数定位加密字符。通过使用解密函数的交叉引用,往上搜索,解密第一条mov eax,mem32 中的字符。当然这里个脚本写得有点简陋, 并不能完全解决程序中的加密字符。这个就任务就留给读者来挑战吧。这里要
22、注意的是我在编写IDC 的过程中遇到很多BUG,这是因为IDA 区分大小写 (调试了很久才知道)。此外要转换数据类型得先把原来的分析结果取消才可以。最后要看到下图的窗口,在运行脚本后,你需要重新打开字符参考窗口(不会自动刷新)。解密后的字符参考窗口名师资料总结 - - -精品资料欢迎下载 - - - - - - - - - - - - - - - - - - 名师精心整理 - - - - - - - 第 11 页,共 32 页 - - - - - - - - - 3静态脱壳上一节我们用IDC 完成了字符解密的工作,既然脱壳的过程实际就是对源程序的解密,现在让我们来尝试在不运行壳的情况下把壳解决
23、掉。首先到下面连接下载一个壳:http:/ 练练手,现在就以该壳的主程序作为例子讲解如何静态脱壳。首先用IDA 加载该壳的主程序。seg005:004560FA loc_4560FA: ; CODE XREF: start:loc_4560F4j seg005:004560FA call sub_456109 seg005:004560FA seg005:004560FA start endp /入口函数的结尾seg005:004560FA seg005:004560FF seg005:004560FF seg005:004560FF seg005:004560FF sub_4560FF pr
24、oc near ; CODE XREF: seg005:00456104p seg005:004560FF /红色seg005:004560FF call sub_456DEF seg005:004560FF seg005:004560FF sub_4560FF endp seg005:004560FF seg005:00456104 call sub_4560FF seg005:00456104 seg005:00456109 seg005:00456109 seg005:00456109 seg005:00456109 sub_456109 proc near ; CODE XREF: s
25、tart:loc_4560FAp seg005:00456109 call near ptr sub_4560FF+1 /+1 表示反汇编出现混乱正常的交叉参考标记是绿色,当显示为红色时则证明与其他部分的反汇编代码产生冲突。另外在jcc,jmp 和 call 后面出现“ +X ”的符号( X 为任意数字),一般也为反汇编出现混乱。在正式分析之前,我们必须找到花指令的规律,编写脚本,除去它的影响。现在我们从最初产生影响的地方开始。点击地址4560FF,按 D seg005:004560FF byte_4560FF db 0E8h; CODE XREF: seg005:00456p seg005:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年IDA实例教程 2022 IDA 实例教程
限制150内