• 8.3 NtGlobalFlag


    NtGlobalFlag 是一个Windows内核全局标记,在Windows调试方案中经常用到。这个标记定义了一组系统的调试参数,包括启用或禁用调试技术的开关、造成崩溃的错误代码和处理方式等等。通过改变这个标记,可以在运行时设置和禁用不同的调试技术和错误处理方式,比如调试器只能访问当前进程、只允许用户模式调试、启用特定的错误处理方式等等。但由于NtGlobalFlag标记是内核全局标记,其改变会影响整个系统的行为,需要谨慎处理。

    利用该标记反调试,首先定位dt -rv ntdll!_TEB找到TEB结构并通过TEB找到PEB结构,然后找到+0x068 NtGlobalFlag,这个位置的NtGlobalFlag类似于BeingDebugged,如果是调试状态NtGlobalFlag的值会是0x70,所以可以判断这个标志是否为0x70来判断程序是否被调试了,首先我们来使用汇编代码解决。

    #include 
    #include 
    
    // 返回调试状态
    BOOL IsDebug()
    {
        DWORD Debug = 0;
        __asm
        {
            mov eax, fs:[0x18]       // TEB基地址
            mov eax, [eax + 0x30]    // 找到PEB
            mov eax, [eax + 0x68]    // 找打 NtGlobalFlag
            mov Debug, eax           // 取出值
        }
    
        if (Debug == 112)
        {
            return TRUE;
        }
    
        return FALSE;
    }
    
    int main(int argc, char * argv[])
    {
    
        if (IsDebug)
        {
            printf("[-] 程序正在被调试 \n");
        }
        else
        {
            printf("[*] 程序正常 \n");
        }
    
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38

    当然除了使用纯汇编实现反调试外,我们也可以使用NativeAPI中的ZwQueryInformationProcess()这个函数来读取到程序中的PET数据,然后判断PebBase+0x68是否等于70,由于这个函数并没有公开,所以在使用时应该自行声明一下结构类型。

    #include 
    #include 
    #include 
    
    // 声明该函数
    typedef NTSTATUS(NTAPI *typedef_ZwQueryInformationProcess)(
        IN HANDLE ProcessHandle,
        IN PROCESSINFOCLASS ProcessInformationClass,
        OUT PVOID ProcessInformation,
        IN ULONG ProcessInformationLength,
        OUT PULONG ReturnLength OPTIONAL
        );
    
    // 调试状态检测
    BOOL IsDebug()
    {
        HANDLE hProcess = NULL;
        DWORD ProcessId = 0;
        PROCESS_BASIC_INFORMATION Pbi;
        typedef_ZwQueryInformationProcess pZwQueryInformationProcess = NULL;
        ProcessId = GetCurrentProcessId();
        hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessId);
    
        if (hProcess != NULL)
        {
            HMODULE hModule = LoadLibrary("ntdll.dll");
            pZwQueryInformationProcess = (typedef_ZwQueryInformationProcess)GetProcAddress(hModule, "ZwQueryInformationProcess");
    
            NTSTATUS Status = pZwQueryInformationProcess(hProcess, ProcessBasicInformation, &Pbi,sizeof(PROCESS_BASIC_INFORMATION), NULL);
            if (NT_SUCCESS(Status))
            {
                DWORD ByteRead = 0;
                WORD NtGlobalFlag = 0;
                ULONG PebBase = (ULONG)Pbi.PebBaseAddress;
    
                // 读取调试标志并判断
                if (ReadProcessMemory(hProcess, (LPCVOID)(PebBase + 0x68), &NtGlobalFlag, 2, &ByteRead) && ByteRead == 2)
                {
                    if (NtGlobalFlag == 0x70)
                    {
                        return TRUE;
                    }
                }
            }
            CloseHandle(hProcess);
        }
    
        return FALSE;
    }
    
    int main(int argc, char * argv[])
    {
        if (IsDebug() == TRUE)
        {
            printf("[-] 进程正在被调试 \n");
        }
        else
        {
            printf("[*] 程序正常 \n");
        }
    
        system("pause");
        return 0;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
  • 相关阅读:
    在pandas中使用query替代loc进行高效简洁的条件筛选
    tsfresh:一款表现出色的自动化提取时序特征的 Python 工具包
    一分钟了解 ‘|’ ‘&’ ‘^’ 运算
    Oracle EBS 动态调用 XML Publisher 模板 输出不同的报表
    桂院校园导航 静态项目 二次开发教程 1.3
    目前全球生物识别市场规模迅速扩张,虹膜识别技术也发展迅猛
    pandas 筛选数据的 8 个骚操作
    战略篇-EMC三板斧
    .NET C#版本和.NET版本以及VS版本的对应关系
    Ubuntu下安装Go
  • 原文地址:https://blog.csdn.net/lyshark_csdn/article/details/133304052