Windows内核结构
第一篇博客,随便写下练练手:)
Windows内核总共分为三层:
-
与硬件直接打交道的这一层叫做硬件抽象层简称HAL,这一层的用意就是把所有与硬件相关联的代码逻辑隔离到一个专门的模块中,从而做到尽可能的独立于硬件平台。
-
HAL之上是内核层,有时也称为微内核,这一层包含了基本的操作系统原语和功能,如线程和进程、线程调度、终端和异常的处理、同步对象和各种同步机制(比如自旋锁)
-
在内核层之上则是执行体层,这一层的目的是提供一些可供上层应用程序的或内核驱动程序直接调用的功能和语义。
执行体层和内核层位于同一个二进制模块中即内核基本模块:ntoskrnl.exe Windows内核为用户模式代码提供了一组系统服务,供应用程序使用内核的功能。应用程序通常不直接调用这些系统服务,而是通过一组系统DLL,最终通过ntdll.dll切换到内核模式下的执行体API函数中,以调用内核中的系统服务,NTDLL是链接用户模式和内核模式的桥梁。 对于内核提供的每一个系统服务,该DLL都提供了一个相应的存根函数,这些存根函数的名称以“Nt”作为前缀,例如NtCreateProcess、NtOpenFile和NtSetTimer。另外,ntdll还提供了许多系统级别的支持函数,如映像加载器程序函数(“Ldr”为前缀)、系统事件函数(以“Etw”为前缀),以及一般的运行支持函数(以“Rtl”为前缀)和字符串支持函数等。
执行体API函数接受的参数来源于各种应用程序,因此,为了保证系统的健壮性以及抵御来自用户模式的恶意攻击,所有执行体API函数必须保证参数的有效性。这意味着他们必须在恰当的时候检查参数的值,若是指针的话,还必须保证调用者可以访问指针所指的内存。通常会在服务函数的开始处检查所有的参数。
检查代码:
PreviousMode = KeGetPreviousMode();
if (PreviousMode != KernelMode) {
try {
ProbeForWrite(InputInformation,
InputInfomationLength,
sizeof(ULONG));
if (ARGUMENT_PRESENT(ReturnLength))
{
ProbeFOrWriteUlong(ReturnLength);
}
except(EXCEPTION_EXECUTE_HANDLER)
{
return GetExceptionCode();
}
}
}