• 标 题:检测debugger的方法补遗 (4千字)
  • 作 者:blowfish
  • 时 间:2001-6-28 17:12:34
  • 链 接:http://bbs.pediy.com

还是这个论坛对源码格式处理得比较好

下面这几个都是利用的WinNT的native API来检查debugger的,所以不能运行在Win9x/ME上。

1、ZwQuerySystemInformation
用这个可以检查系统调试器是否存在,对SoftICE似乎无用,估计只对微软自家的WinDBG有效,有条件的可测试一下。

2、ZwSetInformationThread
用这个函数可以将某个线程的调试端口设为0,使得Win32调试器无法再收到该线程的调试事件,使调试器无法再调试该线程。这个主要是针对VC++这样的ring3调试器的。

3、ZwQueryInformationProcess
这个可以检查某个进程是否正被ring3调试器所调试。

测试程序:

#include <windows.h>
#include <iostream.h>

#define NTAPI              __stdcall
typedef long              NTSTATUS;
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define STATUS_SUCCESS    ((NTSTATUS)0L)

typedef struct _SYSTEM_KERNEL_DEBUGGER_INFORMATION
{
    BOOLEAN DebuggerEnabled;
    BOOLEAN DebuggerNotPresent;
} SYSTEM_KERNEL_DEBUGGER_INFORMATION, *PSYSTEM_KERNEL_DEBUGGER_INFORMATION;

typedef struct _PROCESS_DEBUG_PORT_INFO
{
    HANDLE DebugPort;
}    PROCESS_DEBUG_PORT_INFO;

enum SYSTEM_INFORMATION_CLASS { SystemKernelDebuggerInformation = 35 };
enum THREAD_INFO_CLASS        { ThreadHideFromDebugger          = 17 };
enum PROCESS_INFO_CLASS      { ProcessDebugPort                = 7  };

typedef NTSTATUS  (NTAPI *ZW_QUERY_SYSTEM_INFORMATION)(IN SYSTEM_INFORMATION_CLASS SystemInformationClass, IN OUT PVOID SystemInformation, IN ULONG SystemInformationLength, OUT PULONG ReturnLength);
typedef NTSTATUS  (NTAPI *ZW_SET_INFORMATION_THREAD)(IN HANDLE ThreadHandle, IN THREAD_INFO_CLASS ThreadInformationClass, IN PVOID ThreadInformation, IN ULONG ThreadInformationLength);
typedef NTSTATUS  (NTAPI *ZW_QUERY_INFORMATION_PROCESS)(IN HANDLE ProcessHandle, IN PROCESS_INFO_CLASS ProcessInformationClass, OUT PVOID ProcessInformation, IN ULONG ProcessInformationLength, OUT PULONG ReturnLength);

void main( )
{
    HMODULE hModule = GetModuleHandle("ntdll.dll");
    if (hModule == NULL)
    {
        cout << "Failed: GetModuleHandle" << endl;
        cout << "This prog needs WinNT/2K/XP to run." << endl;
        return;
    }

    //------------------------------------------------------------------------------------
    ZW_QUERY_SYSTEM_INFORMATION ZwQuerySystemInformation;
    ZwQuerySystemInformation = (ZW_QUERY_SYSTEM_INFORMATION)GetProcAddress(hModule, "ZwQuerySystemInformation");
    if (ZwQuerySystemInformation == NULL)
    {
        cout << "Failed: GetProcAddress ZwQuerySystemInformation" << endl;
        return;
    }

    SYSTEM_KERNEL_DEBUGGER_INFORMATION Info;
    if (STATUS_SUCCESS == ZwQuerySystemInformation(SystemKernelDebuggerInformation, &Info, sizeof(Info), NULL))
    {
        if (Info.DebuggerEnabled)
        {
            cout << "System debugger enabled" << endl;
            if (Info.DebuggerNotPresent)
                cout << "System debugger not present" << endl;
            else
                cout << "System debugger present" << endl;

        }
        else
            cout << "System debugger disabled" << endl;
    }
    else
    {
        cout << "Failed: ZwQuerySystemInformation" << endl;
    }

    //---------------------------------------------------------------------------------------
    
    ZW_SET_INFORMATION_THREAD ZwSetInformationThread;
    ZwSetInformationThread = (ZW_SET_INFORMATION_THREAD)GetProcAddress(hModule, "ZwSetInformationThread");
    if (ZwSetInformationThread == NULL)
    {
        cout << "Failed: GetProcAddress ZwSetInformationThread" << endl;
        return;
    }

    if (STATUS_SUCCESS != ZwSetInformationThread(GetCurrentThread( ), ThreadHideFromDebugger, NULL, 0))
        cout << "Failed: ZwSetInformationThread" << endl;
    
    //---------------------------------------------------------------------------------------
    ZW_QUERY_INFORMATION_PROCESS ZwQueryInformationProcess;
    ZwQueryInformationProcess = (ZW_QUERY_INFORMATION_PROCESS)GetProcAddress(hModule, "ZwQueryInformationProcess");
    if (ZwQueryInformationProcess == NULL)
    {
        cout << "Failed: GetProcAddress ZwQueryInformationprocess" << endl;
        return;
    }

    PROCESS_DEBUG_PORT_INFO ProcessInfo;
    if (STATUS_SUCCESS != ZwQueryInformationProcess(GetCurrentProcess( ), ProcessDebugPort, &ProcessInfo, sizeof(ProcessInfo), NULL))
        cout << "Failed: ZwQueryInformationProcess" << endl;
    else
    {
        if (ProcessInfo.DebugPort)
            cout << "Process debugger present" << endl;
        else
            cout << "Process debugger not present" << endl;
    }

}