bool wait_for_exception(EXCEPTION_RECORD &ex) { bool ex_thrown = false; DEBUG_EVENT de; while(!ex_thrown) { if(WaitForDebugEvent(&de, (DWORD)100)) { switch(de.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: if(is_fatal_exception(de.u.Exception.ExceptionRecord.ExceptionCode)) ex_thrown = true; break; case EXIT_PROCESS_DEBUG_EVENT: return false; default: ContinueDebugEvent (de.dwProcessId, de.dwThreadId, DBG_CONTINUE); break; } } else ContinueDebugEvent (de.dwProcessId, de.dwThreadId, DBG_CONTINUE); } /* Exception caught! */ ex = de.u.Exception.ExceptionRecord; return ex_thrown; }
BOOL CDbgHook::DbgLoop(IHookWorker& Work) { DWORD dwDbgStatus; ContinueDebugEvent(m_de.dwProcessId, m_de.dwThreadId, DBG_CONTINUE); while (WaitForDebugEvent(&m_de, INFINITE)) { dwDbgStatus = DBG_CONTINUE; switch (m_de.dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: if (OnExceptionDbgEvent(m_de, Work)) continue; else dwDbgStatus = DBG_EXCEPTION_NOT_HANDLED; break; case EXIT_PROCESS_DEBUG_EVENT: return TRUE; } ContinueDebugEvent(m_de.dwProcessId, m_de.dwThreadId, dwDbgStatus); } return TRUE; }
HL_API int hl_debug_wait( int pid, int *thread, int timeout ) { # if defined(HL_WIN) DEBUG_EVENT e; if( !WaitForDebugEvent(&e,timeout) ) return -1; *thread = e.dwThreadId; switch( e.dwDebugEventCode ) { case EXCEPTION_DEBUG_EVENT: switch( e.u.Exception.ExceptionRecord.ExceptionCode ) { case EXCEPTION_BREAKPOINT: case 0x4000001F: // STATUS_WX86_BREAKPOINT return 1; case EXCEPTION_SINGLE_STEP: case 0x4000001E: // STATUS_WX86_SINGLE_STEP return 2; case 0x406D1388: // MS_VC_EXCEPTION (see SetThreadName) ContinueDebugEvent(e.dwProcessId, e.dwThreadId, DBG_CONTINUE); break; case 0xE06D7363: // C++ EH EXCEPTION ContinueDebugEvent(e.dwProcessId, e.dwThreadId, DBG_EXCEPTION_NOT_HANDLED); break; default: return 3; } case EXIT_PROCESS_DEBUG_EVENT: return 0; default: ContinueDebugEvent(e.dwProcessId, e.dwThreadId, DBG_CONTINUE); break; } return 4; # elif defined(USE_PTRACE) int status; int ret = waitpid(pid,&status,0); //printf("WAITPID=%X %X\n",ret,status); *thread = ret; if( WIFEXITED(status) ) return 0; if( WIFSTOPPED(status) ) { int sig = WSTOPSIG(status); //printf(" STOPSIG=%d\n",sig); if( sig == SIGSTOP || sig == SIGTRAP ) return 1; return 3; } return 4; # else return 0; # endif }
static BOOL tgt_process_active_close_process(struct dbg_process* pcs, BOOL kill) { if (pcs == dbg_curr_process) { /* remove all set breakpoints in debuggee code */ break_set_xpoints(FALSE); /* needed for single stepping (ugly). * should this be handled inside the server ??? */ be_cpu->single_step(&dbg_context, FALSE); if (dbg_curr_thread->in_exception) { SetThreadContext(dbg_curr_thread->handle, &dbg_context); ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, DBG_CONTINUE); } } if (kill) { TerminateProcess(pcs->handle, 0); } else { if (!DebugActiveProcessStop(pcs->pid)) return FALSE; } SymCleanup(pcs->handle); dbg_del_process(pcs); return TRUE; }
bool Pdb::Continue() { LLOG("** Continue"); running = true; ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); return RunToException(); }
void DebugLoop() { DEBUG_EVENT de; DWORD dwContinueStatus; // Debuggee 로부터 event 가 발생할 때까지 기다림 while( WaitForDebugEvent(&de, INFINITE) ) { dwContinueStatus = DBG_CONTINUE; // Debuggee 프로세스 생성 혹은 attach 이벤트 if( CREATE_PROCESS_DEBUG_EVENT == de.dwDebugEventCode ) { OnCreateProcessDebugEvent(&de); } // 예외 이벤트 else if( EXCEPTION_DEBUG_EVENT == de.dwDebugEventCode ) { if( OnExceptionDebugEvent(&de) ) continue; } // Debuggee 프로세스 종료 이벤트 else if( EXIT_PROCESS_DEBUG_EVENT == de.dwDebugEventCode ) { // debuggee 종료 -> debugger 종료 break; } // Debuggee 의 실행을 재개시킴 ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus); } }
ErrorCode Thread::resume(int signal, Address const &address) { // TODO(sas): Not sure how to translate the signal concept to Windows yet. // We'll probably have to get rid of these at some point. DS2ASSERT(signal == 0); // TODO(sas): Continuing a thread from a given address is not implemented yet. DS2ASSERT(!address.valid()); ErrorCode error = kSuccess; if (_state == kStopped || _state == kStepped) { ProcessInfo info; error = process()->getInfo(info); if (error != kSuccess) return error; BOOL result = ContinueDebugEvent(_process->pid(), _tid, DBG_CONTINUE); if (!result) return Host::Platform::TranslateError(); _state = kRunning; } else if (_state == kTerminated) { error = kErrorProcessNotFound; } return error; }
/* TODO: must return true/false */ static int r_debug_native_continue (RDebug *dbg, int pid, int tid, int sig) { #if __WINDOWS__ && !__CYGWIN__ if (ContinueDebugEvent (pid, tid, DBG_CONTINUE) == 0) { print_lasterr ((char *)__FUNCTION__, "ContinueDebugEvent"); eprintf ("debug_contp: error\n"); return false; } return tid; #elif __APPLE__ bool ret; ret = xnu_continue (dbg, pid, tid, sig); if (!ret) return -1; return tid; #elif __BSD__ void *data = (void*)(size_t)((sig != -1) ? sig : dbg->reason.signum); ut64 pc = r_debug_reg_get (dbg, "pc"); return ptrace (PTRACE_CONT, pid, (void*)(size_t)pc, (int)(size_t)data) == 0; #elif __CYGWIN__ #warning "r_debug_native_continue not supported on this platform" return -1; #else void *data = (void*)(size_t)((sig != -1) ? sig : dbg->reason.signum); //eprintf ("SIG %d\n", dbg->reason.signum); return ptrace (PTRACE_CONT, pid, NULL, data) == 0; #endif }
BOOL WINAPI HookedWaitForDebugEvent(LPDEBUG_EVENT lpDebugEvent, DWORD dwMilliseconds) { BOOL retV = dWaitForDebugEvent(lpDebugEvent, dwMilliseconds); if (retV) { while(1) { if (AnalyzeDebugStructure(lpDebugEvent)) { ContinueDebugEvent(lpDebugEvent->dwProcessId, lpDebugEvent->dwThreadId, DBG_EXCEPTION_NOT_HANDLED); retV = dWaitForDebugEvent(lpDebugEvent, dwMilliseconds); if (!retV) { break; } } else { break; } } } return retV; }
void WinDebugger::cont() { DWORD status = DBG_EXCEPTION_NOT_HANDLED; BOOL ret = ContinueDebugEvent(event_.dwProcessId, event_.dwThreadId, status); if (!ret) { std::cerr << "error: cont: " << GetLastError() << std::endl; abort(); } }
/* * DoContinueDebugEvent */ static BOOL DoContinueDebugEvent( DWORD continue_how ) { SetLastError( 0 ); if( !DidWaitForDebugEvent ) { return( FALSE ); } return( ContinueDebugEvent( DebugeePid, LastDebugEventTid, continue_how ) ); }
void get_debug_event() { PCONTEXT ctx; debug_event = DEBUG_EVENT(); ctn_status = DBG_CONTINUE; if (WaitForDebugEvent(&debug_event, INFINITE)) { h_thread = open_thread(debug_event.dwThreadId); ctx = get_thread_context(h_thread, NULL); std::cout << "[E] Event Code : " << debug_event.dwDebugEventCode << " Thread ID : " << debug_event.dwThreadId << std::endl; if (debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) { exception = debug_event.u.Exception.ExceptionRecord.ExceptionCode; exception_address = debug_event.u.Exception.ExceptionRecord.ExceptionAddress; switch (exception) { case EXCEPTION_ACCESS_VIOLATION: std::cout << "[EXCEPTION] ACCESS VIOLATION." << std::endl; break; case EXCEPTION_BREAKPOINT: ctn_status = exception_handler_breakpoint(); break; case EXCEPTION_GUARD_PAGE: std::cout << "[EXCEPTION] Guard Page Access Detected." << std::endl; break; case EXCEPTION_SINGLE_STEP: std::cout << "[EXCEPTION] Single Stepping." << std::endl; break; default: break; } ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, ctn_status); } } ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, ctn_status); }
HL_API bool hl_debug_resume( int pid, int thread ) { # if defined(HL_WIN) return (bool)ContinueDebugEvent(pid, thread, DBG_CONTINUE); # elif defined(USE_PTRACE) return ptrace(PTRACE_CONT,pid,0,0) >= 0; # else return false; # endif }
void Thread::Continue(void) { DWORD dwContinueStatus = DBG_CONTINUE; if (ContinueDebugEvent(this->myProcess->GetId(), this->iThread, dwContinueStatus) == TRUE) { return; } CString str; str.Format("%d: %s, error code (%d)", this->iThread, "/!\\ Error ContinueDebugEvent /!\\", GetLastError()); throw new DebuggerException(str); }
/* TODO: must return true/false */ static int r_debug_native_continue(RDebug *dbg, int pid, int tid, int sig) { #if __WINDOWS__ && !__CYGWIN__ /* Honor the Windows-specific signal that instructs threads to process exceptions */ DWORD continue_status = (sig == DBG_EXCEPTION_NOT_HANDLED) ? DBG_EXCEPTION_NOT_HANDLED : DBG_CONTINUE; if (ContinueDebugEvent (pid, tid, continue_status) == 0) { r_sys_perror ("r_debug_native_continue/ContinueDebugEvent"); eprintf ("debug_contp: error\n"); return false; } return tid; #elif __APPLE__ bool ret; ret = xnu_continue (dbg, pid, tid, sig); if (!ret) { return -1; } return tid; #elif __BSD__ void *data = (void*)(size_t)((sig != -1) ? sig : dbg->reason.signum); ut64 pc = r_debug_reg_get (dbg, "PC"); return ptrace (PTRACE_CONT, pid, (void*)(size_t)pc, (int)(size_t)data) == 0; #elif __CYGWIN__ #warning "r_debug_native_continue not supported on this platform" return -1; #else int contsig = dbg->reason.signum; if (sig != -1) { contsig = sig; } /* SIGINT handler for attached processes: dbg.consbreak (disabled by default) */ if (dbg->consbreak) { r_cons_break_push ((RConsBreak)r_debug_native_stop, dbg); } int ret = ptrace (PTRACE_CONT, pid, NULL, contsig); if (ret) { perror ("PTRACE_CONT"); } if (dbg->continue_all_threads && dbg->n_threads) { RList *list = dbg->threads; RDebugPid *th; RListIter *it; if (list) { r_list_foreach (list, it, th) { if (th->pid && th->pid != pid) { ptrace (PTRACE_CONT, tid, NULL, contsig); } } } }
void runner::debug() { DEBUG_EVENT debug_event; while (WaitForDebugEvent(&debug_event, INFINITE)) { ContinueDebugEvent(debug_event.dwProcessId, debug_event.dwThreadId, DBG_CONTINUE); if (debug_event.dwDebugEventCode == EXCEPTION_DEBUG_EVENT) { debug_event.dwProcessId = 0; } //std::cout << debug_event.u.DebugString.lpDebugStringData << std::endl; } }
void spwanAndHook_(char *dlltoinject,opt *options){ STARTUPINFO sInfo; PROCESS_INFORMATION pInfo; printf("[Info] Launching process: %s\n",options->cmdline); ZeroMemory(&sInfo, sizeof(sInfo)); sInfo.cb = sizeof(sInfo); ZeroMemory(&pInfo, sizeof(pInfo)); if (CreateProcess(options->cmdline, NULL, NULL, NULL, FALSE, DEBUG_ONLY_THIS_PROCESS/*CREATE_SUSPENDED*/, NULL, NULL, &sInfo, &pInfo)) { char cmd[512]; printf("[info] New pid: %d\n",pInfo.dwProcessId); sprintf(cmd,"EXECUTING \"%s\" HOOKING PID %d",options->cmdline,pInfo.dwProcessId); logger(options->ini,"injector",cmd,strlen(cmd)); DEBUG_EVENT debugEvent; do{ // printf(">> %x\n",debugEvent.dwDebugEventCode); if(!WaitForDebugEvent(&debugEvent, 1000)) break; if(debugEvent.dwDebugEventCode == LOAD_DLL_DEBUG_EVENT) { // SuspendThread(debugEvent.u.CreateProcessInfo.hThread); // printf("Injecting!\n"); injecta(pInfo.dwProcessId,dlltoinject,options); Sleep(1000); // ResumeThread(debugEvent.u.CreateProcessInfo.hThread); DebugSetProcessKillOnExit(FALSE); DebugActiveProcessStop(debugEvent.dwProcessId); break; } ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE); } while(1); /* if(WaitForInputIdle((void*)pInfo.hProcess,5)==WAIT_FAILED) printf("[info] Wait failed, console app? :p"); if(options->waitKeyPress){ printf("Press [intro] to resume process..\n"); getchar(); }*/ // injecta(pInfo.dwProcessId,dlltoinject,options); // ResumeThread((void*)pInfo.hThread); // WaitForInputIdle((void*)pInfo.dwProcessId,INFINITE); // Sleep(100); CloseHandle(pInfo.hThread); CloseHandle(pInfo.hProcess); }else{ printf("[Error] Unable to create the process (path not found?)\n"); } }
VOID _cdecl wmain( ULONG argc, WCHAR* argv[] ) { if (argc < 2) { wprintf(L"03sample <target>\n"); return; } STARTUPINFO startupInfo={0}; startupInfo.cb = sizeof(startupInfo); PROCESS_INFORMATION processInfo = {0}; int commandLength = wcslen(argv[1])+(argv[2]?wcslen(argv[2]):0) + 2; WCHAR * commandLine = new WCHAR[commandLength]; if (!commandLine) { TRACE(L"Allocation failed\n"); } wcscpy_s(commandLine, commandLength, argv[1]); if (argv[2]) { wcscat_s(commandLine, commandLength, L" "); wcscat_s(commandLine, commandLength, argv[2]); } BOOL res = CreateProcess(NULL, commandLine, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &startupInfo, &processInfo); if (FALSE == res) { TRACE(L"CreateProcess failed\n"); return; } DEBUG_EVENT debugEvent = { 0 } ; DWORD endDisposition = DBG_CONTINUE; for(;endDisposition != 0;) { if (!WaitForDebugEvent(&debugEvent, INFINITE)) { TRACE(L"WaitForDebugEvent failed\n"); break; } endDisposition = ProcessEvent(debugEvent); if (0 == endDisposition) break; if (!ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, endDisposition)) { TRACE(L"ContinueDebugEvent failed\n"); break; }; } }
static BOOL child_continue (DWORD continue_status, int thread_id) { BOOL res; res = ContinueDebugEvent (current_event.dwProcessId, current_event.dwThreadId, continue_status); continue_status = 0; if (res) find_inferior (&all_threads, continue_one_thread, &thread_id); debug_registers_changed = 0; return res; }
static BOOL child_continue (DWORD continue_status, int thread_id) { /* The inferior will only continue after the ContinueDebugEvent call. */ find_inferior (&all_threads, continue_one_thread, &thread_id); faked_breakpoint = 0; if (!ContinueDebugEvent (current_event.dwProcessId, current_event.dwThreadId, continue_status)) return FALSE; return TRUE; }
void ContextOverride::OnPreExecute( PreExecuteEvent &event, bool firstTime ) { if (!firstTime) return; if (m_done) return; u32 entry = LxEmulator.Proc()->GetEntryPoint(); if (event.Cpu->EIP != entry) return; CONTEXT ctx; RefProcess *refproc = LxEmulator.RefProc(); m_pi = refproc->GetProcessInformation(); m_event = refproc->GetDebugEvent(); byte origByte = refproc->SetInt3(entry); ContinueDebugEvent(m_pi->dwProcessId, m_pi->dwThreadId, DBG_CONTINUE); while (WaitForDebugEvent(m_event, INFINITE)) { if (m_event->dwDebugEventCode == EXCEPTION_DEBUG_EVENT && m_event->u.Exception.ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT) { refproc->GetMainContext(&ctx, CONTEXT_CONTROL); ctx.Eip--; if (ctx.Eip != entry) { LxFatal("SyncDiff: Unexpected sync address %08x, should be %08x\n", ctx.Eip, entry); } refproc->SetMainContext(&ctx); refproc->RestoreInt3(ctx.Eip, origByte); break; } ContinueDebugEvent(m_pi->dwProcessId, m_pi->dwThreadId, DBG_CONTINUE); } refproc->SetTF(); LxInfo("Overriding Context..\n"); OverrideContext(event.Cpu); m_done = true; }
BOOL CDbgHook::OnExceptionDbgEvent(DEBUG_EVENT& de, IHookWorker& Work) { PVOID lpAddr; hsOrgOpcode::iterator it; hsFuncName::iterator it2; BYTE Int3 = 0xCC; CONTEXT ctx; if (de.u.Exception.ExceptionRecord.ExceptionCode != EXCEPTION_BREAKPOINT) return FALSE; lpAddr = de.u.Exception.ExceptionRecord.ExceptionAddress; //Original Opcode를 구한다. it = OrgBytes.find(lpAddr); if (it == OrgBytes.end()) return FALSE; //해당 함수명을 구한다. it2 = Funcs.find(lpAddr); if (it2 == Funcs.end()) return FALSE; //할 일을 한다. Work.Worker(lpAddr, it2->second); //Eip조정 ctx.ContextFlags = CONTEXT_CONTROL; GetThreadContext(m_cpdi.hThread, &ctx); ctx.Eip = (DWORD)lpAddr; SetThreadContext(m_cpdi.hThread, &ctx); //Unhook WriteProcessMemory(m_cpdi.hProcess, lpAddr, &it->second, sizeof(it->second), NULL); ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE); Sleep(0); //Hook WriteProcessMemory(m_cpdi.hProcess, lpAddr, &Int3, sizeof(Int3), NULL); return TRUE; }
unsigned long __stdcall threaddeb(void *v) { STARTUPINFO si = { sizeof(STARTUPINFO) }; CreateProcess(0,"c:\\winnt\\system32\\taskmgr.exe",0,0,0, CREATE_NEW_CONSOLE,0,0,&si,&pi); Sleep(2000); BOOL status = CreateProcess( 0, "c:\\winnt\\system32\\calc.exe", 0,0,0, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS | CREATE_NEW_CONSOLE, 0,0,&si,&pi); if( !status ) { printf("%s\n","error debugging"); exit(1); } add_thread(pi.hThread); for( ;; ) { DEBUG_EVENT de; if( !WaitForDebugEvent(&de, INFINITE) ) { printf("%s\n","error WaitForDebugEvent"); } switch( de.dwDebugEventCode ) { case CREATE_THREAD_DEBUG_EVENT: add_thread(de.u.CreateThread.hThread); break; } ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE); } return 0; }
DWORD _scitGetExitCodeThread(HANDLE hRemoteThread, BOOL bDebugee) { DWORD dwThreadExitCode = -1; DEBUG_EVENT de; do { GetExitCodeThread(hRemoteThread, (LPDWORD)&dwThreadExitCode); if (dwThreadExitCode == STILL_ACTIVE && bDebugee) { if (!WaitForDebugEvent(&de, INFINITE)) { break; } ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE); } } while (dwThreadExitCode == STILL_ACTIVE); return dwThreadExitCode; }
void CDebugger::DebugLoop() { DEBUG_EVENT DebugEvt = { 0 }; LPDEBUG_EVENT lpDebugEvt = &DebugEvt; while (m_bActive) { WaitForDebugEvent(lpDebugEvt, 60 * 1000); m_pEventHandler->SetContinueStatus(DBG_EXCEPTION_NOT_HANDLED); switch (lpDebugEvt->dwDebugEventCode) { case EXCEPTION_DEBUG_EVENT: m_pEventHandler->OnException(lpDebugEvt); break; case CREATE_THREAD_DEBUG_EVENT: m_pEventHandler->OnCreateThreadDebugEvent(lpDebugEvt); break; case CREATE_PROCESS_DEBUG_EVENT: m_pEventHandler->OnCreateProcessDebugEvent(lpDebugEvt); break; case EXIT_THREAD_DEBUG_EVENT: m_pEventHandler->OnExitThreadDebugEvent(lpDebugEvt); break; case EXIT_PROCESS_DEBUG_EVENT: m_pEventHandler->OnExitProcessDebugEvent(lpDebugEvt); break; case LOAD_DLL_DEBUG_EVENT: m_pEventHandler->OnLoadDllDebugEvent(lpDebugEvt); break; case UNLOAD_DLL_DEBUG_EVENT: m_pEventHandler->OnUnloadDllDebugEvent(lpDebugEvt); break; case OUTPUT_DEBUG_STRING_EVENT: m_pEventHandler->OnOutputDebugStringEvent(lpDebugEvt); break; case RIP_EVENT: m_pEventHandler->OnRipEvent(lpDebugEvt); break; default: cout << "[*] Unknown debug event!" << endl; } ContinueDebugEvent(lpDebugEvt->dwProcessId, lpDebugEvt->dwThreadId, m_pEventHandler->GetContinueStatus()); } }
void WinDbgThread::run() { qDebug() << "WinDbgThread started"; // start process or attach process if (m_bOwnsProcess) { // create new process internalStartProcess(); } else { // attach to process qWarning("attach to process not yet implemented"); return; } m_hThisThread = OpenThread(THREAD_SUSPEND_RESUME, FALSE, GetCurrentThreadId()); if (!m_hThisThread) { qWarning("WinDbgThread: can't open thread handle"); return; } DEBUG_EVENT debugEvent; m_bAbortEventPollingLoop = false; while (WaitForDebugEvent(&debugEvent, INFINITE)) { setState(ProcessPaused); emit debugEventOccured(&debugEvent); suspend(); if (m_bAbortEventPollingLoop) break; ContinueDebugEvent(debugEvent.dwProcessId, debugEvent.dwThreadId, DBG_CONTINUE); setState(ProcessRunning); } setState(Idle); if (m_bOwnsProcess) { TerminateProcess(m_pi.hProcess, 0); } CloseHandle(m_pi.hProcess); CloseHandle(m_pi.hThread); CloseHandle(m_hThisThread); qDebug() << "WinDbgThread finished"; }
void DebugLoop() { DEBUG_EVENT de; //int dwContinuesStatus; //wait for event.... while(WaitForDebugEvent(&de,INFINITE)) { //dwContinuesStatus=0x00010002; //被调试进程生成或者附加事件 if(CREATE_PROCESS_DEBUG_EVENT==de.dwDebugEventCode) { printf("created debug !\n"); OnCreateProcessDebugEvent(&de); printf("seccessfully created int 3\n"); } //异常事件 else if (EXCEPTION_DEBUG_EVENT==de.dwDebugEventCode) { printf("Exception debug event !code =%X\n",de.dwDebugEventCode); if(OnExceptionDebugEvent(&de)) { printf("on exception debug event\n"); continue; } } //被调试进程终止事件 else if (EXIT_PROCESS_DEBUG_EVENT==de.dwDebugEventCode) //被调试者终止-调试器终止 { printf("debugee exited \n"); break; } //再次运行被调试者 ContinueDebugEvent(de.dwProcessId,de.dwThreadId,0x00010002) ; } }
bool Pdb::SingleStep() { LLOG("SINGLE STEP 0"); #if CPU_64 if(win64) context.context64.EFlags |= 0x100; else #endif context.context32.EFlags |= 0x100; WriteContext(); running = true; ContinueDebugEvent(event.dwProcessId, event.dwThreadId, DBG_CONTINUE); if(!RunToException()) return false; #if CPU_64 if(win64) context.context64.EFlags &= ~0x100; else #endif context.context32.EFlags &= ~0x100; WriteContext(); return true; }
static void dbg_resume_debuggee(DWORD cont) { if (dbg_curr_thread->in_exception) { ADDRESS64 addr; char hexbuf[MAX_OFFSET_TO_STR_LEN]; dbg_exception_epilog(); memory_get_current_pc(&addr); WINE_TRACE("Exiting debugger PC=%s mode=%d count=%d\n", memory_offset_to_string(hexbuf, addr.Offset, 0), dbg_curr_thread->exec_mode, dbg_curr_thread->exec_count); if (dbg_curr_thread) { if (!SetThreadContext(dbg_curr_thread->handle, &dbg_context)) dbg_printf("Cannot set ctx on %04x\n", dbg_curr_tid); } } dbg_interactiveP = FALSE; if (!ContinueDebugEvent(dbg_curr_pid, dbg_curr_tid, cont)) dbg_printf("Cannot continue on %04x (%08x)\n", dbg_curr_tid, cont); }
int main(int argc, char* argv[]) { if ( argc != 2 ) { printf("usage: %s crackme.exe \r\n", argv[0]); return -1; } // 保存文件名 char *pszFileName = argv[1]; // 启动信息 STARTUPINFO si = { 0 }; si.cb = sizeof(STARTUPINFO); GetStartupInfo(&si); // 进程信息 PROCESS_INFORMATION pi = { 0 }; // 创建被调试进程 BOOL bRet = CreateProcess(pszFileName, NULL, NULL, NULL, FALSE, DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS, NULL, NULL, &si, &pi); if ( bRet == FALSE ) { printf("CreateProcess Error \r\n"); return -1; } DEBUG_EVENT de = { 0 }; CONTEXT context = { 0 }; // 保存原始的机器码 BYTE bOldByte = 0; DWORD dwReadWriteNum = 0; // 保存正确密码使用 char pszPassword[MAXBYTE] = { 0 }; // 保存错误密码使用 char pszErrorPass[MAXBYTE] = { 0 }; while ( TRUE ) { // 获取调试事件 WaitForDebugEvent(&de, INFINITE); // 判断事件类型 switch ( de.dwDebugEventCode ) { // 创建进程时的调试事件 case CREATE_PROCESS_DEBUG_EVENT: { // 读取欲设置INT3断点处的机器码 // 方便后面恢复 ReadProcessMemory(pi.hProcess, (LPVOID)BP_VA, (LPVOID)&bOldByte, sizeof(BYTE), &dwReadWriteNum); // 将INT3的机器码0xCC写入断点处 WriteProcessMemory(pi.hProcess, (LPVOID)BP_VA, (LPVOID)&bInt3, sizeof(BYTE), &dwReadWriteNum); break; } // 产生异常时的调试事件 case EXCEPTION_DEBUG_EVENT: { // 判断异常类型 switch ( de.u.Exception.ExceptionRecord.ExceptionCode ) { // INT3类型的异常 case EXCEPTION_BREAKPOINT: { // 获取线程环境 context.ContextFlags = CONTEXT_FULL; GetThreadContext(pi.hThread, &context); // 判断是否断在我们设置的断点位置处 if ( (BP_VA + 1) == context.Eip ) { // 读取正确的密码 ReadProcessMemory(pi.hProcess, (LPVOID)context.Edx, (LPVOID)pszPassword, MAXBYTE, &dwReadWriteNum); // 读取错误密码 ReadProcessMemory(pi.hProcess, (LPVOID)context.Ecx, (LPVOID)pszErrorPass, MAXBYTE, &dwReadWriteNum); printf("你输入的密码是: %s \r\n", pszErrorPass); printf("正确的密码是: %s \r\n", pszPassword); // 因为我们的指令执行了INT3因此被中断 // INT3的机器指令长度为一个字节 // 因此我们需要将EIP减一来修正EIP // EIP是指令指针寄存器 // 其中保存着下条要执行指令的地址 context.Eip --; // 修正原来该地址的机器码 WriteProcessMemory(pi.hProcess, (LPVOID)BP_VA, (LPVOID)&bOldByte, sizeof(BYTE), &dwReadWriteNum); // 设置当前的线程环境 SetThreadContext(pi.hThread, &context); } break; } } } } ContinueDebugEvent(de.dwProcessId,de.dwThreadId,DBG_CONTINUE); } CloseHandle(pi.hThread); CloseHandle(pi.hProcess); return 0; }