void Debugger::Start() { //initialize loop variables mBreakDebugger = false; mIsDebugging = true; mDetach = false; mDetachAndBreak = false; //use correct WaitForDebugEvent function typedef BOOL(WINAPI *MYWAITFORDEBUGEVENT)( _Out_ LPDEBUG_EVENT lpDebugEvent, _In_ DWORD dwMilliseconds ); static auto WFDEX = MYWAITFORDEBUGEVENT(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "WaitForDebugEventEx")); static auto MyWaitForDebugEvent = WFDEX ? WFDEX : MYWAITFORDEBUGEVENT(GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "WaitForDebugEvent")); if (!MyWaitForDebugEvent) { cbInternalError("MyWaitForDebugEvent not set!"); return; } while (!mBreakDebugger) { //wait for a debug event mIsRunning = true; if (!MyWaitForDebugEvent(&mDebugEvent, INFINITE)) break; mIsRunning = false; //set default continue status mContinueStatus = DBG_EXCEPTION_NOT_HANDLED; //set the current process and thread auto processFound = mProcesses.find(mDebugEvent.dwProcessId); if (processFound != mProcesses.end()) { mProcess = &processFound->second; auto threadFound = mProcess->threads.find(mDebugEvent.dwThreadId); if (threadFound != mProcess->threads.end()) { mThread = mProcess->thread = &threadFound->second; mRegisters = &mThread->registers; if (!mThread->RegReadContext()) cbInternalError("ThreadInfo::RegReadContext() failed!"); } else { mThread = mProcess->thread = nullptr; mRegisters = nullptr; } } else { mRegisters = nullptr; mThread = nullptr; if (mProcess) { mProcess->thread = nullptr; mProcess = nullptr; } } //call the pre debug event callback cbPreDebugEvent(mDebugEvent); //dispatch the debug event (documented here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms679302(v=vs.85).aspx) switch (mDebugEvent.dwDebugEventCode) { case CREATE_PROCESS_DEBUG_EVENT: createProcessEvent(mDebugEvent.u.CreateProcessInfo); break; case EXIT_PROCESS_DEBUG_EVENT: exitProcessEvent(mDebugEvent.u.ExitProcess); break; case CREATE_THREAD_DEBUG_EVENT: createThreadEvent(mDebugEvent.u.CreateThread); break; case EXIT_THREAD_DEBUG_EVENT: exitThreadEvent(mDebugEvent.u.ExitThread); break; case LOAD_DLL_DEBUG_EVENT: loadDllEvent(mDebugEvent.u.LoadDll); break; case UNLOAD_DLL_DEBUG_EVENT: unloadDllEvent(mDebugEvent.u.UnloadDll); break; case EXCEPTION_DEBUG_EVENT: exceptionEvent(mDebugEvent.u.Exception); break; case OUTPUT_DEBUG_STRING_EVENT: debugStringEvent(mDebugEvent.u.DebugString); break; case RIP_EVENT: ripEvent(mDebugEvent.u.RipInfo); break; default: unknownEvent(mDebugEvent.dwDebugEventCode); break; } //call the post debug event callback cbPostDebugEvent(mDebugEvent); //execute the delayed-detach if (mDetachAndBreak) { if (!UnsafeDetachAndBreak()) cbInternalError("Debugger::DetachAndBreak failed!"); break; } //clear trap flag when set by GleeBug (to prevent an EXCEPTION_SINGLE_STEP after detach if (mDetach && mThread) { if (mThread->isInternalStepping || mThread->isSingleStepping) mThread->registers.TrapFlag = false; } //write the register context if (mThread) { if (!mThread->RegWriteContext()) cbInternalError("ThreadInfo::RegWriteContext() failed!"); } //continue the debug event if (!ContinueDebugEvent(mDebugEvent.dwProcessId, mDebugEvent.dwThreadId, mContinueStatus)) break; if (mDetach || mDetachAndBreak) { if (!UnsafeDetach()) cbInternalError("Debugger::Detach failed!"); break; } } //cleanup mProcesses.clear(); mProcess = nullptr; mIsDebugging = false; }
bool EvaSetting::saveSetting(const int id, const char * md5Pwd, const bool recorded, const bool hidden , const int type, const Q_UINT32 server, const Q_UINT16 port, const QString username, const QCString base64Param) { QString home = QDir::homeDirPath(); QDir d; QString fullPath = home + "/.eva"; if (!d.exists(fullPath)){ if(!d.cd(home)){ emit exceptionEvent(QString("can't enter user's home directory")); return false; } if(!d.mkdir(QString(".eva"),false)){ emit exceptionEvent(QString("can't create Eva directory")); return false; } } QString fullName = fullPath + "/" + filename; loadSetting(); //if id exists, update information, otherwise add a new record int userIndex = findUser(id); Q_UINT8 flag = 0x00; if(recorded) flag|=0x01; if(hidden) flag |= 0x02; switch(type){ case 0: flag |= 0x10; // udp; break; case 1: flag |= 0x08; // tcp; break; case 2: flag |= 0x04; // http proxy; break; } QString s_username = "******"; QCString s_param = " "; if( !username.isEmpty() && username.stripWhiteSpace() != "") s_username = username; if( !base64Param.isEmpty() && base64Param.stripWhiteSpace() != "") s_param = base64Param; if( userIndex == -1){ //new record LoginRecord *record = new LoginRecord(); record->id = (uint)id; char *pwd = (char *)malloc(16 * sizeof(char)); memcpy(pwd, md5Pwd, 16); //FIXME memory leak here!!!! record->md5Pwd = (Q_UINT8 *)pwd; record->flag = flag; record->proxy = server; record->port = port; record->proxyUserName = s_username; record->base64param = s_param; userList.append(record); userIndex = userList.count()-1; }else{ // update information memcpy(userList.at(userIndex)->md5Pwd, md5Pwd, 16); userList.at(userIndex)->flag = flag; userList.at(userIndex)->proxy = server; userList.at(userIndex)->port = port; userList.at(userIndex)->proxyUserName = s_username; userList.at(userIndex)->base64param = s_param; } QFile file(fullName); if(!file.open(IO_WriteOnly)){ //QString msg = qApp->translate("QFile",file.errorString()); emit exceptionEvent(fullName); return false; } QDataStream stream(&file); // save the lastest user's id stream<<(Q_UINT32)(userIndex); // saving now for(uint i=0; i<userList.count(); i++){ LoginRecord *r= userList.at(i); stream<<r->id; stream.writeRawBytes((char *)(r->md5Pwd), 16); stream<<r->flag; stream<<r->proxy; stream<<r->port; Q_UINT8 len = strlen(r->proxyUserName.ascii()); stream<<len; //stream<<r->proxyUserName; stream.writeRawBytes(r->proxyUserName.ascii(), len); len = strlen(r->base64param.data()); stream<<len; stream.writeRawBytes(r->base64param.data(), len); } file.flush(); file.close(); return true; }