多调试器调试模型
我的想法很简单,就是让多个调试器附加调试同一个进程!!!然而为了实现这一点,设计了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,
};
能写个C版本吗??? 前排膜拜..
页:
[1]