phpskycn作者
14年4个月前IP:未同步
448220
1楼
三、调试事件的处理
回顾一下,前面讲了,可以通过WaitForDebugEvent()函数填充DEBUG_EVENT结构获取DEBUG事件,下面介绍对于事件的处理。
处理无非分为两种:作出适当处理后继续运行被调试者或者终止被调试者运行。
Windows Debug API中通过ContinueDebugEvent()处理调试事件。
BOOL WINAPI ContinueDebugEvent(
  _In_  DWORD dwProcessId,
  _In_  DWORD dwThreadId,
  _In_  DWORD dwContinueStatus
);
前面两个参数在DEBUG_EVENT结构中包含,最后一个参考:XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX(v=vs.85).aspx。
一般选择DBG_CONTINUE使被调试者继续运行。
四、DEBUG循环
通过建立一个DEBUG循环,可以实现对DEBUG事件的动态处理。通过一个循环+switch...case结构,可以很好地完成。

STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
CreateProcess("C://1.exe",NULL,NULL,NULL,false,DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS|CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi);
cout<<"[s:9]roccess Creat"<<endl;
DEBUG_EVENT dbe;
while(true){
                                WaitForDebugEvent(&dbe,INFINITE);
        switch(dbe.dwDebugEventCode){
        case CREATE_PROCESS_DEBUG_EVENT:
            //Do what you want.
             ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
        case LOAD_DLL_DEBUG_EVENT:
            //Do what you want.
             ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
        case EXCEPTION_DEBUG_EVENT:
            cout<<"EXCEPTION!"<<endl;
            ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
        case EXIT_PROCESS_DEBUG_EVENT:
            cout<<"[s:9]orocess Exit!"<<endl;
                                                ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
            break;
        default:
            ContinueDebugEvent(dbe.dwProcessId,dbe.dwThreadId,DBG_CONTINUE);
        }
    
    }
TerminateProcess(pi.hProcess,-1);

循环开始的时候完成对事件的获取,接下来在switch...case结构中进行判断和处理。
五、更多
我们的调试器还能实现更多功能,除了利用进程句柄管理其内存外,还可以通过GetThreadContext()填充CONTEXT结构获取某线程的寄存器内容,甚至还可以通过SetThreadContext()来修改。

BOOL WINAPI GetThreadContext(
  _In_     HANDLE hThread,
  _Inout_  LPCONTEXT lpContext
);

BOOL WINAPI SetThreadContext(
  _In_  HANDLE hThread,
  _In_  const CONTEXT *lpContext
);

typedef struct _CONTEXT
{
      DWORD   ContextFlags;
      DWORD   Dr0;        
      DWORD   Dr1;        
      DWORD   Dr2;        
      DWORD   Dr3;        
      DWORD   Dr6;        
      DWORD   Dr7;        
      FLOATING_SAVE_AREA FloatSave;        
      DWORD   SegGs;        
      DWORD   SegFs;        
      DWORD   SegEs;        
      DWORD   SegDs;        
      DWORD   Edi;        
      DWORD   Esi;        
      DWORD   Ebx;        
      DWORD   Edx;        
      DWORD   Ecx;        
      DWORD   Eax;        
      DWORD   Ebp;        
      DWORD   Eip;        
      DWORD   SegCs;      
      DWORD   EFlags;        
      DWORD   Esp;        
      DWORD   SegSs;
}CONTEXT;
Eip也可以修改,可以通过它在直接控制被调试程序的运行,当然修改EFlags也可以。
评论
文号 / 448220

万流景仰
名片发私信
学术分 8
总主题 412 帖总回复 4593 楼拥有证书:专家 老干部 学者 机友 笔友
注册于 2009/03/15 21:53:00最后登录 2026/01/31 04:21:35
主体类型:个人
所属领域:无
认证方式:手机号
IP归属地:0

个人简介

CV

笔记
{{note.content}}
{{n.user.username}}
{{fromNow(n.toc)}} {{n.status === noteStatus.disabled ? "已屏蔽" : ""}} {{n.status === noteStatus.unknown ? "正在审核" : ""}} {{n.status === noteStatus.deleted ? '已删除' : ''}}
  • 编辑
  • 删除
  • {{n.status === 'disabled' ? "解除屏蔽" : "屏蔽" }}
我也是有底线的