我是靠谱客的博主 积极背包,最近开发中收集的这篇文章主要介绍与调试相关的系统级函数,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

PEB相关
 
#include <windows.h>
#include <stdio.h>
bool PEB_BeingDebugged()
{
    bool BeingDebugged = false;
    _asm
    {
        mov eax, dword ptr fs : [0x30];//dt _PEB
        mov al, byte ptr ds : [eax + 0x02];//BeingDebugged
        mov BeingDebugged, al;
    }
    return BeingDebugged;
}
int main()
{
    bool bDebug = false;
    bDebug = PEB_BeingDebugged();//等价于IsDebuggerPresent()
    printf("%dn", bDebug);
    system("pause");
    return 0;
}

  • ProcessHeap的Flags与ForceFlags正常情况下为2与0,处于调试态会发生改变,此方法在NT 5.x版本以上无效。
 
#include <windows.h>
#include <stdio.h>
bool PEB_ProcessHeap()
{
    int nFlags = 0;
    int nForceFlags = 0;
    _asm
    {
        PUSHAD;
        mov eax, dword ptr FS : [0x30];
        mov eax, dword ptr ds : [eax + 0x18];
        mov ebx, dword ptr ds : [eax + 0x0c];
        mov ecx, dword ptr ds : [eax + 0x10];
        mov nFlags, ebx;
        mov nForceFlags, ecx;
        POPAD;
    }
    return (nFlags == 2 && nForceFlags == 0) ? false : true;
}
int main()
{
    bool bDebug = false;
    bDebug = PEB_ProcessHeap();
    printf("%dn", bDebug);
    system("pause");
    return 0;
}

  • NtGlobalFlag在当前进程处于调试状态时的值为0x70
 
#include <windows.h>
#include <stdio.h>
bool PEB_NtGlobalFlag()
{
    int nNtGlobalFlag = 0;
    _asm
    {
        mov eax, dword ptr fs:[0x30];
        mov eax, dword ptr ds : [eax + 0x68];
        mov nNtGlobalFlag, eax;
    }
    return (nNtGlobalFlag != 0x70) ? false : true;
}
int main()
{
    bool bDebug = false;
    bDebug = PEB_NtGlobalFlag();
    printf("%dn", bDebug);
    system("pause");
    return 0;
}

  • NtQueryInformationProcess-ProcessDebugPort,如果目标进程处于未调试状态,端口为0,否则为0xFFFFFFFF
 
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
bool NQIP_ProcessDebug()
{
    int nDebugPort = 0;
    NtQueryInformationProcess(
        GetCurrentProcess(),
        ProcessDebugPort,
        &nDebugPort,
        sizeof(nDebugPort),
        NULL);
    return nDebugPort == 0xFFFFFFFF ? true : false;
}
int main()
{
    bool nDebug = false;
    nDebug = NQIP_ProcessDebug();
    printf("%dn", nDebug);
    system("pause");
    return 0;
}

  • ProcessDebugObjectHandle可以获取目标进程的调试对象句柄,如果未处于调试状态,则获取的值为NULL
 
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
bool NQIP_ProcessDebugObjectHandle()
{
    HANDLE hDebug = NULL;
    NtQueryInformationProcess(
        GetCurrentProcess(),
        (PROCESSINFOCLASS)0x1E,
        &hDebug,
        sizeof(hDebug),
        NULL);
    return hDebug? true : false;
}
int main()
{
    bool nDebug = false;
    nDebug = NQIP_ProcessDebugObjectHandle();
    printf("%dn", nDebug);
    system("pause");
    return 0;
}

  • ProcessDebugFlag可获取目标进程的调试标记,若处于调试状态值为0,否则为1
 
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
bool NQIP_ProcessDebugFlag()
{
    BOOL bDebugFlag = FALSE;
    NtQueryInformationProcess(
        GetCurrentProcess(),
        (PROCESSINFOCLASS)0x1F,
        &bDebugFlag,
        sizeof(bDebugFlag),
        NULL);
    return bDebugFlag ? false : true;
}
int main()
{
    bool nDebug = false;
    nDebug = NQIP_ProcessDebugFlag();
    printf("%dn", nDebug);
    system("pause");
    return 0;
}

  • 可获取指定进程的父进程PID,将其与Explorer.exe的PID对比,不匹配则不是被双击运行的。
 
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
bool NQIP_CheckParentProcess()
{
    struct PROCESS_BASIC_INFORMATION
    {
        ULONG ExitStatus;//进程返回码
        PPEB PebBaseAddress;//PEB地址
        ULONG AffinityMask;//CPU亲和性掩码
        LONG BasePriority;//基本优先级
        ULONG UniqueProcessId;//本进程PID
        ULONG InheritedFromUniqueProcessId;//父进程PID
    }stcProcInfo;
    NtQueryInformationProcess(
        GetCurrentProcess(),
        ProcessBasicInformation,
        &stcProcInfo,
        sizeof(stcProcInfo),
        NULL);
    DWORD dwExplorerPID = 0;
    DWORD dwCurrentPID = stcProcInfo.InheritedFromUniqueProcessId;
    GetWindowThreadProcessId(FindWindow("explorer.exe", NULL), &dwExplorerPID);
    return dwExplorerPID == dwCurrentPID ? false : true;
}
int main()
{
    bool nDebug = false;
    nDebug = NQIP_CheckParentProcess();
    printf("%dn", nDebug);
    system("pause");
    return 0;
}

  • NtQuerySystemInformation()可获取当前系统是否开启调试模式
 
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
bool NQSI_SystemKernelDebuggerInformation()
{
    struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
    {
        BOOLEAN DebuggerEnabled;
        BOOLEAN DebuggerNotPresent;
    }DebuggerInfo = {0};
    NtQuerySystemInformation(
        (SYSTEM_INFORMATION_CLASS)0x23,
        &DebuggerInfo,
        sizeof(DebuggerInfo),
        NULL);
    return DebuggerInfo.DebuggerEnabled;
}
int main()
{
    BOOLEAN bDebug = FALSE;
    bDebug = NQSI_SystemKernelDebuggerInformation();
    printf("%dn", bDebug);
    system("pause");
    return 0;
}

  • NtQueryObject
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
bool NQO_NtQueryObject()
{
    typedef struct _OBJECT_TYPE_INFORMATION
    {
        UNICODE_STRING TypeName;
        ULONG TotalNumberOfHandlers;
        ULONG TotalNumberOfObjects;
    }OBJECT_TYPE_INFORMATION, *POBJECT_TYPE_INFORMATION;
    typedef struct _OBJECT_ALL_INFORMATION
    {
        ULONG NumberOfObjectTypes;
        OBJECT_TYPE_INFORMATION ObjTypeInfo[1];
    }OBJECT_ALL_INFORMATION, *POBJECT_ALL_INFORMATION;
    ULONG uSize = 0;
    NtQueryObject(NULL, (OBJECT_INFORMATION_CLASS)0x03, &uSize, sizeof(uSize), &uSize);
    POBJECT_ALL_INFORMATION pObj = (POBJECT_ALL_INFORMATION)new BYTE[uSize];
    NtQueryObject(NULL, (OBJECT_INFORMATION_CLASS)0x03, pObj, uSize, &uSize);
    POBJECT_TYPE_INFORMATION pObjTypeInfo = pObj->ObjTypeInfo;
    for (int i = 0; i < pObj->NumberOfObjectTypes; ++i)
    {
        if (!wcscmp(L"DebugObject", pObjTypeInfo->TypeName.Buffer))return true;
        //获取对象名占用空间大小
        ULONG uNameLength = pObjTypeInfo->TypeName.Length;
        ULONG uDataLength = uNameLength - uNameLength % sizeof(ULONG) + sizeof(ULONG);
        //指向下一个对象
        pObjTypeInfo = (POBJECT_TYPE_INFORMATION)pObjTypeInfo->TypeName.Buffer;
        pObjTypeInfo = (POBJECT_TYPE_INFORMATION)((PBYTE)pObjTypeInfo + uDataLength);
    }
    delete[] pObj;
    return false;
}
int main()
{
    bool bDebug = false;
    bDebug = NQO_NtQueryObject();
    printf("%dn", bDebug);
    system("pause");
    return 0;
}

  • ZwSetInformationThread,此函数可以主动脱离调试器,这个碉堡了。
 
#include <windows.h>
#include <winternl.h>
#pragma comment(lib,"ntdll.lib")
#include <stdio.h>
typedef enum THREAD_INFO_CLASS
{ ThreadHideFromDebugger = 17 };
typedef NTSTATUS(NTAPI *ZW_SET_INFORMATION_THREAD)
(
_In_ HANDLE ThreadHandle,
_In_ THREAD_INFO_CLASS ThreadInformationClass,
_In_ PVOID ThreadInformation,
_In_ ULONG ThreadInformationLength
);
void ZSIT_DetachDebug()
{
    ZW_SET_INFORMATION_THREAD Func;
    Func = (ZW_SET_INFORMATION_THREAD)GetProcAddress(LoadLibrary("ntdll.dll"), "ZwSetInformationThread");
    Func(GetCurrentThread(), ThreadHideFromDebugger, NULL, NULL);
}
int main()
{
    ZSIT_DetachDebug();
    return 0;
}

最后

以上就是积极背包为你收集整理的与调试相关的系统级函数的全部内容,希望文章能够帮你解决与调试相关的系统级函数所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(47)

评论列表共有 0 条评论

立即
投稿
返回
顶部