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");
}

用调试器打开程序,结果如下:

posted @ 2025-02-17 22:01  lostin9772  阅读(6)  评论(0)    收藏  举报