找回密码
 立即注册→加入我们

QQ登录

只需一步,快速开始

搜索
热搜: 下载 VB C 实现 编写
查看: 3131|回复: 2

多调试器调试模型

[复制链接]

307

主题

228

回帖

7349

积分

用户组: 真·技术宅

UID
2
精华
76
威望
291 点
宅币
5599 个
贡献
253 次
宅之契约
0 份
在线时间
949 小时
注册时间
2014-1-25
发表于 2015-7-12 15:33:07 | 显示全部楼层 |阅读模式

欢迎访问技术宅的结界,请注册或者登录吧。

您需要 登录 才可以下载或查看,没有账号?立即注册→加入我们

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

  1. struct SlaveDebuggerInfo
  2. {
  3.         std::deque<DBGUI_WAIT_STATE_CHANGE> singlemsgs;
  4.         char szEvent[0x100];//用于DebugContinue回调
  5.         HANDLE hWaitForDebugEvent;//等待主调试器得到Wait的事件
  6.         HANDLE hDebugContinueEvent;//等待从调试器DebugContinue事件
  7. };

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

  10. void CEasyDbgDlg::OnAttach()
  11. {
  12.         if (m_isDebuging==TRUE)
  13.         {
  14.                 AfxMessageBox("调试器正在调试中!不能在调试另一个程序");
  15.                 return;
  16.         }
  17.         ProcessEnum pe;
  18.         if(IDOK != pe.DoModal())
  19.                 return;

  20.         if(pe.selid < 0)
  21.         {
  22.                 AfxMessageBox("未能附加程序");
  23.                 return;       
  24.         }
  25.         m_DebuggeeProcId = pe.selid;

  26.         m_isDebuging=TRUE;
  27.         m_DebugType = 2;
  28.         EnterCriticalSection(&mlock);
  29.         msgs.clear();
  30.         LeaveCriticalSection(&mlock);
  31.         CreateThread(NULL,0,DebugThreadProc,this,NULL,NULL);
  32. }

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

  41.                 EnterCriticalSection(&mlock);
  42.                 switch(data.type)
  43.                 {
  44.                 case NtDebugActiveProcess:
  45.                         //将主调试器Fake调试信息复制到自己的消息队列
  46.                         {
  47.                                 std::deque<DBGUI_WAIT_STATE_CHANGE>& mainmsg = msgs[pDebug->m_MasterProcId].singlemsgs;//获得主调试器消息队列
  48.                                 std::deque<DBGUI_WAIT_STATE_CHANGE>& slavemsg = msgs[data.dwDebuggerId].singlemsgs;
  49.                                 std::deque<DBGUI_WAIT_STATE_CHANGE>::iterator itor = mainmsg.begin();
  50.                                 while(itor != mainmsg.end())
  51.                                 {
  52.                                         switch((*itor).NewState)
  53.                                         {
  54.                                         case DbgCreateThreadStateChange:
  55.                                         case DbgCreateProcessStateChange:
  56.                                         case DbgExitThreadStateChange:
  57.                                         case DbgLoadDllStateChange:
  58.                                         case DbgUnloadDllStateChange:
  59.                                                 slavemsg.push_back((*itor));
  60.                                                 break;
  61.                                         case DbgExitProcessStateChange:
  62.                                                 //摘掉从调试器
  63.                                                 SetEvent(msgs[data.dwDebuggerId].hWaitForDebugEvent);
  64.                                                 SetEvent(msgs[data.dwDebuggerId].hDebugContinueEvent);
  65.                                                 CloseHandle(msgs[data.dwDebuggerId].hWaitForDebugEvent);
  66.                                                 CloseHandle(msgs[data.dwDebuggerId].hDebugContinueEvent);
  67.                                                 msgs.erase(data.dwDebuggerId);
  68.                                         }
  69.                                         ++itor;
  70.                                 }
  71.                                 msgs[data.dwDebuggerId].hWaitForDebugEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//初始化Wait事件
  72.                                 msgs[data.dwDebuggerId].hDebugContinueEvent = CreateEvent(NULL, TRUE, FALSE, NULL);//初始化Wait事件
  73.                                 HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
  74.                                 if(hszEvent)
  75.                                 {
  76.                                         SetEvent(hszEvent);
  77.                                         CloseHandle(hszEvent);
  78.                                 }
  79.                         }
  80.                         break;
  81.                 case NtDebugContinue://主调试器等待所有从调试器NtDebugContinue信号到达之后才进行下个循环
  82.                         SetEvent(msgs[data.dwDebuggerId].hDebugContinueEvent);//通知主调试器该从调试器已准备DebugContinue
  83.                         memcpy(msgs[data.dwDebuggerId].szEvent,data.szEvent,0x100);
  84.                         //不能直接在这里等待主调试器DebugContinue,否则造成死锁
  85.                 case NtRemoveProcessDebug:
  86.                         //摘掉从调试器
  87.                         SetEvent(msgs[data.dwDebuggerId].hWaitForDebugEvent);
  88.                         SetEvent(msgs[data.dwDebuggerId].hDebugContinueEvent);
  89.                         CloseHandle(msgs[data.dwDebuggerId].hWaitForDebugEvent);
  90.                         CloseHandle(msgs[data.dwDebuggerId].hDebugContinueEvent);
  91.                         msgs.erase(data.dwDebuggerId);
  92.                         HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
  93.                         if(hszEvent)
  94.                         {
  95.                                 SetEvent(hszEvent);
  96.                                 CloseHandle(hszEvent);
  97.                         }
  98.                         break;
  99.                 case NtSetInformationDebugObject:
  100.                         {
  101.                                 BYTE* buf = new BYTE[data.InOut.NtSetInformationDebugObject.DebugInformationLength];
  102.                                 HANDLE hProc = OpenProcess(PROCESS_VM_READ,FALSE,data.dwDebuggerId);
  103.                                 if(buf && hProc)
  104.                                 {
  105.                                         DWORD readnum;
  106.                                         ReadProcessMemory(hProc,data.InOut.NtSetInformationDebugObject.DebugInformation,buf,data.InOut.NtSetInformationDebugObject.DebugInformationLength,&readnum);
  107.                                         NtSetInformationDebugObject(NtCurrentTeb()->DbgSsReserved[1],data.InOut.NtSetInformationDebugObject.DebugObjectInformationClass,
  108.                                                 buf,data.InOut.NtSetInformationDebugObject.DebugInformationLength,&data.InOut.NtSetInformationDebugObject.ReturnLength);
  109.                                 }
  110.                                 if(hProc)
  111.                                         CloseHandle(hProc);
  112.                                 if(buf)
  113.                                         delete []buf;
  114.                                 HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
  115.                                 if(hszEvent)
  116.                                 {
  117.                                         SetEvent(hszEvent);
  118.                                         CloseHandle(hszEvent);
  119.                                 }
  120.                         }
  121.                         break;
  122.                 case NtWaitForDebugEvent:
  123.                         {
  124.                                 //从调试事件中获取队首元素,若调试事件队列为空,需加入等待逻辑,在主调试器接收到调试事件后设置事件通知从调试器
  125.                                 if(msgs[data.dwDebuggerId].singlemsgs.empty())
  126.                                 {
  127.                                         WaitForSingleObject(msgs[data.dwDebuggerId].hWaitForDebugEvent,INFINITE);//等待主调试器WaitForDebugEvent事件
  128.                                 }
  129.                                 HANDLE hProc = OpenProcess(PROCESS_VM_READ,FALSE,data.dwDebuggerId);
  130.                                 if(hProc)
  131.                                 {
  132.                                         DWORD readnum;
  133.                                         WriteProcessMemory(hProc,data.InOut.NtWaitForDebugEvent.WaitStateChange,(LPVOID)&msgs[data.dwDebuggerId].singlemsgs.front(),sizeof(DBGUI_WAIT_STATE_CHANGE),&readnum);
  134.                                         msgs[data.dwDebuggerId].singlemsgs.pop_front();
  135.                                 }
  136.                                 HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, data.szEvent);//通知从调试器处理完毕
  137.                                 if(hszEvent)
  138.                                 {
  139.                                         SetEvent(hszEvent);
  140.                                         CloseHandle(hszEvent);
  141.                                 }
  142.                         }
  143.                         break;
  144.                 }
  145.                 LeaveCriticalSection(&mlock);
  146.         }
  147. };

  148. NTSTATUS WINAPI HOOK_NtWaitForDebugEvent( IN HANDLE DebugObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL,
  149.         OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange)
  150. {
  151.         NTSTATUS status = NtWaitForDebugEvent(DebugObjectHandle, Alertable, Timeout, WaitStateChange);
  152.         if(NT_SUCCESS(status))
  153.         {
  154.                 EnterCriticalSection(&mlock);
  155.                 std::map<DWORD,std::deque<DBGUI_WAIT_STATE_CHANGE>>::iterator itor = msgs.begin();
  156.                 while(itor != msgs.end())
  157.                 {
  158.                         (*itor).second.push_back(*WaitStateChange);
  159.                         ++itor;
  160.                 }
  161.                 LeaveCriticalSection(&mlock);
  162.         }
  163. }

  164. //调试线程函数
  165. DWORD WINAPI DebugThreadProc(LPVOID lpParameter)
  166. {
  167.         CEasyDbgDlg* pDebug=(CEasyDbgDlg*)lpParameter;
  168.         if(pDebug->m_DebugType == 1)
  169.         {
  170.                 STARTUPINFO si={0};
  171.                 //要初始化此成员
  172.                 si.cb = sizeof(si);
  173.                 PROCESS_INFORMATION pi={0};
  174.                 char szFilePath[256]={0};
  175.    
  176.                 //要用工作线程 创建调试进程
  177.                 if (!CreateProcess(pDebug->m_SzFilePath,NULL,NULL,NULL,FALSE,DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi))
  178.                 {
  179.                         OutputDebugString("EasyDbgDlg.cpp中第337行代码出错");
  180.                         DWORD dwErrorCode=0;
  181.                         dwErrorCode=GetLastError();
  182.                         //获得出错信息并输出
  183.                         pDebug->GetErrorMessage(dwErrorCode);
  184.                         return FALSE;
  185.                 }
  186.         }
  187.         else if(pDebug->m_DebugType == 2)
  188.         {
  189.                 if(!DebugActiveProcess(pDebug->m_DebuggeeProcId))
  190.                         return FALSE;
  191.         }
  192.    
  193.     BOOL isExit=FALSE;//被调试进程是否退出的标志
  194.     //调试事件
  195.     DEBUG_EVENT de={0};
  196.     //作为系统第一次断点的标志
  197.     BOOL bFirstBp=FALSE;
  198.     //标志 被调试线程以怎样的方式恢复
  199.     DWORD  dwContinueStatus=DBG_CONTINUE;
  200.     //调试循环
  201.         while (!isExit&&WaitForDebugEvent(&de,INFINITE))//如果不加上isExit则被调试进程退出时,调试器还会一直等待它
  202.         {  
  203.                 EnterCriticalSection(&mlock);
  204.                 std::map<DWORD,SlaveDebuggerInfo>::iterator itor = msgs.begin();
  205.                 while(itor != msgs.end())
  206.                 {//给每个从调试器发送Wait事件
  207.                         SetEvent(msgs[(*itor).first].hWaitForDebugEvent);
  208.                         ++itor;
  209.                 }
  210.                 LeaveCriticalSection(&mlock);

  211.                 switch (de.dwDebugEventCode)
  212.                 {
  213.                 case EXCEPTION_DEBUG_EVENT:
  214.                         switch (de.u.Exception.ExceptionRecord.ExceptionCode)
  215.                         {
  216.                         case EXCEPTION_ACCESS_VIOLATION:
  217.                                 {
  218.                                         DWORD dwAccessAddress=0;
  219.                                         //异常访问的地址
  220.                                         dwAccessAddress=de.u.Exception.ExceptionRecord.ExceptionInformation[1];
  221.                                         dwContinueStatus=pDebug->ON_EXCEPTION_ACCESS_VIOLATION((DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress,dwAccessAddress);
  222.                                         break;
  223.                                 }
  224.                         case EXCEPTION_BREAKPOINT:
  225.                                 if (bFirstBp)
  226.                                 {
  227.                                         dwContinueStatus = pDebug->ON_EXCEPTION_BREAKPOINT((DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress);
  228.                                 }
  229.                                 else
  230.                                 {
  231.                                         //处理系统第一次断点
  232.                                         bFirstBp=TRUE;
  233.                                 }
  234.                                 break;
  235.                         case EXCEPTION_SINGLE_STEP:
  236.                                 dwContinueStatus = pDebug->ON_EXCEPTION_SINGLE_STEP((DWORD)de.u.Exception.ExceptionRecord.ExceptionAddress);
  237.                                 break;
  238.                         }
  239.                         break;
  240.                 case CREATE_THREAD_DEBUG_EVENT:
  241.                         //主线程创建不会有此事件
  242.                         // AfxMessageBox("线程创建");
  243.                         break;
  244.                 case CREATE_PROCESS_DEBUG_EVENT:
  245.                         //主线程创建
  246.                         //AfxMessageBox("进程创建");
  247.                         dwContinueStatus=pDebug->ON_CREATE_PROCESS_DEBUG_EVENT(de.dwProcessId,de.dwThreadId,de.u.CreateProcessInfo.lpStartAddress);
  248.                         break;  
  249.                 case EXIT_THREAD_DEBUG_EVENT:
  250.                         //主线程退出不会产生此事件
  251.                         //AfxMessageBox("线程退出");
  252.                         break;
  253.                 case EXIT_PROCESS_DEBUG_EVENT:
  254.                         //主线程退出
  255.                         //AfxMessageBox("进程退出");
  256.                         isExit=TRUE;
  257.                         AfxMessageBox("被调试进程退出");
  258.                         break;
  259.                 case LOAD_DLL_DEBUG_EVENT:
  260.                         pDebug->ON_LOAD_DLL_DEBUG_EVENT(de.u.LoadDll.hFile,de.u.LoadDll.lpBaseOfDll);
  261.                         break;
  262.                 case UNLOAD_DLL_DEBUG_EVENT:
  263.                         break;
  264.                 case OUTPUT_DEBUG_STRING_EVENT:
  265.                         break;
  266.                 }

  267.                 //等待所有从调试器DebugContinue事件
  268.                 itor = msgs.begin();
  269.                 while(itor != msgs.end())
  270.                 {
  271.                         if((*itor).first != pDebug->m_MasterProcId)
  272.                         {
  273.                                 WaitForSingleObject(msgs[(*itor).first].hDebugContinueEvent,INFINITE);
  274.                         }
  275.                         ++itor;
  276.                 }

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

  278.                 //执行回调:对每个从调试器恢复被调试线程的运行
  279.                 itor = msgs.begin();
  280.                 while(itor != msgs.end())
  281.                 {
  282.                         if((*itor).first != pDebug->m_MasterProcId)
  283.                         {
  284.                                 HANDLE hszEvent = OpenEventA(EVENT_MODIFY_STATE, FALSE, msgs[(*itor).first].szEvent);//通知从调试器处理完毕
  285.                                 if(hszEvent)
  286.                                 {
  287.                                         SetEvent(hszEvent);
  288.                                         CloseHandle(hszEvent);
  289.                                 }
  290.                         }
  291.                         ++itor;
  292.                 }

  293.                 break;

  294.                 if (!ret)
  295.                 {
  296.                         OutputDebugString("EasyDbgDlg.cpp 442行出错");
  297.                         DWORD dwErrorCode=0;
  298.                         dwErrorCode=GetLastError();
  299.                         pDebug->GetErrorMessage(dwErrorCode);
  300.                         return DBG_EXCEPTION_NOT_HANDLED ;
  301.                 }

  302.                 //重置此标志
  303.                 dwContinueStatus=DBG_CONTINUE;
  304.   
  305.       
  306.         }
  307.    
  308.     return 0;
  309. }
复制代码


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

  3. #include "stdafx.h"


  4. #include <windows.h>
  5. #include <queue>
  6. #include "detours.h"
  7. #include "common.h"
  8. using namespace std;
  9. #pragma comment(lib,"detours.lib")

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

  15. BOOL FakeDebug = FALSE;
  16. HANDLE hReadLock,hWriteLock;

  17. #if defined(UNICODE) || defined(_UNICODE)
  18. #define _T(X) L##X
  19. #else
  20. #define _T(X)
  21. #endif

  22. // extern "C"
  23. // {
  24. //         BOOL WINAPI CheckRemoteDebuggerPresent( __in HANDLE hProcess, __out PBOOL pbDebuggerPresent );
  25. // };
  26. #define G(X) GetProcAddress(GetModuleHandle(_T("ntdll.dll")),X)
  27. // static FARPROC OLD_NtDebugActiveProcess = G("NtDebugActiveProcess") ;
  28. // static FARPROC OLD_NtDebugContinue = G("NtDebugContinue");
  29. // static FARPROC OLD_NtRemoveProcessDebug = G("NtRemoveProcessDebug");
  30. // static FARPROC OLD_NtSetInformationDebugObject = G("NtSetInformationDebugObject");
  31. // //static FARPROC OLD_NtSystemDebugControl = G("NtSystemDebugControl");
  32. // static FARPROC OLD_NtWaitForDebugEvent = G("NtWaitForDebugEvent");
  33. // static FARPROC OLD_CheckRemoteDebuggerPresent = GetProcAddress(GetModuleHandle(_T("Kernel32.dll")),"CheckRemoteDebuggerPresent");

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

  42. FARPROC OLD_FUNCS[HookMax] =
  43. {
  44.         G("NtDebugActiveProcess"),
  45.         G("NtDebugContinue"),
  46.         G("NtRemoveProcessDebug"),
  47.         G("NtSetInformationDebugObject"),
  48.         G("NtWaitForDebugEvent"),
  49.         GetProcAddress(GetModuleHandle(_T("Kernel32.dll")),"CheckRemoteDebuggerPresent"),
  50. };

  51. FARPROC NEW_FUNCS[HookMax] =
  52. {
  53.         (FARPROC)NEW_NtDebugActiveProcess,
  54.         (FARPROC)NEW_NtDebugContinue,
  55.         (FARPROC)NEW_NtRemoveProcessDebug,
  56.         (FARPROC)NEW_NtSetInformationDebugObject,
  57.         (FARPROC)NEW_NtWaitForDebugEvent,
  58.         (FARPROC)NEW_CheckRemoteDebuggerPresent,
  59. };

  60. NTSTATUS WINAPI NEW_NtDebugActiveProcess( IN HANDLE ProcessHandle, IN HANDLE DebugObjectHandle )
  61. {
  62. /*        ProcessHandle     - Handle to a process to be debugged
  63.         DebugObjectHandle - Handle to a debug object
  64. */
  65.         DWORD dwProcessId = GetProcessId(ProcessHandle);
  66.         if(monid == dwProcessId)
  67.         {
  68.                 HANDLE hEvent;
  69.                 WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
  70.                 memset(&data,0,sizeof(data));
  71.                 FakeDebug = TRUE;
  72.                 data.type = NtDebugActiveProcess;
  73.                 data.dwDebuggerId = GetCurrentProcessId();
  74.                 data.InOut.NtDebugActiveProcess.dwDebuggeeId = dwProcessId;
  75.                 sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
  76.                 hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
  77.                 if(hEvent)
  78.                 {
  79.                         SetEvent(hReadLock);//通知主调试器
  80.                         WaitForSingleObject(hEvent,INFINITE);
  81.                         CloseHandle(hEvent);
  82.                 }
  83.                 SetEvent(hWriteLock);//释放写锁
  84.                 return STATUS_SUCCESS;//支持多调试器共同调试
  85.         }
  86.         else
  87.         {
  88.                 return ((NTSTATUS (WINAPI*)(HANDLE,HANDLE))OLD_FUNCS[NtDebugActiveProcess])(ProcessHandle, DebugObjectHandle);
  89.         }
  90. }

  91. NTSTATUS WINAPI NEW_NtDebugContinue( IN HANDLE DebugObjectHandle, IN PCLIENT_ID pClientId, IN NTSTATUS ContinueStatus )
  92. {
  93. /*        DebugObjectHandle - Handle to a debug object
  94.         ClientId - ClientId of thread to continue
  95.         ContinueStatus - Status of continue
  96. */
  97.         DWORD dwProcessId = (DWORD)pClientId->UniqueProcess;
  98.         if(monid == dwProcessId)
  99.         {
  100.                 HANDLE hEvent;
  101.                 WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
  102.                 memset(&data,0,sizeof(data));
  103.                 FakeDebug = TRUE;
  104.                 data.type = NtDebugContinue;
  105.                 data.dwDebuggerId = GetCurrentProcessId();
  106.                 data.InOut.NtDebugContinue.ClientId = *pClientId;
  107.                 data.InOut.NtDebugContinue.ContinueStatus = ContinueStatus;
  108.                 sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
  109.                 hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
  110.                 if(hEvent)
  111.                 {
  112.                         SetEvent(hReadLock);//通知主调试器
  113.                         WaitForSingleObject(hEvent,INFINITE);
  114.                         CloseHandle(hEvent);
  115.                 }
  116.                 SetEvent(hWriteLock);//释放写锁
  117.                 return STATUS_SUCCESS;//支持多调试器共同调试
  118.         }
  119.         else
  120.         {
  121.                 return ((NTSTATUS (WINAPI*)(HANDLE,PCLIENT_ID,NTSTATUS))OLD_FUNCS[NtDebugContinue])(DebugObjectHandle, pClientId, ContinueStatus);
  122.         }
  123. }

  124. NTSTATUS WINAPI NEW_NtRemoveProcessDebug( IN HANDLE ProcessHandle, IN HANDLE DebugObjectHandle)
  125. {
  126. /*        ProcessHandle     - Handle to a process to be debugged
  127.         DebugObjectHandle - Handle to a debug object
  128. */
  129.         DWORD dwProcessId = GetProcessId(ProcessHandle);
  130.         if(monid == dwProcessId)
  131.         {
  132.                 HANDLE hEvent;
  133.                 WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
  134.                 memset(&data,0,sizeof(data));
  135.                 FakeDebug = FALSE;
  136.                 data.type = NtRemoveProcessDebug;
  137.                 data.dwDebuggerId = GetCurrentProcessId();
  138.                 sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
  139.                 hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
  140.                 if(hEvent)
  141.                 {
  142.                         SetEvent(hReadLock);//通知主调试器
  143.                         WaitForSingleObject(hEvent,INFINITE);
  144.                         CloseHandle(hEvent);
  145.                 }
  146.                 SetEvent(hWriteLock);//释放写锁
  147.                 return STATUS_SUCCESS;//支持多调试器共同调试
  148.         }
  149.         else
  150.         {
  151.                 return ((NTSTATUS (WINAPI*)(HANDLE,HANDLE))OLD_FUNCS[NtRemoveProcessDebug])(ProcessHandle, DebugObjectHandle);
  152.         }
  153. }

  154. NTSTATUS WINAPI NEW_NtSetInformationDebugObject( IN HANDLE DebugObjectHandle, IN ULONG DebugObjectInformationClass,
  155.         IN PVOID DebugInformation, IN ULONG DebugInformationLength, OUT PULONG ReturnLength OPTIONAL )
  156. {
  157. /*        ProcessHandle - Supplies a handle to a process object.
  158.         ProcessInformationClass - Supplies the class of information being set.
  159.         ProcessInformation - Supplies a pointer to a record that contains the information to set.
  160.         ProcessInformationLength - Supplies the length of the record that contains the information to set.
  161. */
  162.         if(FakeDebug)
  163.         {
  164.                         HANDLE hEvent;
  165.                         WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
  166.                         memset(&data,0,sizeof(data));
  167.                         data.type = NtSetInformationDebugObject;
  168.                         data.InOut.NtSetInformationDebugObject.DebugObjectInformationClass = DebugObjectInformationClass;
  169.                         data.InOut.NtSetInformationDebugObject.DebugInformation = DebugInformation;
  170.                         data.InOut.NtSetInformationDebugObject.DebugInformationLength = DebugInformationLength;
  171.                         data.dwDebuggerId = GetCurrentProcessId();
  172.                         sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
  173.                         hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
  174.                         if(hEvent)
  175.                         {
  176.                                 SetEvent(hReadLock);//通知主调试器
  177.                                 WaitForSingleObject(hEvent,INFINITE);
  178.                                 CloseHandle(hEvent);
  179.                         }
  180.                         *ReturnLength = data.InOut.NtSetInformationDebugObject.ReturnLength;
  181.                         SetEvent(hWriteLock);//释放写锁
  182.                 return STATUS_SUCCESS;//支持多调试器共同调试
  183.         }
  184.         else
  185.         {
  186.                 return ((NTSTATUS (WINAPI*)(HANDLE,ULONG,PVOID,ULONG,PULONG))OLD_FUNCS[NtSetInformationDebugObject])
  187.                         (DebugObjectHandle, DebugObjectInformationClass, DebugInformation, DebugInformationLength, ReturnLength);
  188.         }
  189. }

  190. NTSTATUS WINAPI NEW_NtWaitForDebugEvent( IN HANDLE DebugObjectHandle, IN BOOLEAN Alertable, IN PLARGE_INTEGER Timeout OPTIONAL,
  191.         OUT PDBGUI_WAIT_STATE_CHANGE WaitStateChange)
  192. {
  193. /*        DebugObjectHandle - Handle to a debug object
  194.         Alertable - TRUE is the wait is to be alertable
  195.         Timeout - Operation timeout value
  196.         WaitStateChange - Returned debug event
  197. */
  198.         if(FakeDebug)
  199.         {
  200.                 HANDLE hEvent;
  201.                 WaitForSingleObject(hWriteLock, INFINITE);//独占写锁
  202.                 memset(&data,0,sizeof(data));
  203.                 data.type = NtWaitForDebugEvent;
  204.                 data.InOut.NtWaitForDebugEvent.Alertable = Alertable;
  205.                 data.InOut.NtWaitForDebugEvent.Timeout = *Timeout;
  206.                 data.InOut.NtWaitForDebugEvent.WaitStateChange = WaitStateChange;
  207.                 data.dwDebuggerId = GetCurrentProcessId();
  208.                 sprintf_s(data.szEvent,"%d%s%d",GetCurrentProcessId(),__FUNCTION__,GetTickCount());
  209.                 hEvent = CreateEventA(NULL,TRUE,FALSE,data.szEvent);
  210.                 if(hEvent)
  211.                 {
  212.                         SetEvent(hReadLock);//通知主调试器
  213.                         WaitForSingleObject(hEvent,INFINITE);
  214.                         CloseHandle(hEvent);
  215.                         if(WaitStateChange->NewState == DbgExitProcessStateChange)
  216.                                 FakeDebug = FALSE;
  217.                 }
  218.                 SetEvent(hWriteLock);//释放写锁
  219.                 return STATUS_SUCCESS;//支持多调试器共同调试
  220.         }
  221.         else
  222.         {
  223.                 return ((NTSTATUS (WINAPI*)(HANDLE,BOOLEAN,PLARGE_INTEGER,PDBGUI_WAIT_STATE_CHANGE))OLD_FUNCS[NtWaitForDebugEvent])
  224.                         (DebugObjectHandle, Alertable, Timeout, WaitStateChange);
  225.         }
  226. }

  227. BOOL WINAPI NEW_CheckRemoteDebuggerPresent( IN HANDLE hProcess, OUT PBOOL pbDebuggerPresent )
  228. {
  229.         DWORD dwProcessId = GetProcessId(hProcess);
  230.         if(monid == dwProcessId)
  231.         {
  232.                 *pbDebuggerPresent = FALSE;

  233.                 return TRUE;
  234.         }
  235.         else
  236.         {
  237.                 return ((BOOL (WINAPI*)(HANDLE,PBOOL))OLD_FUNCS[CheckRemoteDebugger])(hProcess, pbDebuggerPresent);
  238.         }
  239. }

  240. extern "C" __declspec(dllexport) void Hook()
  241. {
  242.         DetourRestoreAfterWith();
  243.         DetourTransactionBegin();
  244.         DetourUpdateThread(GetCurrentThread());
  245.         for(int i = 0 ;i < HookMax; i++)
  246.         {
  247.                 DetourAttach(&(PVOID&)OLD_FUNCS[i],NEW_FUNCS[i]);
  248.         }
  249.         DetourTransactionCommit();
  250. }

  251. extern "C" __declspec(dllexport) void UnHook()
  252. {
  253.         DetourTransactionBegin();
  254.         DetourUpdateThread(GetCurrentThread());
  255.         for(int i = 0 ;i < HookMax; i++)
  256.         {
  257.                 DetourAttach(&(PVOID&)OLD_FUNCS[i],NEW_FUNCS[i]);
  258.         }
  259.         DetourTransactionCommit();
  260. }

  261. extern "C" __declspec(dllexport) void SetExternHook(int FuncId, FARPROC FuncAddr)
  262. {
  263.         if(FuncId < 0 || FuncId >= HookMax || !FuncAddr)
  264.                 return;
  265.         DetourRestoreAfterWith();
  266.         DetourTransactionBegin();
  267.         DetourUpdateThread(GetCurrentThread());
  268.         NEW_FUNCS[FuncId] = FuncAddr;
  269.         DetourAttach(&(PVOID&)OLD_FUNCS[FuncId],NEW_FUNCS[FuncId]);
  270.         DetourTransactionCommit();
  271. }

  272. BOOL WINAPI DllMain(HINSTANCE hinstDLL,DWORD fdwReason,LPVOID lpReserved )
  273. {
  274.         switch( fdwReason )
  275.         {
  276.         case DLL_PROCESS_ATTACH:
  277.                 hReadLock = OpenEventA(EVENT_MODIFY_STATE, FALSE, "MultiDebugRead");
  278.                 hWriteLock = OpenEventA(EVENT_MODIFY_STATE, FALSE, "MultiDebugWrite");
  279.                 if(!hReadLock || !hWriteLock)
  280.                         exit(0);
  281.                 Hook();
  282.                 break;
  283.         case DLL_THREAD_ATTACH:
  284.                 break;
  285.         case DLL_THREAD_DETACH:
  286.                 break;
  287.         case DLL_PROCESS_DETACH:
  288.                 UnHook();
  289.                 CloseHandle(hReadLock);
  290.                 CloseHandle(hWriteLock);
  291.                 break;
  292.         }
  293.         return TRUE;
  294. }

复制代码
  1. #define STATUS_SUCCESS                          ((NTSTATUS)0x00000000L)

  2. typedef LONG NTSTATUS;

  3. typedef struct _CLIENT_ID
  4. {
  5.         HANDLE UniqueProcess;
  6.         HANDLE UniqueThread;
  7. } CLIENT_ID, *PCLIENT_ID;

  8. typedef enum _DBG_STATE
  9. {
  10.         DbgIdle,
  11.         DbgReplyPending,
  12.         DbgCreateThreadStateChange,
  13.         DbgCreateProcessStateChange,
  14.         DbgExitThreadStateChange,
  15.         DbgExitProcessStateChange,
  16.         DbgExceptionStateChange,
  17.         DbgBreakpointStateChange,
  18.         DbgSingleStepStateChange,
  19.         DbgLoadDllStateChange,
  20.         DbgUnloadDllStateChange
  21. } DBG_STATE, *PDBG_STATE;

  22. typedef struct _DBGKM_EXCEPTION
  23. {
  24.         EXCEPTION_RECORD ExceptionRecord;
  25.         ULONG FirstChance;
  26. } DBGKM_EXCEPTION, *PDBGKM_EXCEPTION;

  27. typedef struct _DBGKM_CREATE_THREAD
  28. {
  29.         ULONG SubSystemKey;
  30.         PVOID StartAddress;
  31. } DBGKM_CREATE_THREAD, *PDBGKM_CREATE_THREAD;

  32. typedef struct _DBGKM_CREATE_PROCESS
  33. {
  34.         ULONG SubSystemKey;
  35.         HANDLE FileHandle;
  36.         PVOID BaseOfImage;
  37.         ULONG DebugInfoFileOffset;
  38.         ULONG DebugInfoSize;
  39.         DBGKM_CREATE_THREAD InitialThread;
  40. } DBGKM_CREATE_PROCESS, *PDBGKM_CREATE_PROCESS;

  41. typedef struct _DBGUI_CREATE_THREAD
  42. {
  43.         HANDLE HandleToThread;
  44.         DBGKM_CREATE_THREAD NewThread;
  45. } DBGUI_CREATE_THREAD, *PDBGUI_CREATE_THREAD;

  46. typedef struct _DBGUI_CREATE_PROCESS
  47. {
  48.         HANDLE HandleToProcess;
  49.         HANDLE HandleToThread;
  50.         DBGKM_CREATE_PROCESS NewProcess;
  51. } DBGUI_CREATE_PROCESS, *PDBGUI_CREATE_PROCESS;

  52. typedef struct _DBGKM_EXIT_THREAD
  53. {
  54.         NTSTATUS ExitStatus;
  55. } DBGKM_EXIT_THREAD, *PDBGKM_EXIT_THREAD;

  56. typedef struct _DBGKM_EXIT_PROCESS
  57. {
  58.         NTSTATUS ExitStatus;
  59. } DBGKM_EXIT_PROCESS, *PDBGKM_EXIT_PROCESS;

  60. typedef struct _DBGKM_LOAD_DLL
  61. {
  62.         HANDLE FileHandle;
  63.         PVOID BaseOfDll;
  64.         ULONG DebugInfoFileOffset;
  65.         ULONG DebugInfoSize;
  66.         PVOID NamePointer;
  67. } DBGKM_LOAD_DLL, *PDBGKM_LOAD_DLL;

  68. typedef struct _DBGKM_UNLOAD_DLL
  69. {
  70.         PVOID BaseAddress;
  71. } DBGKM_UNLOAD_DLL, *PDBGKM_UNLOAD_DLL;

  72. typedef struct _DBGUI_WAIT_STATE_CHANGE
  73. {
  74.         DBG_STATE NewState;
  75.         CLIENT_ID AppClientId;
  76.         union
  77.         {
  78.                 DBGKM_EXCEPTION Exception;
  79.                 DBGUI_CREATE_THREAD CreateThread;
  80.                 DBGUI_CREATE_PROCESS CreateProcessInfo;
  81.                 DBGKM_EXIT_THREAD ExitThread;
  82.                 DBGKM_EXIT_PROCESS ExitProcess;
  83.                 DBGKM_LOAD_DLL LoadDll;
  84.                 DBGKM_UNLOAD_DLL UnloadDll;
  85.         } StateInfo;
  86. } DBGUI_WAIT_STATE_CHANGE, *PDBGUI_WAIT_STATE_CHANGE;

  87. //common.h
  88. typedef struct _REQUEST_DATA//主调试器初始化
  89. {
  90.         int type;
  91.         char szEvent[0x100];//用于等待主调试器处理结果
  92.         DWORD dwDebuggerId;
  93.         union
  94.         {
  95.                 struct
  96.                 {
  97.                         DWORD dwDebuggeeId;
  98.                 }NtDebugActiveProcess;

  99.                 struct
  100.                 {
  101.                         CLIENT_ID ClientId;
  102.                         NTSTATUS ContinueStatus;
  103.                 }NtDebugContinue;

  104.                 struct
  105.                 {
  106.                 }NtRemoveProcessDebug;

  107.                 struct
  108.                 {
  109.                         ULONG DebugObjectInformationClass;
  110.                         PVOID DebugInformation;//主调试器ReadProcessMemory
  111.                         ULONG DebugInformationLength;
  112.                         ULONG ReturnLength;//返回长度
  113.                 }NtSetInformationDebugObject;

  114.                 struct
  115.                 {
  116.                         BOOLEAN Alertable;
  117.                         LARGE_INTEGER Timeout;
  118.                         PDBGUI_WAIT_STATE_CHANGE WaitStateChange;//主调试器WriteProcessMemory
  119.                 }NtWaitForDebugEvent;
  120.         }InOut;
  121. } REQUEST_DATA, *PREQUEST_DATA;

  122. enum
  123. {
  124.         NtDebugActiveProcess,
  125.         NtDebugContinue,
  126.         NtRemoveProcessDebug,
  127.         NtSetInformationDebugObject,
  128.         NtWaitForDebugEvent,
  129.         CheckRemoteDebugger,
  130.         HookMax,
  131. };
复制代码
回复

使用道具 举报

55

主题

276

回帖

9362

积分

用户组: 管理员

UID
77
精华
16
威望
237 点
宅币
8226 个
贡献
251 次
宅之契约
0 份
在线时间
255 小时
注册时间
2014-2-22
发表于 2015-7-13 00:38:32 | 显示全部楼层
能写个C版本吗???
回复 赞! 靠!

使用道具 举报

0

主题

76

回帖

6758

积分

用户组: 真·技术宅

UID
604
精华
0
威望
2 点
宅币
825 个
贡献
5853 次
宅之契约
0 份
在线时间
101 小时
注册时间
2014-12-20
发表于 2015-7-13 09:18:02 | 显示全部楼层
前排膜拜..
回复

使用道具 举报

QQ|Archiver|小黑屋|技术宅的结界 ( 滇ICP备16008837号 )|网站地图

GMT+8, 2024-5-7 12:15 , Processed in 0.037095 second(s), 28 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表