第九章 OllyDbg
1.加载恶意代码
直接加载可执行文件,甚至dll程序。如果恶意代码已经在你的系统上运行,你可以通过附加进程的
方式调试它。另外,ollydbg是一个灵活的调试系统,可以使用命令行选项运行恶意代码,甚至支持
执行DLL中某个函数。
打开一个可执行文件, 使用ollydbg调试恶意代码的最简单方式,是选择ollydbg界面中的File-open
然后浏览到要加载的可执行文件。如果需要执行参数,可以在open对话框中的arguments输入框给出。
2.附加调试器到一个运行程序
选择ollydbg界面的File-Attach。然后会弹出一个菜单,你可以在这个菜单中选择要附加的进程(如果
有多个同名的进程,你需要知道调试进程的ID)。接下来选择调试的进程,此刻OllyDbg会立即暂停
这个程序以及它所有线程。
OllyDbg附加上进程后,进程当前执行线程的代码会被暂停,并显示在OllyDbg的窗口中。然而,有可
能在进程正在执行一个系统Dll中的指令把它暂停了,此种情况,回到主代码醉简单的方式是在这个代
码段设置一个访问断点。这样就会让程序在下次访问代码段中断执行。我们会在本章的后面解释如何
设置这些断点。
2.OllDbg的接口。
反汇编面板窗口,显示被调试程序的代码。
寄存器面板窗口,显示调试程序寄存器当前状态。代码被调试时,如果一条指令运行修改了寄存器的
值,这个寄存器的就会从黑色变为红色。当一个程序被调试时,你可以通过右键单机任意的寄存器,
在弹出的菜单中选择Modify来修改寄存器的值。
栈面板窗口 这个窗口用来显示被调试线程堆栈在内存中的当前状态。这个窗口总是显示给定线程的
栈顶。可以通过右击一个栈单元,选择modify来操作这个窗口中的栈。OllyDbg会在一些栈单元上显
示一些有用的注释,这些注释描述了调用一个api之前栈中存放的参数。
内存转存面板窗口 这个窗口用来显示被调试进程的实时内存转储。这个窗口中按ctrl+g组合键,并输
入一个内存位置,可以跳转到任何内存地址。
3.内存映射
显示了被调试程序分配的所有内存块。图9-4显示了netcat程序的内存映射。
内存映射是查看程序在内存中布局的一个好方式。会标注可执行成勋的代码段和数据段,所有DLL
程序以及它们的代码段,数据段都是可见的。你可以双击内存映射中的任意一行,显示那个段的内
存存储。你也可以通过右击一段内存转储,然后选择view in Disassembler的方式,将其中的数据
发送到反汇编窗口
基地址重定位。 内存映射可卡因帮助你理解一个PE文件在运行时如何被重定位。基地址重定位是
指Windows中的一个模块没有被加载到其预定基地址时发生的情况。
绝对地址,相对地址。
4.查看线程和堆栈
恶意diamond经常使用多线程。你可以选择通过view-Threads,调出线程面板窗口,查看一个程序
的当前线程。这个窗口显示了线程的内存位置,以及它们当前的活动状态(活动,暂停,挂起).
由于OllyDbg是单线程的,可能需要你先暂停所有的线程,设置一个断点后,继续运行程序,这样
可以确保在一个特定线程内调试。单击主工具栏中的暂停按钮,可以暂停所有活动的线程。右键
单机其中一个线程弹出的选项,可以选择kill thread可以终止这个线程。
给定进程中的每个线程有自己的栈,通常情况下,线程的重要数据都保存在栈中。
5.执行代码
6.断点,同第八章
内存断点,可以在一个内存块设置内存断点,支持内存读,写,执行或其他权限访问是否产生
中断的设置。
7.加载DLL
Dll不可以直接运行,使用了loaddll.exe的虚拟程序来加载它。由于恶意代码经常打包成DLL,
且其大部分代码都会包含在DLL的DLLMain函数中,因此OllyDbg的这种技术非常有用。默
认情况下,一旦DLL被加载,OllyDbg会在DLL的入口点(DLLMain)处中断。
如果要用参数调用调试DLL中的导出函数,首先OLLYDbg加载DLL,然后在其入口点暂停
DLL的执行,最后单机Play按钮,运行DllMain函数,以及其他一些DLL要求的初始化操作。
DLLMain执行结束后,接下来OllyDbg会暂停DLL的执行。通过在主菜单中选择
Debug->Call Dll Export,你可以使用参数来调用DLL导出的具体函数,并调试它。
8.跟踪。
标准回溯跟踪, 使用 - 路退回上一次运行的指令。 使用+可以执行下一条指令。
堆栈调用跟组, 在OllyDbg中,用过堆栈跟踪可以查看一个给定函数的执行路径。
为了查看堆栈调用,在主菜单中选择view->Call Stack,会弹出一个窗口,显示当
前位置之前的调用序列。
运行跟踪。 运行跟踪是指在运行代码时,OllyDbg会保存所有运行过的指令,以及
它们运行过程中对寄存器和标志所做的改变。
- 在反汇编面板窗口中高亮,你要跟踪的代码。右键单机代码,选择Run Trace->Add Selection。
代码运行后,选择View->Run Trace,查看运行过的指令。使用键盘上的 - 和 + 来上下浏览代
码,使用这种方法可以查看每条指令执行时所有寄存器发生的变化。
- 选择select Dbug->Set condition。可以在命中条件来使程序暂停之前,跟踪程序的运行。
如果你想在条件断点命中时停止跟踪,并且从发生中断的位置,回溯跟踪查看如何或者为
什么发生中断,这种跟踪方式将对你非常有帮助。
9.异常处理
默认情况下,OllyDbg被附加后会产生异常,附加程序也会停止运行,此时调试器开始接
管控制权。调试器可以处理该异常,也可以将异常转到被调试的应用程序处理。当异常
发生时,OllyDbg会暂停运行,然后你可以选择任何一种方法,来决定是否转到应用程序
的处理:
shift+f7 进入异常
shift+f8 跳过异常
shift+f9 运行异常处理
10.修补
OllyDbg可以容易修改实时的数据,标志和寄存器,也可以将汇编形式的修补代码直接插入
到一个程序。
11.分析shellcode
OllyDbg有一种分析shellcode的简单方法。下面是使用这种方法的步骤:
<1> 将shell code从一个十六进制编辑器复制到剪切板
<2> 将内存映射面板窗口中,选择类型为Priv的内存区域
<3> 双击内存映射面板窗口的某行,会弹出一个十六进制转储窗口,你可以检测它的内容
<4> 在内存映射面板窗口中,右击被选择的区域,选择set access->Full Access,赋予该
区域读,写,运行的权限
<5> 返回内存转储窗口。0字节填充的高亮区域足以容纳整个shellcode ,右键单机选择的内
存区域,选择Binary->Binary paste.这个操作将步骤1中复制的shell code粘贴到选择的区域
<6>使用EIP寄存器,指向你修改的内存区域。(右击反汇编面板窗口的一条指令,选择
new origin here,你可以很容易设置EIP寄存器的值.
上述步骤结束后,就可以像对待正常程序一样运行,调试,单步整个shellcode。
12.协助功能
日志
监视窗口
帮助
标注
13.插件
ollydump 脱壳
调试器隐藏插件 防止恶意代码使用反调试技术,
命令行
书签
14.脚本调试
实验
用ollydbg和ida pro分析恶意代码文件Lab09-01.exe,回答下列问题。在第三章中,我们使用基础的静态和动态分析技术,已经对这个恶意代码做了初步分析。
Lab 9-1
问题
1.如何让这个恶意代码安装自身?
参数是否是一个
2.这个恶意代码的命令行选项是什么?它要求的密码是什么?
re,in,密码是abcd
if ( strlen((const char *)a1) == 4 ) //判断长度是否为4
{
if ( *(_BYTE *)a1 == 97 ) //判断第一个字符是否为a
{
v2 = *(_BYTE *)(a1 + 1) - *(_BYTE *)a1; //偏移一个字符,减去a 判断是否为1极为 下一个字符是否为a+1 ->b
if ( v2 == 1 )
{
v3 = 99 * v2; //99 -> c
if ( v3 == *(_BYTE *)(a1 + 2) )
result = (char)(v3 + 1) == *(_BYTE *)(a1 + 3);//判断是否为d,因为v3为c
else
result = 0;
}
else
{
result = 0;
}
}
else
{
result = 0;
}
}
3.如何利用OllyDbg永久修补这个恶意代码,使其不需要指定的命令行密码?
判断密码之后修改为jmp。
4.这个恶意代码基于系统的特征是什么?
会创建注册表项 “SOFTWARE\Microsoft \XPS”,设置注册表项
创建服务 manger service,
5.这个恶意代码通过网络安全执行了那些不同的操作?
下载,和上传
6.这个恶意代码是否有网络特征?
下载,和上传
Lab 9-2
用OllyDbg分析恶意代码文件Lab09-02.exe,回答下列问题。
问题
1.在二进制文件中,你看到的静态字符是什么?
runtime error
2.当你运行这个二进制文件时,会发生什么?
直接运行结束,没有发现
3.怎样让恶意代码的攻击负载(payload)获得运行?
将文件名改为ocl.exe
4.在地址0x0040 1133处发生了什么?
一连串的字符,
5.传递给子例程(函数)0x0040 1089的参数是什么?
一个是之前的字符串,一个地址
6.恶意代码使用的域名是什么?
0019FB24 www.practicalmalwareanalysis.com
7.恶意代码使用什么编码函数来混淆域名?
先对域名进行异或存放,然后进行调用 0x00401089进行还原
8.恶意代码在0x0040 106E处调用CreateProcessA 函数的意义是什么?
创建一个cmd命令窗口用来等待命令。
Lab 9-3
使用OllyDbg和IDA pro分析恶意代码文件Lab09-03.exe这个恶意diamond加载3个自带的dll(DLL1.dll,DLL2.dll,DLL3.dll),它们在编译时请求相同的内存加载位置。因此,在OllyDbg中对照IDA Pro浏览这些DLL可以发现,相同代码可能会出现在不同的内存位置。这个实验的目的是让你在使用OllyDbg看代码时可以轻松的在IDA pro里找到它对应的位置。
问题
1.Lab09-03.exe导入了那些DLL?
查看LoadLibrary P代表调用发现俩处调用,查看导入表发现俩个。
2.DLL1.dll,DLL2.dll,DLL3.dll要求的基地址是多少?
使用peid查看都为 DLL1.dll-> 00007000 DLL2.dll-> 00007000 DLL3.dll-> 00007000
3.当使用Olldbg调试Lab09-03.exe时,为Dll1.dll,Dll2.dll,Dll3.dll分配的基地址是什么?
4.当Lab09-03.exe调用DLL1.dll中的一个导入函数时,这个导入函数都做了写什么?
查看dll1printf,获取了当前进程的pid。
5.当Lab09-03.exe调用writeFile函数时,它写入文件名是什么?
6.当Lab09-03.exe使用NetScheduleJobAdd创建一个job时,从那里获取第二个参数的数据?
从dll3中获取的数据
7.在运行或调试Lab09-03.exe,你会看到Lab09-03.exe打印出三块神秘。DLL1,DLL2,DLL3的神秘数据分别是什么?
dll1 是进程pid
dll2是 temp.txt返回的句柄指针 dll3是偏移地址,是用来存放 ping 网站的偏移地址
8.如何将DLL2.dll加载到IDA pro中,使得它与OLLyDbg使用的加载地址匹配?
IDA选择手动加载