NoDebugInherit 标志位
一、通过检测 NoDebugInherit 标志位
在进程的 EPROCESS
结构体中存在一个 NoDebugInherit
标志位,当进程处于调试状态时,该标志位被置为 1,默认情况为 0。
我们在虚拟机中打开 notepad.exe
程序,并用 x64dbg 附加 notepad 程序,通过如下命令来观察 notepad 程序的 EPROCESS
结构:
dt nt!_EPROCESS ffffe107c29ef1c0
结果如下:
可以看到,在偏移为 0x464 的位置,存在 NoDebugInherit
标志位,且该标志位位于一个名为 Flags
字段的联合体结构中,由于进程处于被调试状态,因此该标志位此时为 1。
1 通过 NtQueryInformationProcess 函数来检测
同样,这个标志位可以通过函数 NtQueryInformationProcess
来检测,指定查询的值为 ProcessDebugFlags(31)
,如果进程处于被调试状态,则返回 0(被调试时其 NoDebugInherit
标志位为 1),没有被调试则返回 1(未被调试时其 NoDebugInherit
标志位为 0),检测代码如下:
#include <stdio.h>
#include <Windows.h>
typedef enum _PROCESSINFOCLASS {
ProcessBasicInformation,
ProcessQuotaLimits,
ProcessIoCounters,
ProcessVmCounters,
ProcessTimes,
ProcessBasePriority,
ProcessRaisePriority,
ProcessDebugPort,
ProcessExceptionPort,
ProcessAccessToken,
ProcessLdtInformation,
ProcessLdtSize,
ProcessDefaultHardErrorMode,
ProcessIoPortHandlers, // Note: this is kernel mode only
ProcessPooledUsageAndLimits,
ProcessWorkingSetWatch,
ProcessUserModeIOPL,
ProcessEnableAlignmentFaultFixup,
ProcessPriorityClass,
ProcessWx86Information,
ProcessHandleCount,
ProcessAffinityMask,
ProcessPriorityBoost,
ProcessDeviceMap,
ProcessSessionInformation,
ProcessForegroundInformation,
ProcessWow64Information,
ProcessImageFileName,
ProcessLUIDDeviceMapsEnabled,
ProcessBreakOnTermination,
ProcessDebugObjectHandle,
ProcessDebugFlags,
ProcessHandleTracing,
ProcessIoPriority,
ProcessExecuteFlags,
ProcessResourceManagement,
ProcessCookie,
ProcessImageInformation,
MaxProcessInfoClass // MaxProcessInfoClass should always be the last enum
} PROCESSINFOCLASS;
typedef NTSTATUS(NTAPI* PFN_NtQueryInformationProcess)(
HANDLE ProcessHandle, // 需查询的进程句柄
DWORD ProcessInformationClass, // 需查询的进程信息枚举类型
PVOID ProcessInformation, // 输出缓冲区
ULONG ProcessInformationLength, // 输出缓冲区大小
PULONG ReturnLength // 实际返回大小
);
// 定义函数指针
PFN_NtQueryInformationProcess NtQueryInformationProcess;
int main()
{
/* 通过 NtQueryInformationProcess 函数检测 NoDebugInherit 标志位 */
// 从 ntdll.dll 中获取 NtQueryInformationProcess 函数的地址
HMODULE hMod = LoadLibraryA("ntdll.dll");
NtQueryInformationProcess = (PFN_NtQueryInformationProcess)GetProcAddress(hMod, "NtQueryInformationProcess");
// 查询 ProcessDebugFlags 字段中的 NoDebugInherit 标志位是否为 1(为 1 则返回 0,为 0 则返回 1)
BOOL NoDebugInherit = 1; // 返回值默认为 1 表示没有被调试
NtQueryInformationProcess(GetCurrentProcess(), ProcessDebugFlags, &NoDebugInherit, sizeof(BOOL), NULL); // ProcessDebugFlags(31)
if (NoDebugInherit == 0)
{
printf("正在被调试\r\n");
}
else
{
printf("没有被调试\r\n");
}
system("pause");
}
用调试器打开程序,结果如下: