简介

允许用户模式调试工作的内部机制很少得到充分的解释。更糟糕的是,这些机制在Windows XP中已经发生了根本性的变化,当许多支持被重新编写时,还通过将ntdll中的大多数例程作为本地API的一部分,使更多的子系统变得可移植。希望读者对C和通用NT内核体系结构和语义有一些基本的了解。此外,这并不是介绍什么是调试或如何编写调试器。它可以作为经验丰富的调试器编写人员或好奇的安全专家的参考。

Win32 Debugging

NT的Win32子系统从第一个版本开始就允许对进程进行调试,随后的版本添加了更多与符号和其他PE信息相关的特性和调试帮助库。但是,对于外部API用户来说,除了在Windows XP中添加的停止调试进程而不杀死进程的功能之外,其他的变化相对较少。NT的这个版本还包含了对底层实现的几次彻底检查,我们将对此进行详细讨论。但是,这些更改的一个重要副作用是不再使用LPC(和csrss.exe),这允许调试这个二进制文件(以前,调试这个二进制文件是不可能的,因为它负责处理内核到用户的通知)。
处理调试进程的基本win32api很简单:DebugActiveProcess,to attach,WaitForDebugEvent,等待调试事件的出现,以便调试可以处理它们,ContinueDebugEvent,恢复线程执行。WindowsXP的发布增加了三个更有用的API:Debug活动进程,它允许您停止调试一个进程(Debug),Debug GestPosikIon退出,这允许您即使在它被拆分和Debug处理之后继续运行一个进程,它允许您执行远程DebugBreak,而无需手动创建远程线程。在Windows XP Service Pack 1中,又添加了一个API,CheckRemoteDebuggerPresent。与IsDebuggerPresent类似,此API允许您在另一个进程中检查连接的调试器,而无需远程读取PEB。
由于NT的体系结构,这些api在最新版本的Windows上(2003将被用作一个例子,但是这些信息也适用于XP)本身做不了多少工作。相反,它们执行的典型工作是调用所需的Native函数,然后处理输出,以便Win32调用方能够以与Win9x和原始Win32 API定义兼容的格式使用它。让我们看看这些非常简单的实现:

BOOL
WINAPI
DebugActiveProcess(IN DWORD dwProcessId)
{
NTSTATUS Status;
HANDLE Handle;
/*Connect to the debugger*/Status=DbgUiConnectToDbg();if (!NT_SUCCESS(Status))
{
SetLastErrorByStatus(Status);
returnFALSE;
}
/*Get the process handle*/Handle=ProcessIdToHandle(dwProcessId);if (!Handle) returnFALSE;/*Now debug the process*/Status=DbgUiDebugActiveProcess(Handle);
NtClose(Handle);
/*Check if debugging worked*/ if (!NT_SUCCESS(Status))
{
/*Fail*/SetLastErrorByStatus(Status);returnFALSE;
}
/*Success*/ returnTRUE;
}

标签: none

添加新评论