使用WinDbg调试内核


知识点

WinDbg是微软提供的一个免费调试器,支持内核调试,也具有监控Windows系统交互的功能。

驱动与内核代码:Windows设备驱动简称为驱动,他让第三方开发商在Windows内核模式下运行代码。驱动程序常驻与内存,并且负责响应用户态程序的请求,而且应用程序不直接与驱动程序通信,而是直接访问设备对象,向具体的物理设备发送请求。设备对象由驱动程序创建和销毁,可以被用户态的程序直接访问,但他们并不一定是真实的物理设备。为了系统能正常工作,驱动程序必须加载到内核空间,这与DLL需要加载到进程空间道理相同,当驱动被首次加载时,DriverEntry函数将被调用。

与DLL通过导出函数表来提供其功能不同,驱动程序通过注册回调函数来提供功能。当用户态的应用程序请求一个服务时,这些回调函数将被调用。回调函数在DriverEntry程序中被注册。Window会为每个条创建一个驱动对象,并以参数形式将其传递给DriverEntry函数,DriverEntry函数用回调函数填充这个驱动对象。然后DriverEntry会创建一个可以被用户态应用程序访问的设备对象,应用程序与去当的交互请求都通过这个设备对象进行。

考虑到来自用户态应用程序的一个读取数据的请求。最终这个请求发送到负责管理硬件并存储读入数据的驱动程序。首先,用户态的应用程序应该获得该硬件设备的一个文件句柄,然后再该具柄上调用函数ReadFile,接着内核会处理ReadFile函数的请求,最终由驱动程序的回调函数来响应对IO设备的读请求。七个球内核态的而已组建最常见函数时DeviceIoControl,它是从用户态模块到内核折别的一种通用请求方法,使用该函数时,用户态应用程序传递一个任意长度的缓冲区数据作为输入,并且接收一个任意长度的缓冲区作为输出。

安装内核调试:由于运行内核调试时操作系统会被冻结,因此我们需要Vmware来进行这一操作,与用户态调试不同,内核调试需要一些初始化设置。首先要在虚拟机系统中开启内核调试,然后配置Vmware使虚拟机与宿主系统之间有一条虚拟化的串口,同时还应该配置宿主系统中的WinDbg。详细的配置方法在网上能搜索到,在这里就不赘述了 。

boot.ini

1
2
3
4
5
6
[boot loader]
timeout=30
default=multi(0)disk(0)rdisk(0)partition(1)\WINDOWS
[operating systems]
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional" /noexecute=optin /fastdetect
multi(0)disk(0)rdisk(0)partition(1)\WINDOWS="Microsoft Windows XP Professional with Kernel Debugging" /noexecute=optin /fastdetect /debug /debugport=COM1 /baudrate=115200

WinDbg读取内存中的数据:通过再WinDbg的内存窗口输入如下指令来读取程序数据或堆栈等内存位置:

1
dx addressToLoad
选项 描述
da 读取内存数据并以ASCII文本显示
du 读取内存数据并以Unicode文本显示
dd 读取内存数据并以32位双字显示

e命令与d类似,可以用来改变内存中的值:

1
ex addressToWrite data

使用算术运算符:Windbg支持再命令行中使用简单的算术操作符,对内存和寄存器进行直接操作,如加减乘除。命令dwo用来解引用一个32位的指针并查看该指针代表的地址的值。例如设置一个函数断点,该函数的第一个参数是一个宽字符串指针,通过下面命令可以查看字符串的内容:

1
du dwo (esp+4)

设置断点:使用bp命令来设置基本断点,使用g(go)命令可以再断点处执行一个动作后继续执行而不用等待用户,例如,下面这个命令可以再每次调用GetProcAddress函数时,在不中断程序执行的前提下,打印出第二个参数:

1
bp GetProcAddress "da dwo(esp+8);g"

列举模块:WinDgb无法向OD一样通过内存映射列举出所有内存段与加载模块,但是Windbg没有类似的功能。但是可以使用lm命令来列举加载到进程空间的所有模块,包括用户模式下的可执行模块,DLL以及内核模式下的内核驱动,同时也会列举出每个模块的起始与结束地址。

微软符号表:调试符号提供了游戏安的源代码信息,用来帮助我们理解汇编代码,微软的调试符号表中包含默写函数和变量的名字。

搜索符号:WinDbg的符号格式如下:

1
moduleName!symbolName

这种语法可以在任何一个拥有正常地址的地方使用,其中moduleName表示exedll或者sys文件的文件名(不包含文件扩展名),SymbolName是与这个地址关联的一个名字。其中ntoskrnl.exe文件是一个特例,他的moduleNament

bu命令允许我们用符号在没有加载的代码中设置一个延迟断点。延迟断点是一个断点,当加载的额名字匹配模块时延迟断点才会被设置。命令bu $iment(driverName)回在任何驱动程序代码运行之前在其入口点设置一个断点。

z命令可以用来使用通配符来搜索函数或者符号。如使用x nt!*CreateProcess*可以搜索ntoskrnl.exe中包含字符串CreateProcess的所有函数。

ln命令用来例如出最接近给定内存地址的符号,他可以用来确认指针指向的函数。

查看结构信息:微软符号也包含多个数据结构的类型信息,包括没有被公开的内部类型。这对恶意代码分析人员非常有用,因为恶意代码经常操作未公开的数据结构。

内核代码:恶意代码的编写者坑会从内核空间写文件,因为这样可能会绕过一些安全产品的审查,同时也可以误导哪些尝试查找用户空间中CreateFileWriteFile函数作为调用证据的恶意代码分析师。在内核模式下,普通的Win32函数不能直接被调用,所以内核模式下会有新的函数来取代这些函数。

内核模式的代码:在使用VMware调试内核时,如果看到系统频繁的加载和卸载KMixer.sys这是正常现象,与恶意活动无关。我们需要找到驱动对象来确定调用了哪些恶意驱动的代码。我们能知道驱动的名字,所以我们可以使用!drvobj命令来找到驱动对象。

Rootkit:Rootkit通过修改操作系统内部函数来隐藏自己存在的痕迹。通过这种修改,Rootkit可以隐藏一个长在运行的程序的文件、进程、网络连接等其他资源,这种恶意活动难以被反病毒产品及安全分析员发现。大部分Rootkit时通过某种方式来修改操作系统内核来工作的,但是在实际应用中,系统服务描述表挂钩技术的使用成都远远超过其他技术,但是缺点是容易被探测,但是由于这种方法实现简单且便于使用,因此到现在这种方法还是很常见。

系统服务描述表(SSDT):也成为系统服务分发表,微软使用它来查找进入内核的系统调用,它通常不被第三方应用程序或者驱动程序访问,内核态代码只能被用户态的SYSCALLSYSENTERINT 0x2E指令来访问。

Rootkit挂钩SSDT:假设一个系统已经感染了恶意驱动,我们需要先检查SSDT是否被挂钩,在WinDbg中通过存放在nt!KeServiceDescripterTable表中的偏移量查看SSDT表。SSDT表中的所有函数偏移量都因该指向位于NT模块的地址范围内的函数,通过查看ntoskrnl.exe模块的起始地址和结束地址来确定地址边界,若表中的地址在这个地址边界之外,那么就能确定SSDT被挂钩了。一旦确定了被挂钩的驱动程序(lm指令),下一步就是查找安装挂钩的代码段和执行挂钩的函数,在IDA中查找挂钩函数引用的数据。

中断:有时Rootkit使用中断来干扰系统时间,现代的处理器实现了用硬件方式触发软件事件的中断,系统发送一条指令到硬件,硬件处理完请求事件后会中断处理器。有时驱动或Rootkit会使用中断来执行代码,驱动程序调用IoConnectInterrup函数位特定中断注册一个处理程序,然后为这个中断指定一个中断服务例程(ISR),每当触发该中断时,系统都会调用注册的中断服务例程。中断描述表(IDT)中存储着ISR的信息,在WinDbg中可以通过!idt命令查看。如果发现中断位于一个没有名字、没有签名或可疑的驱动中,则表明存在Rootkit或者恶意代码。

加载驱动:我们可以通过OSR Driver Loader加载工具来加载驱动程序。

Windows系统更新带来的差异:新的Windows做了很大的改变,这些改变会涌向内核调试的过程每一集恶意代码的有效性。从Windows Vista开始,最大的一个改变就是boot.ini文件不再用来负责引导系统,我们需要BCDEdit工具来修改引导配置。在安全方面,新的系统引入了内核保护补丁机制,通常被称为PatchGuard,内核保护能组织第三方程序修改内核。在64位版本的Vista系统中,Windows强制执行驱动签名机制,没有数字签名的内核驱动无法被加载到系统中,所以这是一个对抗恶意内核驱动的有效措施。

课后练习

Lab10-1

本实验包括一个驱动程序和一个可执行文件。你可以从任意位置运行可执行文件,但为了使程序能正常运行,,必须将程序放到C:\Windows\System32目录下,这个目录在受害者的计算机中已存在。可执行文件使Lab10-1.exe,驱动程序使Lab10-01.sys。

问题

1.这个程序是否直接修改了注册表(使用Procmon来检查)?

ProcMon中发现程序只对如下键进行了修改:

1
2
HKLM\SOFTWARE\Microsoft\Cryptography\RNG\Seed
Type: REG_BINARY, Length: 80, Data: 5D 5E 85 61 23 D1 3F 6F 65 AE D8 01 B5 2E 98 EA

2.用户态的程序调用了ControlService函数,你是否能够使用WinDbg设置一个断点,从此来观察由于ControlService的调用导致内核执行了怎样的操作。

在IDA中看到Lab10-01.exe调用了ControlService来进行驱动的写在操作,为了方便分析,在WindowsXP中安装WinDbg来打开Lab10-01.exe并在ControlService调用处下一个断点:

1
2
3
4
.text:0040107C                 push    eax             ; lpServiceStatus
.text:0040107D push 1 ; dwControl
.text:0040107F push esi ; hService
.text:00401080 call ds:ControlService

Windbg中信息:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Executable search path is: 
ModLoad: 00400000 00407000 image00400000
ModLoad: 7c920000 7c9b3000 ntdll.dll
ModLoad: 7c800000 7c91e000 C:\WINDOWS\system32\kernel32.dll
ModLoad: 77da0000 77e49000 C:\WINDOWS\system32\ADVAPI32.dll
ModLoad: 77e50000 77ee2000 C:\WINDOWS\system32\RPCRT4.dll
ModLoad: 77fc0000 77fd1000 C:\WINDOWS\system32\Secur32.dll
(c0.f8): Break instruction exception - code 80000003 (first chance)
eax=00241eb4 ebx=7ffd6000 ecx=00000007 edx=00000080 esi=00241f48 edi=00241eb4
eip=7c92120e esp=0012fb20 ebp=0012fc94 iopl=0 nv up ei pl nz na po nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000202
*** ERROR: Symbol file could not be found. Defaulted to export symbols for ntdll.dll -
ntdll!DbgBreakPoint:
7c92120e cc int 3
0:000> bp 00401080
breakpoint 0 redefined

点击运行,运行至断点处WinDbg输出如下信息:

1
2
3
4
5
6
7
Breakpoint 0 hit
eax=0012ff1c ebx=7ffd6000 ecx=77dbfb6d edx=00000000 esi=00144050 edi=00144f60
eip=00401080 esp=0012ff08 ebp=0012ffc0 iopl=0 nv up ei pl nz na pe nc
cs=001b ss=0023 ds=0023 es=0023 fs=003b gs=0000 efl=00000206
image00400000+0x1080:
*** ERROR: Symbol file could not be found. Defaulted to export symbols for C:\WINDOWS\system32\ADVAPI32.dll -
00401080 ff1510404000 call dword ptr [image00400000+0x4010 (00404010)] ds:0023:00404010={ADVAPI32!ControlService (77dc49dd)}

3.这个程序做了些什么?

这个程序通过创建服务来加载驱动,修改注册表\\Registry\\Machine\\SOFTWARE\\Policies\\Microsoft\\WindowsFirewall\\StandardProfile\\Registry\\Machine\\SOFTWARE\\Policies\\Microsoft\\WindowsFirewall\\DomainProfile来禁用WindowsXP的防火墙

Lab10-2

该实验的文件为Lab10-02.exe。

问题

1.这个程序创建文件了吗,它创建了什么文件?

2.这个程序有内核组件吗?

3.这个程序做了些什么?

Lab10-3

本实验包括一个驱动程序和一个可执行文件。你可以从任意位置运行可执行文件,但为了使程序能正常运行,,必须将程序放到C:\Windows\System32目录下,这个目录在受害者的计算机中已存在。可执行文件使Lab10-3.exe,驱动程序是Lab10-03.sys。

问题

1.这个程序做了些什么?

2.一旦运行,你怎样停止它?

3.它的内核组件做了什么操作?

本章结束🎊

评论

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×