知识点
**加载恶意代码:**OD可以直接加载可执行文件,也可以加载DLL文件,也可以将调试器附加在进程中,我们甚至可以用命令行运行恶意代码或者执行DLL中的某个函数。
**加载可执行文件:**在加载可执行文件的时候OD会使用它的加载器来加载这个程序,并可在此过程选择运行的命令行参数。如果OD能确定程序的main函数就在main处中断,否则在程序PE头提供的程序入口点中断。
**附加调试器到一个程序:**OD在附加到一个进程时会立即暂停这个程序以及它所有的线程。
**OD窗口:**OD有如下几个常用窗口:
- 反汇编窗口:这个窗口显示了被调试程序的代码,下一条要执行的指令回在窗口中高亮显示,如果项修改指令或者数据,可以在此窗口中敲击空格键。
- 寄存器窗口:这个窗口会显示程序寄存器的当前状态,代码在调试过程中,如果莫格寄存器的值发生了改变,则此寄存器就会从黑色变成红色。右键某个寄存器选择Modify就可以修改某个寄存器中的值。
- 栈窗口:这个窗口会显示被调试宪曾在内存中的当前状态。这个窗口总会显示给定线程得到栈顶。OD会在一些栈单元上显示一些有用的注释,这些注释描述了调用一个API之前栈中存放的参数。
- 内存转储窗口:这个窗口显示被调试进程的实时内存转储。
**内存映射:**内存映射窗口显示了被调试程序的所有内存块。
**基地址重定位:**基地址重定位是指Windows中的一个模块没有被加载到其预定基地址时发生的情况。Windows中所有PE文件都有一个预定的基地址,它在PE文件头中称为映像基地址。大部分可执行程序都被预加载到0x00400000处,这是Windows下大多数编译器使用的默认地址,支持ALSR的程序经常被重定位。
**绝对地址与相对地址:**多数执行会引用内存中的相对地址,但是有些却引用内存的绝对地址。多数DLL回在PE头的.reloc节打包一个修改位置的列表。DLL的重定位会对性能造成影响,会增加加载的时间。
**查看线程和堆栈:**恶意代码通常使用多线程。我们在OD中可以选择View->Threads来查看线程面板窗口,这个窗口显示了线程的内存地址。由于OD时单线程的,多以我们需要暂停所有的线程,设置一个断点,继续运行程序,这样就可以保证程序在一个特定的线程内调试。
**加载DLL:**OD使用一个名为loaddll.exe的虚拟程序来加载DLL,然后再其主入口处暂停DLL的执行,最后单击Play按钮,运行DllMain函数,此时DllMain函数运行完毕之后选择Debug->Call DLL Export就可以调用DLL的导出函数,并调试它。
**异常处理:**当异常发生时,你可以通过以下热键来决定如何处理这个异常:
- Shift+F7:进入异常
- Shift+F8:跳过异常
- Shift+F9:运行异常处理
**分析ShellCode:**OD有一种分析ShellCode的简单方法,下面是这个方法的步骤:
- 将ShellCode从十六进制编辑器复制到剪切板
- 再内存映射窗口中选择类型为Priv的内存区域(私有)
- 双击这个内存窗口中的某一行,会弹出一个十六进制转储窗口,你可以检查他的内容。该区域应该包含几百个连续为0的字节。
- 右键该区域,赋予这个区域读、写、运行的权限。
- 返回内存转储窗口,选择刚才的内存区域将ShellCode粘贴进去。
- 设置EIP为刚才的内存地址。
- 完成
**调试器隐藏插件:**调试器隐藏插件用多种方法对探测者隐藏调试器的存在。
课后练习
Lab9-1
用OllyDbg和IDA Pro分析恶意代码文件Lab09-01.exe,回答下列问题。再第三章中我们使用基础的静态和动态分析技术,已经对这个恶意代码做了初步的分析。
问题
1.如何让这个恶意代码安装自身?
首先这道题先前在第三章分析过,但是当时还没有学习动态调试地知识,因此将本题留在了本章,根据之前静态分析地结果我们可以知道这个程序可能会因为参数地错误而进行自我删除,执行删除指令的代码如下:
我们先找到程序的主函数所在位置,这些代码会判断程序是否有参数,如果没有参数则会直接执行上图中的自我删除动作:
.text:00402AF0 push ebp
.text:00402AF1 mov ebp, esp
.text:00402AF3 mov eax, 182Ch
.text:00402AF8 call __alloca_probe
.text:00402AFD cmp [ebp+argc], 1
.text:00402B01 jnz short loc_402B1D
.text:00402B03 call sub_401000
.text:00402B08 test eax, eax
.text:00402B0A jz short loc_402B13
.text:00402B0C call sub_402360
.text:00402B11 jmp short loc_402B18
但是如果程序带有参数,程序则会进入参数判断的过程,参数字符串判断函数的完成汇编代码如下:
.text:00402510 push ebp
.text:00402511 mov ebp, esp
.text:00402513 push ecx
.text:00402514 push edi
.text:00402515 mov edi, [ebp+arg_0]
.text:00402518 or ecx, 0FFFFFFFFh
.text:0040251B xor eax, eax
.text:0040251D repne scasb
.text:0040251F not ecx
.text:00402521 add ecx, 0FFFFFFFFh
.text:00402524 cmp ecx, 4
.text:00402527 jz short loc_40252D
.text:00402529 xor eax, eax
.text:0040252B jmp short loc_4025A0
.text:0040252D ; ---------------------------------------------------------------------------
.text:0040252D
.text:0040252D loc_40252D: ; CODE XREF: sub_402510+17↑j
.text:0040252D mov eax, [ebp+arg_0]
.text:00402530 mov cl, [eax]
.text:00402532 mov [ebp+var_4], cl
.text:00402535 movsx edx, [ebp+var_4]
.text:00402539 cmp edx, 61h
.text:0040253C jz short loc_402542
.text:0040253E xor eax, eax
.text:00402540 jmp short loc_4025A0
.text:00402542 ; ---------------------------------------------------------------------------
.text:00402542
.text:00402542 loc_402542: ; CODE XREF: sub_402510+2C↑j
.text:00402542 mov eax, [ebp+arg_0]
.text:00402545 mov cl, [eax+1]
.text:00402548 mov [ebp+var_4], cl
.text:0040254B mov edx, [ebp+arg_0]
.text:0040254E mov al, [ebp+var_4]
.text:00402551 sub al, [edx]
.text:00402553 mov [ebp+var_4], al
.text:00402556 movsx ecx, [ebp+var_4]
.text:0040255A cmp ecx, 1
.text:0040255D jz short loc_402563