运用WinDbg调试Windows内核(二)
上篇文章介绍了windbg调试内核的根本环境设置以及一些根底调试技巧,这篇文章介绍一些windbg的高档调试技巧。
0×01运用断点盯梢数据
断点一般用在暂停某个咱们感兴趣的履行代码,例如当某个函数被调用时,咱们还能够运用WinDbg断点指令字符串盯梢一些信息。在这儿,咱们将着眼于盯梢特定用户方式进程的风趣信息,即特定数据NOTEPAD.EXE写入到磁盘的一个比如。在开端前,咱们需求在咱们的虚拟机中翻开一个记事本实例。咱们现在能够创立一个断点来阻拦文件体系写入记事本的数据,并一起显现要写入磁盘的数据。
第一步,咱们需求找到Notepad.exe进程的一些信息,以保证咱们只在这个进程里断下,而不是在每个进程都断下。而咱们需求寻觅的信息是一个指向EPROCESS结构的指针。该EPROCESS结构是用来表明一个进程的主内核数据结构。你能够看到包括“DT _EPROCESS”(在EPROCESS结构dump类型)的信息。为了找到一个给定的进程的EPROCESS结构,咱们能够调用!Process扩展指令。该扩展指令打印方针体系中当时活动进程的信息。咱们过滤筛选出notepad的进程,而且只显现最低极限的信息:
该EPROCESS的指针为蓝色杰出“PROCESS”字段,咱们接下来就会用到这个值。
咱们要设置在内核中设置NtWriteFile断点。这是体系的调用,一切用户方式写入磁盘会调用该函数。经过在此处设置断点,咱们能够看到体系一切写入磁盘数据的进程。这样就显得很烦了,所以咱们将运用上述EPROCESS值,要求从咱们挑选的进程上下文中止NtWriteFile函数。咱们能够运用指令如下:
bp /p fffffa800295d060 nt!NtWriteFile "da poi(@rsp+30); g"
这就只在咱们的进程中设置(经过/ P运用咱们的EPROCESS值)NT!NtWriteFile(NT为内核模块的称号)断点。当断点射中时,引号后的指令将运转,这儿由分号来分隔每个指令。这儿现已运用了notepad写显现数据的指令,然后运用“g”重新启动虚拟机履行。可是,为什么“da poi (*@ rsp+ 30)”的显现成果为写入缓冲区数据?
要了解这一部分,咱们需求看看NtWriteFile的函数原型:
NTSTATUS NtWriteFile(
_In_ HANDLE FileHandle,
_In_opt_ HANDLE Event,
_In_opt_ PIO_APC_ROUTINE ApcRoutine,
_In_opt_ PVOID ApcContext,
_Out_ PIO_STATUS_BLOCK IoStatusBlock,
_In_ PVOID Buffer,
_In_ ULONG Length,
_In_opt_ PLARGE_INTEGER ByteOffset,
_In_opt_ PULONG Key
);
来源于这儿
在这个函数的原型中,咱们感兴趣的是Buffer参数。这些缓冲区的数据调经过函数调用最终写入磁盘。在微软64位调用约好中,前四个参数由寄存器( RCX ,RDX,R8和R9 )传递的,剩余的参数是经过仓库来传递的。尽管前4个参数在寄存器中传递调用约好要求在栈上分配空间(这便是所谓的Home Space) 。由于Buffer是第6个参数,在Home Space和第五个参数之后。这意味着,在仓库中止点断下后,仓库中是这样的:
所以指令da poi(@ rsp+ 30)取出寄存器RSP中的值,加上30h刚好指向第6个参数,然后运用POI()引证该值(POI()类似于C语言中的*,回来一个指针巨细的值)。最终,咱们将这个地址传入da(显现ASCII)。咱们能够在监督缓冲区数据,由于咱们知道记事本存储的是纯文本而不是二进制文件。运转这个断点,并在记事本中保存一些文字,WinDbg的输出如下:
运用这种技能,能够经过内核盯梢各种风趣的信息。
0×02更先进的指令用法
经过调试来操作一些数据,常常能够获得更多的有意义的成果。一个很好的比如来阐明其间的一些技能是体系服务描述表(SSDT)。该SSDT形成了一切的体系调用而发生的体系调用表。内核导出的SSDT是具有以下格局符号KeServiceDescriptorTable的结构:
typedef struct _KSERVICE_DESCRIPTOR_TABLE {
PULONG ServiceTableBase; // Pointer to function/offset table (the table itself is exported as KiServiceTable)
PULONG ServiceCounterTableBase;
ULONG NumberOfServices; // The number of entries in ServiceTableBase
PUCHAR ParamTableBase;
} KSERVICE_DESCRIPTOR_TABLE,*PKSERVICE_DESCRIPTOR_TABLE;
在Windows的32位版别,ServiceTableBase是一个指向函数指针数组的指针。在64位中略微有点杂乱,ServiceTableBase指向数组偏移值为32位处,全部都是相对于KiServiceTable在存储器中的表的方位,这使得可视化运用常用的内存显现指令(如dds)是不可能的。相反,咱们将不得不运用一些WinDbgs更高档的指令在列表中迭代,数据操作到一个更适宜的方式。
[1] [2] 黑客接单网