调试器的原理
加载调试程序
调试程序的第一步就是使用OllyDbg来加载程序,加载的过程是通过创建新进程来完成的。OllyDbg通过CreateProcess以调试的方式开启新进程。在创建调成程序前,OllyDbg需要进行一些必要的检查工作。
首先是针对快捷方式的检查。OllyDbg根据可执行程序的后缀名来判断分析程序是否为一个快捷方式,如果是快捷方式,则会找到这个快捷方式所对应的可执行程序的全路径。通过检查DOS头与NT头来判定分析文件是否为合法的PE文件。当调试文件为DLL动态库时,Olly/Dbg会使用自带的LoadDll.exe将Dll文件进行加载。当调试文件为exe可执行程序时,会跳过Dll文件的处理部分,直接获取相关的配置文件信息并进行加载和调试。
加载步骤: 以加载扫雷为例
;1 创建扫雷进程 invoke CreateProcess,offset g_szFileName,NULL,NULL,NULL,NULL, DEBUG_ONLY_THIS_PROCESS,NULL,NULL,addr @si,addr @di ;2 等待调试事件 .While 1 invoke WaitForDebugEvent,addr @DebugEv,INFINITE ;3 获得进程句柄 invoke OpenProcess,PROCESS_ALL_ACCESS,NULL,@DebugEv.dwProcessId mov @hProcess,eax ;4 获得线程句柄 invoke OpenThread,THREAD_ALL_ACCESS,NULL,@DebugEv.dwThreadId mov @hThread,eax ;5 得到线程上下文 mov @Context.ContextFlags,CONTEXT_ALL invoke GetThreadContext,@hThread,addr @Context ;6 进入循环判断上下文内容 .if @DebugEv.dwDebugEventCode==EXCEPTION_DEBUG_EVENT;报告异常调试事件。 invoke OnException,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .elseif @DebugEv.dwDebugEventCode==CREATE_PROCESS_DEBUG_EVENT;报告创建进程调试事件。 invoke OnCreateProcess,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .elseif @DebugEv.dwDebugEventCode==CREATE_THREAD_DEBUG_EVENT;报告创建线程调试事件 invoke OnCreateThread,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .elseif @DebugEv.dwDebugEventCode==EXIT_PROCESS_DEBUG_EVENT;报告退出进程调试事件 invoke OnExitProcess,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .elseif @DebugEv.dwDebugEventCode==EXIT_THREAD_DEBUG_EVENT;报告退出线程调试事件。 invoke OnExitThread,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .elseif @DebugEv.dwDebugEventCode==UNLOAD_DLL_DEBUG_EVENT;报告一个卸载DLL调试事件 invoke OnUnLoadDll,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .elseif @DebugEv.dwDebugEventCode==LOAD_DLL_DEBUG_EVENT;报告加载动态链接库(DLL)调试事件。 invoke OnLoadDll,@hProcess,@hThread,addr @DebugEv,addr @Context mov @dwContinueStatus,eax .endif ;7 恢复线程上下文 mov @Context.ContextFlags,CONTEXT_ALL invoke SetThreadContext,@hThread,addr @Context ;8 关闭进程句柄和线程句柄 invoke CloseHandle,@hProcess invoke CloseHandle,@hThread ;9 继续调试事件,意思就是调试程序的时候有事件来,你处理完了要继续. invoke ContinueDebugEvent,@DebugEv.dwProcessId,@DebugEv.dwThreadId,@dwContinueStatus .endw