元始天尊 发表于 2015-7-12 15:33:07

多调试器调试模型

我的想法很简单,就是让多个调试器附加调试同一个进程!!!
然而为了实现这一点,设计了2页纸的消息传递模型!!!

struct SlaveDebuggerInfo
{
        std::deque<DBGUI_WAIT_STATE_CHANGE> singlemsgs;
        char szEvent;//用于DebugContinue回调
        HANDLE hWaitForDebugEvent;//等待主调试器得到Wait的事件
        HANDLE hDebugContinueEvent;//等待从调试器DebugContinue事件
};

std::map<DWORD,SlaveDebuggerInfo> msgs;//共享消息
CRITICAL_SECTION mlock;

void CEasyDbgDlg::OnAttach()
{
        if (m_isDebuging==TRUE)
        {
                AfxMessageBox("调试器正在调试中!不能在调试另一个程序");
                return;
        }
        ProcessEnum pe;
        if(IDOK != pe.DoModal())
                return;

        if(pe.selid < 0)
        {
                AfxMessageBox("未能附加程序");
                return;       
        }
        m_DebuggeeProcId = pe.selid;

        m_isDebuging=TRUE;
        m_DebugType = 2;
        EnterCriticalSection(&mlock);
        msgs.clear();
        LeaveCriticalSection(&mlock);
        CreateThread(NULL,0,DebugThreadProc,this,NULL,NULL);
}

// extern DWORD monid;//主调试器正在调试进程的id
// extern REQUEST_DATA data;
void HandleSlaveDebugger(LPVOID lpParameter)
{//处理从调试器发送的消息
        CEasyDbgDlg* pDebug=(CEasyDbgDlg*)lpParameter;
        while(pDebug->StopMsg)
        {
                WaitForSingleObject(pDebug->hReadLock,INFINITE);

                EnterCriticalSection(&mlock);
                switch(data.type)
                {
                case NtDebugActiveProcess:
                        //将主调试器Fake调试信息复制到自己的消息队列
                        {
                                std::deque<DBGUI_WAIT_STATE_CHANGE>& mainmsg = msgs.singlemsgs;//获得主调试器消息队列
                                std::deque<DBGUI_WAIT_STATE_CHANGE>& slavemsg = msgs.singlemsgs;
                                std::deque<DBGUI_WAIT_STATE_CHANGE>::iterator itor = mainmsg.begin();
                                while(itor != mainmsg.end())
                                {
                                        switch((*itor).NewState)
                                        {
                                        case DbgCreateThreadStateChange:
                                        case DbgCreateProcessStateChange:
                                        case DbgExitThreadStateChange:
                                        case DbgLoadDllStateChange:
                                        case DbgUnloadDllStateChange:
                                                slavemsg.push_back((*itor));
                                                break;
                                        case DbgExitProcessStateChange:
                                                //摘掉从调试器
                                                SetEvent(msgs.hWaitForDebugEvent);
                                                SetEvent(msgs.hDebugContinueEvent);
                                                CloseHandle(msgs.hWaitForDebugEvent);
                                                CloseHandle(msgs.hDebugContinueEvent);
                                                msgs.erase(data.dwDebuggerId);
                                        }
                                        ++itor;
                                }
                                msgs.hWaitForDebugEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//初始化Wait事件
                                msgs.hDebugContinueEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//初始化Wait事件
                                HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
                                if(hszEvent)
                                {
                                        SetEvent(hszEvent);
                                        CloseHandle(hszEvent);
                                }
                        }
                        break;
                case NtDebugContinue://主调试器等待所有从调试器NtDebugContinue信号到达之后才进行下个循环
                        SetEvent(msgs.hDebugContinueEvent);//通知主调试器该从调试器已准备DebugContinue
                        memcpy(msgs.szEvent,data.szEvent,0x100);
                        //不能直接在这里等待主调试器DebugContinue,否则造成死锁
                case NtRemoveProcessDebug:
                        //摘掉从调试器
                        SetEvent(msgs.hWaitForDebugEvent);
                        SetEvent(msgs.hDebugContinueEvent);
                        CloseHandle(msgs.hWaitForDebugEvent);
                        CloseHandle(msgs.hDebugContinueEvent);
                        msgs.erase(data.dwDebuggerId);
                        HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
                        if(hszEvent)
                        {
                                SetEvent(hszEvent);
                                CloseHandle(hszEvent);
                        }
                        break;
                case NtSetInformationDebugObject:
                        {
                                BYTE* buf = new BYTE;
                                HANDLE hProc = OpenProcess(PROCESS_VM_READ,FALSE,data.dwDebuggerId);
                                if(buf && hProc)
                                {
                                        DWORD readnum;
                                        ReadProcessMemory(hProc,data.InOut.NtSetInformationDebugObject.DebugInformation,buf,data.InOut.NtSetInformationDebugObject.DebugInformationLength,&readnum);
                                        NtSetInformationDebugObject(NtCurrentTeb()->DbgSsReserved,data.InOut.NtSetInformationDebugObject.DebugObjectInformationClass,
                                                buf,data.InOut.NtSetInformationDebugObject.DebugInformationLength,&data.InOut.NtSetInformationDebugObject.ReturnLength);
                                }
                                if(hProc)
                                        CloseHandle(hProc);
                                if(buf)
                                        delete []buf;
                                HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
                                if(hszEvent)
                                {
                                        SetEvent(hszEvent);
                                        CloseHandle(hszEvent);
                                }
                        }
                        break;
                case NtWaitForDebugEvent:
                        {
                                //从调试事件中获取队首元素,若调试事件队列为空,需加入等待逻辑,在主调试器接收到调试事件后设置事件通知从调试器
                                if(msgs.singlemsgs.empty())
                                {
                                        WaitForSingleObject(msgs.hWaitForDebugEvent,INFINITE);//等待主调试器WaitForDebugEvent事件
                                }
                                HANDLE hProc = OpenProcess(PROCESS_VM_READ,FALSE,data.dwDebuggerId);
                                if(hProc)
                                {
                                        DWORD readnum;
                                        WriteProcessMemory(hProc,data.InOut.NtWaitForDebugEvent.WaitStateChange,(LPVOID)&msgs.singlemsgs.front(),sizeof(DBGUI_WAIT_STATE_CHANGE),&readnum);
                                        msgs.singlemsgs.pop_front();
                                }
                                HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
                                if(hszEvent)
                                {
                                        SetEvent(hszEvent);
                                        CloseHandle(hszEvent);
                                }
                        }
                        break;
                }
                LeaveCriticalSection(&mlock);
        }
};

NTSTATUS WINAPI HOOK_NtWaitForDebugEvent( IN HANDLE DebugObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL,
        OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange)
{
        NTSTATUS status = NtWaitForDebugEvent(DebugObjectHandle, Alertable, Timeout, WaitStateChange);
        if(NT_SUCCESS(status))
        {
                EnterCriticalSection(&mlock);
                std::map<DWORD,std::deque<DBGUI_WAIT_STATE_CHANGE>>::iterator itor = msgs.begin();
                while(itor != msgs.end())
                {
                        (*itor).second.push_back(*WaitStateChange);
                        ++itor;
                }
                LeaveCriticalSection(&mlock);
        }
}

//调试线程函数
DWORD WINAPI DebugThreadProc(LPVOID lpParameter)
{
        CEasyDbgDlg* pDebug=(CEasyDbgDlg*)lpParameter;
        if(pDebug->m_DebugType == 1)
        {
                STARTUPINFO si={0};
                //要初始化此成员
                si.cb = sizeof(si);
                PROCESS_INFORMATION pi={0};
                char szFilePath={0};
   
                //要用工作线程 创建调试进程
                if (!CreateProcess(pDebug->m_SzFilePath,NULL,NULL,NULL,FALSE,DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi))
                {
                        OutputDebugString("EasyDbgDlg.cpp中第337行代码出错");
                        DWORD dwErrorCode=0;
                        dwErrorCode=GetLastError();
                        //获得出错信息并输出
                        pDebug->GetErrorMessage(dwErrorCode);
                        return FALSE;
                }
        }
        else if(pDebug->m_DebugType == 2)
        {
                if(!DebugActiveProcess(pDebug->m_DebuggeeProcId))
                        return FALSE;
        }
   
    BOOL isExit=FALSE;//被调试进程是否退出的标志
    //调试事件
    DEBUG_EVENT de={0};
    //作为系统第一次断点的标志
    BOOL bFirstBp=FALSE;
    //标志 被调试线程以怎样的方式恢复
    DWORDdwContinueStatus=DBG_CONTINUE;
    //调试循环
        while (!isExit&&WaitForDebugEvent(&de,INFINITE))//如果不加上isExit则被调试进程退出时,调试器还会一直等待它
        {
                EnterCriticalSection(&mlock);
                std::map<DWORD,SlaveDebuggerInfo>::iterator itor = msgs.begin();
                while(itor != msgs.end())
                {//给每个从调试器发送Wait事件
                        SetEvent(msgs[(*itor).first].hWaitForDebugEvent);
                        ++itor;
                }
                LeaveCriticalSection(&mlock);

                switch (de.dwDebugEventCode)
                {
                case EXCEPTION_DEBUG_EVENT:
                        switch (de.u.Exception.ExceptionRecord.ExceptionCode)
                        {
                        case EXCEPTION_ACCESS_VIOLATION:
                                {
                                        DWORD dwAccessAddress=0;
                                        //异常访问的地址
                                        dwAccessAddress=de.u.Exception.ExceptionRecord.ExceptionInformation;
                                        dwContinueStatus=pDebug->ON_EXCEPTION_ACCESS_VIOLATION((DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress,dwAccessAddress);
                                        break;
                                }
                        case EXCEPTION_BREAKPOINT:
                                if (bFirstBp)
                                {
                                        dwContinueStatus = pDebug->ON_EXCEPTION_BREAKPOINT((DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress);
                                }
                                else
                                {
                                        //处理系统第一次断点
                                        bFirstBp=TRUE;
                                }
                                break;
                        case EXCEPTION_SINGLE_STEP:
                                dwContinueStatus = pDebug->ON_EXCEPTION_SINGLE_STEP((DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress);
                                break;
                        }
                        break;
                case CREATE_THREAD_DEBUG_EVENT:
                        //主线程创建不会有此事件
                        // AfxMessageBox("线程创建");
                        break;
                case CREATE_PROCESS_DEBUG_EVENT:
                        //主线程创建
                        //AfxMessageBox("进程创建");
                        dwContinueStatus=pDebug->ON_CREATE_PROCESS_DEBUG_EVENT(de.dwProcessId,de.dwThreadId,de.u.CreateProcessInfo.lpStartAddress);
                        break;
                case EXIT_THREAD_DEBUG_EVENT:
                        //主线程退出不会产生此事件
                        //AfxMessageBox("线程退出");
                        break;
                case EXIT_PROCESS_DEBUG_EVENT:
                        //主线程退出
                        //AfxMessageBox("进程退出");
                        isExit=TRUE;
                        AfxMessageBox("被调试进程退出");
                        break;
                case LOAD_DLL_DEBUG_EVENT:
                        pDebug->ON_LOAD_DLL_DEBUG_EVENT(de.u.LoadDll.hFile,de.u.LoadDll.lpBaseOfDll);
                        break;
                case UNLOAD_DLL_DEBUG_EVENT:
                        break;
                case OUTPUT_DEBUG_STRING_EVENT:
                        break;
                }

                //等待所有从调试器DebugContinue事件
                itor = msgs.begin();
                while(itor != msgs.end())
                {
                        if((*itor).first != pDebug->m_MasterProcId)
                        {
                                WaitForSingleObject(msgs[(*itor).first].hDebugContinueEvent,INFINITE);
                        }
                        ++itor;
                }

                BOOL ret = ContinueDebugEvent(de.dwProcessId,de.dwThreadId,dwContinueStatus );

                //执行回调:对每个从调试器恢复被调试线程的运行
                itor = msgs.begin();
                while(itor != msgs.end())
                {
                        if((*itor).first != pDebug->m_MasterProcId)
                        {
                                HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, msgs[(*itor).first].szEvent);//通知从调试器处理完毕
                                if(hszEvent)
                                {
                                        SetEvent(hszEvent);
                                        CloseHandle(hszEvent);
                                }
                        }
                        ++itor;
                }

                break;

                if (!ret)
                {
                        OutputDebugString("EasyDbgDlg.cpp 442行出错");
                        DWORD dwErrorCode=0;
                        dwErrorCode=GetLastError();
                        pDebug->GetErrorMessage(dwErrorCode);
                        return DBG_EXCEPTION_NOT_HANDLED ;
                }

                //重置此标志
                dwContinueStatus=DBG_CONTINUE;

      
        }
   
    return 0;
}



// hook.cpp : 定义 DLL 应用程序的导出函数。
//

#include "stdafx.h"


#include <windows.h>
#include <queue>
#include "detours.h"
#include "common.h"
using namespace std;
#pragma comment(lib,"detours.lib")

#pragma data_seg("Shared")
__declspec(dllexport) DWORD monid=0;//主调试器正在调试进程的id
__declspec(dllexport) REQUEST_DATA data={0};
#pragma data_seg()
#pragma comment(linker,"/Section:Shared,RWS")

BOOL FakeDebug = FALSE;
HANDLE hReadLock,hWriteLock;

#if defined(UNICODE) || defined(_UNICODE)
#define _T(X) L##X
#else
#define _T(X)
#endif

// extern "C"
// {
//         BOOL WINAPI CheckRemoteDebuggerPresent( __in HANDLE hProcess, __out PBOOL pbDebuggerPresent );
// };
#define G(X) GetProcAddress(GetModuleHandle(_T("ntdll.dll")),X)
// static FARPROC OLD_NtDebugActiveProcess = G("NtDebugActiveProcess") ;
// static FARPROC OLD_NtDebugContinue = G("NtDebugContinue");
// static FARPROC OLD_NtRemoveProcessDebug = G("NtRemoveProcessDebug");
// static FARPROC OLD_NtSetInformationDebugObject = G("NtSetInformationDebugObject");
// //static FARPROC OLD_NtSystemDebugControl = G("NtSystemDebugControl");
// static FARPROC OLD_NtWaitForDebugEvent = G("NtWaitForDebugEvent");
// static FARPROC OLD_CheckRemoteDebuggerPresent = GetProcAddress(GetModuleHandle(_T("Kernel32.dll")),"CheckRemoteDebuggerPresent");

NTSTATUS WINAPI NEW_NtDebugActiveProcess( IN HANDLE ProcessHandle, IN HANDLE DebugObjectHandle );
NTSTATUS WINAPI NEW_NtDebugContinue( IN HANDLE DebugObjectHandle, IN PCLIENT_ID pClientId, IN NTSTATUS ContinueStatus );
NTSTATUS WINAPI NEW_NtRemoveProcessDebug( IN HANDLE ProcessHandle, IN HANDLE DebugObjectHandle);
NTSTATUS WINAPI NEW_NtSetInformationDebugObject( IN HANDLE DebugObjectHandle, IN ULONG DebugObjectInformationClass,
        IN PVOID DebugInformation, IN ULONG DebugInformationLength, OUT PULONG ReturnLength OPTIONAL );
NTSTATUS WINAPI NEW_NtWaitForDebugEvent( IN HANDLE DebugObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL,
        OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange);
BOOL WINAPI NEW_CheckRemoteDebuggerPresent( IN HANDLE hProcess, OUT PBOOL pbDebuggerPresent );

FARPROC OLD_FUNCS =
{
        G("NtDebugActiveProcess"),
        G("NtDebugContinue"),
        G("NtRemoveProcessDebug"),
        G("NtSetInformationDebugObject"),
        G("NtWaitForDebugEvent"),
        GetProcAddress(GetModuleHandle(_T("Kernel32.dll")),"CheckRemoteDebuggerPresent"),
};

FARPROC NEW_FUNCS =
{
        (FARPROC)NEW_NtDebugActiveProcess,
        (FARPROC)NEW_NtDebugContinue,
        (FARPROC)NEW_NtRemoveProcessDebug,
        (FARPROC)NEW_NtSetInformationDebugObject,
        (FARPROC)NEW_NtWaitForDebugEvent,
        (FARPROC)NEW_CheckRemoteDebuggerPresent,
};

NTSTATUS WINAPI NEW_NtDebugActiveProcess( IN HANDLE ProcessHandle, IN HANDLE DebugObjectHandle )
{
/*        ProcessHandle   - Handle to a process to be debugged
        DebugObjectHandle - Handle to a debug object
*/
        DWORD dwProcessId = GetProcessId(ProcessHandle);
        if(monid == dwProcessId)
        {
                HANDLE hEvent;
                WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
                memset(&data,0,sizeof(data));
                FakeDebug = TRUE;
                data.type = NtDebugActiveProcess;
                data.dwDebuggerId = GetCurrentProcessId();
                data.InOut.NtDebugActiveProcess.dwDebuggeeId = dwProcessId;
                sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
                hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
                if(hEvent)
                {
                        SetEvent(hReadLock);//通知主调试器
                        WaitForSingleObject(hEvent,INFINITE);
                        CloseHandle(hEvent);
                }
                SetEvent(hWriteLock);//释放写锁
                return STATUS_SUCCESS;//支持多调试器共同调试
        }
        else
        {
                return ((NTSTATUS (WINAPI*)(HANDLE,HANDLE))OLD_FUNCS)(ProcessHandle, DebugObjectHandle);
        }
}

NTSTATUS WINAPI NEW_NtDebugContinue( IN HANDLE DebugObjectHandle, IN PCLIENT_ID pClientId, IN NTSTATUS ContinueStatus )
{
/*        DebugObjectHandle - Handle to a debug object
        ClientId - ClientId of thread to continue
        ContinueStatus - Status of continue
*/
        DWORD dwProcessId = (DWORD)pClientId->UniqueProcess;
        if(monid == dwProcessId)
        {
                HANDLE hEvent;
                WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
                memset(&data,0,sizeof(data));
                FakeDebug = TRUE;
                data.type = NtDebugContinue;
                data.dwDebuggerId = GetCurrentProcessId();
                data.InOut.NtDebugContinue.ClientId = *pClientId;
                data.InOut.NtDebugContinue.ContinueStatus = ContinueStatus;
                sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
                hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
                if(hEvent)
                {
                        SetEvent(hReadLock);//通知主调试器
                        WaitForSingleObject(hEvent,INFINITE);
                        CloseHandle(hEvent);
                }
                SetEvent(hWriteLock);//释放写锁
                return STATUS_SUCCESS;//支持多调试器共同调试
        }
        else
        {
                return ((NTSTATUS (WINAPI*)(HANDLE,PCLIENT_ID,NTSTATUS))OLD_FUNCS)(DebugObjectHandle, pClientId, ContinueStatus);
        }
}

NTSTATUS WINAPI NEW_NtRemoveProcessDebug( IN HANDLE ProcessHandle, IN HANDLE DebugObjectHandle)
{
/*        ProcessHandle   - Handle to a process to be debugged
        DebugObjectHandle - Handle to a debug object
*/
        DWORD dwProcessId = GetProcessId(ProcessHandle);
        if(monid == dwProcessId)
        {
                HANDLE hEvent;
                WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
                memset(&data,0,sizeof(data));
                FakeDebug = FALSE;
                data.type = NtRemoveProcessDebug;
                data.dwDebuggerId = GetCurrentProcessId();
                sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
                hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
                if(hEvent)
                {
                        SetEvent(hReadLock);//通知主调试器
                        WaitForSingleObject(hEvent,INFINITE);
                        CloseHandle(hEvent);
                }
                SetEvent(hWriteLock);//释放写锁
                return STATUS_SUCCESS;//支持多调试器共同调试
        }
        else
        {
                return ((NTSTATUS (WINAPI*)(HANDLE,HANDLE))OLD_FUNCS)(ProcessHandle, DebugObjectHandle);
        }
}

NTSTATUS WINAPI NEW_NtSetInformationDebugObject( IN HANDLE DebugObjectHandle, IN ULONG DebugObjectInformationClass,
        IN PVOID DebugInformation, IN ULONG DebugInformationLength, OUT PULONG ReturnLength OPTIONAL )
{
/*        ProcessHandle - Supplies a handle to a process object.
        ProcessInformationClass - Supplies the class of information being set.
        ProcessInformation - Supplies a pointer to a record that contains the information to set.
        ProcessInformationLength - Supplies the length of the record that contains the information to set.
*/
        if(FakeDebug)
        {
                        HANDLE hEvent;
                        WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
                        memset(&data,0,sizeof(data));
                        data.type = NtSetInformationDebugObject;
                        data.InOut.NtSetInformationDebugObject.DebugObjectInformationClass = DebugObjectInformationClass;
                        data.InOut.NtSetInformationDebugObject.DebugInformation = DebugInformation;
                        data.InOut.NtSetInformationDebugObject.DebugInformationLength = DebugInformationLength;
                        data.dwDebuggerId = GetCurrentProcessId();
                        sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
                        hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
                        if(hEvent)
                        {
                                SetEvent(hReadLock);//通知主调试器
                                WaitForSingleObject(hEvent,INFINITE);
                                CloseHandle(hEvent);
                        }
                        *ReturnLength = data.InOut.NtSetInformationDebugObject.ReturnLength;
                        SetEvent(hWriteLock);//释放写锁
                return STATUS_SUCCESS;//支持多调试器共同调试
        }
        else
        {
                return ((NTSTATUS (WINAPI*)(HANDLE,ULONG,PVOID,ULONG,PULONG))OLD_FUNCS)
                        (DebugObjectHandle, DebugObjectInformationClass, DebugInformation, DebugInformationLength, ReturnLength);
        }
}

NTSTATUS WINAPI NEW_NtWaitForDebugEvent( IN HANDLE DebugObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL,
        OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange)
{
/*        DebugObjectHandle - Handle to a debug object
        Alertable - TRUE is the wait is to be alertable
        Timeout - Operation timeout value
        WaitStateChange - Returned debug event
*/
        if(FakeDebug)
        {
                HANDLE hEvent;
                WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
                memset(&data,0,sizeof(data));
                data.type = NtWaitForDebugEvent;
                data.InOut.NtWaitForDebugEvent.Alertable = Alertable;
                data.InOut.NtWaitForDebugEvent.Timeout = *Timeout;
                data.InOut.NtWaitForDebugEvent.WaitStateChange = WaitStateChange;
                data.dwDebuggerId = GetCurrentProcessId();
                sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
                hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
                if(hEvent)
                {
                        SetEvent(hReadLock);//通知主调试器
                        WaitForSingleObject(hEvent,INFINITE);
                        CloseHandle(hEvent);
                        if(WaitStateChange->NewState == DbgExitProcessStateChange)
                                FakeDebug = FALSE;
                }
                SetEvent(hWriteLock);//释放写锁
                return STATUS_SUCCESS;//支持多调试器共同调试
        }
        else
        {
                return ((NTSTATUS (WINAPI*)(HANDLE,BOOLEAN,PLARGE_INTEGER,PDBGUI_WAIT_STATE_CHANGE))OLD_FUNCS)
                        (DebugObjectHandle, Alertable, Timeout, WaitStateChange);
        }
}

BOOL WINAPI NEW_CheckRemoteDebuggerPresent( IN HANDLE hProcess, OUT PBOOL pbDebuggerPresent )
{
        DWORD dwProcessId = GetProcessId(hProcess);
        if(monid == dwProcessId)
        {
                *pbDebuggerPresent = FALSE;

                return TRUE;
        }
        else
        {
                return ((BOOL (WINAPI*)(HANDLE,PBOOL))OLD_FUNCS)(hProcess, pbDebuggerPresent);
        }
}

extern "C" __declspec(dllexport) void Hook()
{
        DetourRestoreAfterWith();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        for(int i = 0 ;i < HookMax; i++)
        {
                DetourAttach(&(PVOID&)OLD_FUNCS,NEW_FUNCS);
        }
        DetourTransactionCommit();
}

extern "C" __declspec(dllexport) void UnHook()
{
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        for(int i = 0 ;i < HookMax; i++)
        {
                DetourAttach(&(PVOID&)OLD_FUNCS,NEW_FUNCS);
        }
        DetourTransactionCommit();
}

extern "C" __declspec(dllexport) void SetExternHook(int FuncId, FARPROC FuncAddr)
{
        if(FuncId < 0 || FuncId >= HookMax || !FuncAddr)
                return;
        DetourRestoreAfterWith();
        DetourTransactionBegin();
        DetourUpdateThread(GetCurrentThread());
        NEW_FUNCS = FuncAddr;
        DetourAttach(&(PVOID&)OLD_FUNCS,NEW_FUNCS);
        DetourTransactionCommit();
}

BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved )
{
        switch( fdwReason )
        {
        case DLL_PROCESS_ATTACH:
                hReadLock = OpenEventA(EVENT_MODIFY_STATE, FALSE, "MultiDebugRead");
                hWriteLock = OpenEventA(EVENT_MODIFY_STATE, FALSE, "MultiDebugWrite");
                if(!hReadLock || !hWriteLock)
                        exit(0);
                Hook();
                break;
        case DLL_THREAD_ATTACH:
                break;
        case DLL_THREAD_DETACH:
                break;
        case DLL_PROCESS_DETACH:
                UnHook();
                CloseHandle(hReadLock);
                CloseHandle(hWriteLock);
                break;
        }
        return TRUE;
}


#define STATUS_SUCCESS                        ((NTSTATUS)0x00000000L)

typedef LONG NTSTATUS;

typedef struct _CLIENT_ID
{
        HANDLE UniqueProcess;
        HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef enum _DBG_STATE
{
        DbgIdle,
        DbgReplyPending,
        DbgCreateThreadStateChange,
        DbgCreateProcessStateChange,
        DbgExitThreadStateChange,
        DbgExitProcessStateChange,
        DbgExceptionStateChange,
        DbgBreakpointStateChange,
        DbgSingleStepStateChange,
        DbgLoadDllStateChange,
        DbgUnloadDllStateChange
} DBG_STATE, *PDBG_STATE;

typedef struct _DBGKM_EXCEPTION
{
        EXCEPTION_RECORD ExceptionRecord;
        ULONG FirstChance;
} DBGKM_EXCEPTION, *PDBGKM_EXCEPTION;

typedef struct _DBGKM_CREATE_THREAD
{
        ULONG SubSystemKey;
        PVOID StartAddress;
} DBGKM_CREATE_THREAD, *PDBGKM_CREATE_THREAD;

typedef struct _DBGKM_CREATE_PROCESS
{
        ULONG SubSystemKey;
        HANDLE FileHandle;
        PVOID BaseOfImage;
        ULONG DebugInfoFileOffset;
        ULONG DebugInfoSize;
        DBGKM_CREATE_THREAD InitialThread;
} DBGKM_CREATE_PROCESS, *PDBGKM_CREATE_PROCESS;

typedef struct _DBGUI_CREATE_THREAD
{
        HANDLE HandleToThread;
        DBGKM_CREATE_THREAD NewThread;
} DBGUI_CREATE_THREAD, *PDBGUI_CREATE_THREAD;

typedef struct _DBGUI_CREATE_PROCESS
{
        HANDLE HandleToProcess;
        HANDLE HandleToThread;
        DBGKM_CREATE_PROCESS NewProcess;
} DBGUI_CREATE_PROCESS, *PDBGUI_CREATE_PROCESS;

typedef struct _DBGKM_EXIT_THREAD
{
        NTSTATUS ExitStatus;
} DBGKM_EXIT_THREAD, *PDBGKM_EXIT_THREAD;

typedef struct _DBGKM_EXIT_PROCESS
{
        NTSTATUS ExitStatus;
} DBGKM_EXIT_PROCESS, *PDBGKM_EXIT_PROCESS;

typedef struct _DBGKM_LOAD_DLL
{
        HANDLE FileHandle;
        PVOID BaseOfDll;
        ULONG DebugInfoFileOffset;
        ULONG DebugInfoSize;
        PVOID NamePointer;
} DBGKM_LOAD_DLL, *PDBGKM_LOAD_DLL;

typedef struct _DBGKM_UNLOAD_DLL
{
        PVOID BaseAddress;
} DBGKM_UNLOAD_DLL, *PDBGKM_UNLOAD_DLL;

typedef struct _DBGUI_WAIT_STATE_CHANGE
{
        DBG_STATE NewState;
        CLIENT_ID AppClientId;
        union
        {
                DBGKM_EXCEPTION Exception;
                DBGUI_CREATE_THREAD CreateThread;
                DBGUI_CREATE_PROCESS CreateProcessInfo;
                DBGKM_EXIT_THREAD ExitThread;
                DBGKM_EXIT_PROCESS ExitProcess;
                DBGKM_LOAD_DLL LoadDll;
                DBGKM_UNLOAD_DLL UnloadDll;
        } StateInfo;
} DBGUI_WAIT_STATE_CHANGE, *PDBGUI_WAIT_STATE_CHANGE;

//common.h
typedef struct _REQUEST_DATA//主调试器初始化
{
        int type;
        char szEvent;//用于等待主调试器处理结果
        DWORD dwDebuggerId;
        union
        {
                struct
                {
                        DWORD dwDebuggeeId;
                }NtDebugActiveProcess;

                struct
                {
                        CLIENT_ID ClientId;
                        NTSTATUS ContinueStatus;
                }NtDebugContinue;

                struct
                {
                }NtRemoveProcessDebug;

                struct
                {
                        ULONG DebugObjectInformationClass;
                        PVOID DebugInformation;//主调试器ReadProcessMemory
                        ULONG DebugInformationLength;
                        ULONG ReturnLength;//返回长度
                }NtSetInformationDebugObject;

                struct
                {
                        BOOLEAN Alertable;
                        LARGE_INTEGER Timeout;
                        PDBGUI_WAIT_STATE_CHANGE WaitStateChange;//主调试器WriteProcessMemory
                }NtWaitForDebugEvent;
        }InOut;
} REQUEST_DATA, *PREQUEST_DATA;

enum
{
        NtDebugActiveProcess,
        NtDebugContinue,
        NtRemoveProcessDebug,
        NtSetInformationDebugObject,
        NtWaitForDebugEvent,
        CheckRemoteDebugger,
        HookMax,
};

Golden Blonde 发表于 2015-7-13 00:38:32

能写个C版本吗???

0x01810 发表于 2015-7-13 09:18:02

前排膜拜..
页: [1]
查看完整版本: 多调试器调试模型