将详细分析Windows调试的本机接口。希望读者对C和通用NT内核体系结构和语义有一些基本的了解。此外,这并不是介绍什么是调试或如何编写调试器。它可以作为经验丰富的调试器编写人员或好奇的安全专家的参考。

本机调试

现在是时候看看事情的本机方面,以及ntdll.dll中的包装层如何与内核通信。DbgUi层的优点是它允许更好地分离Win32和NT内核,而NT内核一直是NT设计的一部分。NTDLL和NTOSKRNL是一起构建的,所以他们对彼此有复杂的了解是正常的。它们共享相同的结构,需要有相同的系统调用ID等。在完美的世界中,NT内核应该对Win32一无所知。

此外,它还可以帮助任何希望在本机应用程序中编写调试功能或编写功能齐全的本机模式调试器的人。如果没有DbgUi,就必须手动调用Nt*DebugObject api,并在某些情况下进行大量的前/后处理。DbgUi将所有这些工作简化为一个简单的调用,并提供一个干净的接口来完成。如果内核在内部发生变化,DbgUi可能会保持不变,只会修改其内部代码。

我们从负责创建调试对象并将其与当前进程关联的函数开始探索。与Win32不同,创建调试对象和实际附加到进程之间有着明显的区别。

NTSTATUS
NTAPI
DbgUiConnectToDbg(VOID)
{
OBJECT_ATTRIBUTES ObjectAttributes;
/*Don't connect twice*/ if (NtCurrentTeb()->DbgSsReserved[1]) returnSTATUS_SUCCESS;/*Setup the Attributes*/InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, 0);/*Create the object*/ return ZwCreateDebugObject(&NtCurrentTeb()->DbgSsReserved[1],
DEBUG_OBJECT_ALL_ACCESS,
&ObjectAttributes,
TRUE);
}

标签: none

添加新评论