void coreInit(PLUG_INITSTRUCT* initStruct) { // register commands _plugin_logprintf("[sync] pluginHandle: %d\n", pluginHandle); if (!_plugin_registercommand(pluginHandle, "!sync", cbSyncCommand, false)) _plugin_logputs("[sync] error registering the \"!sync\" command!"); if (!_plugin_registercommand(pluginHandle, "!syncoff", cbSyncoffCommand, true)) _plugin_logputs("[sync] error registering the \"!syncoff\" command!"); // initialize globals g_Synchronized = FALSE; g_hPollCompleteEvent = CreateEvent(NULL, true, false, NULL); if (g_hPollCompleteEvent == NULL) { _plugin_logputs("[sync] Command polling feature init failed\n"); return; } InitializeCriticalSection(&g_CritSectPollRelease); if (SUCCEEDED(LoadConfigurationFile())){ _plugin_logprintf("[sync] Configuration file loaded\n -> set HOST to %s:%s\n", g_DefaultHost, g_DefaultPort); } }
// Update state and send info to client: eip module's base address, offset, name HRESULT UpdateState() { bool bRes = FALSE; HRESULT hRes = E_FAIL; DWORD dwRes = 0; ULONG64 PrevBase = g_Base; ULONG NameSize = 0; HANDLE hProcess; g_Offset = GetContextData(UE_CIP); bRes = DbgGetModuleAt((duint)g_Offset, g_NameBuffer); if (!bRes) { _plugin_logprintf("[sync] UpdateState: no module at %p...\n", g_Offset); return hRes; } g_Base = DbgModBaseFromName(g_NameBuffer); if (!g_Base) { _plugin_logputs("[sync] UpdateState: could not get module base..."); return hRes; } // Check if we are in a new module if ((g_Base != PrevBase) & g_SyncAuto) { hProcess = ((PROCESS_INFORMATION*)TitanGetProcessInformation())->hProcess; dwRes = GetModuleBaseNameA(hProcess, (HMODULE)g_Base, g_NameBuffer, MAX_MODULE_SIZE); if (dwRes==0) { _plugin_logputs("[sync] could not get module base name..."); return hRes; } #if VERBOSE >= 2 _plugin_logprintf("[sync] UpdateState: module : \"%s\"\n", g_NameBuffer); #endif hRes = TunnelSend("[notice]{\"type\":\"module\",\"path\":\"%s\"}\n", g_NameBuffer); if (FAILED(hRes)){ return hRes; } } hRes = TunnelSend("[sync]{\"type\":\"loc\",\"base\":%llu,\"offset\":%llu}\n", g_Base, g_Offset); return hRes; }
ApiDB::ApiDB(void) { unsigned int i=0; mValid = true; std::ifstream helpFile; std::string rawLine; helpFile.open("api.dat"); if(!helpFile){ _plugin_logputs("[StaticAnalysis] api help file not found ..."); }else{ _plugin_logputs("[StaticAnalysis] load api help file ..."); while(!helpFile.eof()) { helpFile >> rawLine; std::vector<std::string> tokens = split(rawLine,";"); if(tokens.size() >3){ FunctionInfo_t f; f.DLLName = tokens.at(0); f.ReturnType = tokens.at(1); f.Name = tokens.at(2); for (int j = 3;j<tokens.size()-1;j+=2) { ArgumentInfo_t a; a.Type = tokens.at(j); a.Name = tokens.at(j+1); f.Arguments.push_back(a); } mInfo.push_back(f); i++; } } } _plugin_logprintf("[StaticAnalysis] loaded %i functions signatures from helpfile\n",i); helpFile.close(); }
extern "C" __declspec(dllexport) void CBRESUMEDEBUG(CBTYPE cbType, PLUG_CB_RESUMEDEBUG* info) { #if VERBOSE >= 2 _plugin_logputs("[sync] debugging resumed!"); #endif ReleasePollTimer(); }
extern "C" __declspec(dllexport) void CBSTOPDEBUG(CBTYPE cbType, PLUG_CB_STOPDEBUG* info) { #if VERBOSE >= 2 _plugin_logputs("[sync] debugging stopped!"); #endif syncoff(); }
void printFileName() { std::wstring logtext = LoadWideString(IDS_LOGTEXT1) + L"\r\n"; ReplaceWString(logtext, L"%template", templatename); ReplaceWString(logtext, L"%file", exportedname); std::string outputtext; utf8::utf16to8(logtext.begin(), logtext.end(), std::back_inserter(outputtext)); _plugin_logputs(outputtext.c_str()); }
extern "C" __declspec(dllexport) void CBMENUENTRY(CBTYPE cbType, PLUG_CB_MENUENTRY* info) { switch (info->hEntry) { case MENU_ENABLE_SYNC: { _plugin_logputs("[sync] enable sync"); sync(NULL); } break; case MENU_DISABLE_SYNC: { _plugin_logputs("[sync] disable sync"); syncoff(); } break; break; } }
// Setup poll timer callback VOID CreatePollTimer() { BOOL bRes; bRes = CreateTimerQueueTimer(&g_hPollTimer, NULL, (WAITORTIMERCALLBACK)PollTimerCb, NULL, TIMER_PERIOD, TIMER_PERIOD, WT_EXECUTEINTIMERTHREAD); if (!(bRes)){ _plugin_logputs("[sync] failed to CreatePollTimer\n"); } }
extern "C" __declspec(dllexport) void CBPAUSEDEBUG(CBTYPE cbType, PLUG_CB_PAUSEDEBUG* info) { #if VERBOSE >= 2 _plugin_logputs("[sync] debugging paused!"); #endif if (SUCCEEDED(TunnelIsUp())) { UpdateState(); CreatePollTimer(); } }
HRESULT sync(PSTR Args) { HRESULT hRes = S_OK; // Reset global state g_Base = NULL; g_Offset = NULL; if (g_Synchronized) { _plugin_logputs("[sync] sync update\n"); UpdateState(); goto Exit; } if (FAILED(hRes = TunnelCreate(g_DefaultHost, g_DefaultPort))) { _plugin_logputs("[sync] sync failed\n"); goto Exit; } _plugin_logputs("[sync] probing sync\n"); hRes = TunnelSend("[notice]{\"type\":\"new_dbg\",\"msg\":\"dbg connect - x64_dbg\",\"dialect\":\"x64_dbg\"}\n"); if (FAILED(hRes)) { _plugin_logputs("[sync] sync aborted\n"); goto Exit; } _plugin_logprintf("[sync] sync is now enabled with host %s\n", g_DefaultHost); UpdateState(); CreatePollTimer(); Exit: return hRes; }
HRESULT syncoff() { HRESULT hRes = S_OK; if (!g_Synchronized){ return hRes; } ReleasePollTimer(); hRes = TunnelClose(); _plugin_logputs("[sync] sync is now disabled\n"); return hRes; }
void ReleasePollTimer() { BOOL bRes; DWORD dwErr; EnterCriticalSection(&g_CritSectPollRelease); #if VERBOSE >= 2 _plugin_logputs("[sync] ReleasePollTimer called\n"); #endif if (!(g_hPollTimer == INVALID_HANDLE_VALUE)) { ResetEvent(g_hPollCompleteEvent); bRes = DeleteTimerQueueTimer(NULL, g_hPollTimer, g_hPollCompleteEvent); if (bRes == 0) { // msdn: If the error code is ERROR_IO_PENDING, it is not necessary to // call this function again. For any other error, you should retry the call. dwErr = GetLastError(); if (dwErr != ERROR_IO_PENDING){ bRes = DeleteTimerQueueTimer(NULL, g_hPollTimer, g_hPollCompleteEvent); if (!bRes){ #if VERBOSE >= 2 _plugin_logputs("[sync] ReleasePollTimer called\n"); #endif } } } g_hPollTimer = INVALID_HANDLE_VALUE; } LeaveCriticalSection(&g_CritSectPollRelease); }
static bool cbSyncoffCommand(int argc, char* argv[]) { _plugin_logputs("[sync] syncoff command!"); syncoff(); return true; }
static bool cbSyncCommand(int argc, char* argv[]) { _plugin_logputs("[sync] sync command!"); sync(NULL); return true; }
void ExportPatch(const std::wstring & templateContent, DBGPATCHINFO* patchList, size_t numPatches) { printFileName(); size_t idx_template = templateContent.find(L"$TEMPLATE_PREFIX:"); size_t idx_module = templateContent.find(L"$MODULE_PREFIX:"); size_t idx_patch = templateContent.find(L"$PATCH:"); size_t idx_module_suffix = templateContent.find(L"$MODULE_SUFFIX:"); size_t idx_template_suffix = templateContent.find(L"$TEMPLATE_SUFFIX:"); if(idx_template == std::wstring::npos || idx_module == std::wstring::npos || idx_patch == std::wstring::npos || idx_module_suffix == std::wstring::npos || idx_template_suffix == std::wstring::npos) { MessageBox(hwndDlg, LoadWideString(IDS_INVALID_PATCH).c_str(), LoadWideString(IDS_PLUGNAME).c_str(), MB_ICONERROR); return; } HANDLE hProcess; wchar_t ProcessName[1024]; memset(ProcessName, 0, sizeof(ProcessName)); hProcess = (HANDLE)DbgValFromString("$hProcess"); if(GetModuleBaseNameW(hProcess, 0, ProcessName, sizeof(ProcessName) / sizeof(wchar_t)) == 0) { MessageBox(hwndDlg, LoadWideString(IDS_HPROCESSFAIL).c_str(), LoadWideString(IDS_PLUGNAME).c_str(), MB_ICONERROR); return; } std::wstring text = templateContent.substr(idx_template + int(wcslen(L"$TEMPLATE_PREFIX:")), idx_module - idx_template - int(wcslen(L"$TEMPLATE_PREFIX:"))); std::wstring modulePrefix = templateContent.substr(idx_module + int(wcslen(L"$MODULE_PREFIX:")), idx_patch - idx_module - int(wcslen(L"$MODULE_PREFIX:"))); std::wstring patchText = templateContent.substr(idx_patch + int(wcslen(L"$PATCH:")), idx_module_suffix - idx_patch - int(wcslen(L"$PATCH:"))); std::wstring moduleSuffix = templateContent.substr(idx_module_suffix + int(wcslen(L"$MODULE_SUFFIX:")), idx_template_suffix - idx_module_suffix - int(wcslen(L"$MODULE_SUFFIX:"))); std::wstring templateSuffix = templateContent.substr(idx_template_suffix + int(wcslen(L"$TEMPLATE_SUFFIX:"))); std::vector<std::pair<std::wstring, unsigned int>> modules; std::string firstModuleUTF8(patchList[0].mod); std::wstring firstModuleUTF16; unsigned int currentModuleCount = 1; utf8::utf8to16(firstModuleUTF8.begin(), firstModuleUTF8.end(), std::back_inserter(firstModuleUTF16)); modules.push_back(std::make_pair(firstModuleUTF16, 1)); for(duint i = 1; i < numPatches; i++) { firstModuleUTF8 = std::string(patchList[i].mod); firstModuleUTF16.clear(); utf8::utf8to16(firstModuleUTF8.begin(), firstModuleUTF8.end(), std::back_inserter(firstModuleUTF16)); if(firstModuleUTF16.compare(modules.back().first) != 0) { modules.back().second = currentModuleCount; currentModuleCount = 1; modules.push_back(std::make_pair(firstModuleUTF16, 1)); } else currentModuleCount++; } modules.back().second = currentModuleCount; currentModuleCount = 0; duint patches = 0; duint modbase; unsigned int currentModule = 0; std::wstring moduleText; for(duint i = 0; i < numPatches; i++) { if(currentModuleCount == 0) { moduleText += modulePrefix + L"\r\n"; modbase = DbgFunctions()->ModBaseFromName(patchList[i].mod); } std::wstring patchText2(patchText); std::wstring newByteText(printByte(patchList[i].newbyte)); ReplaceWString(patchText2, L"$rva", printHex(patchList[i].addr - modbase)); ReplaceWString(patchText2, L"$newByte", newByteText); ReplaceWString(patchText2, L"$patchIndex", printInto(++patches)); moduleText += patchText2 + L"\r\n"; if(currentModuleCount == modules.at(currentModule).second - 1) { moduleText += moduleSuffix + L"\r\n"; ReplaceWString(moduleText, L"$moduleName", modules.at(currentModule).first); ReplaceWString(moduleText, L"$numPatches", printInto(modules.at(currentModule).second)); text += moduleText; moduleText.clear(); currentModuleCount = 0; patches = 0; currentModule++; } else currentModuleCount++; } text.append(templateSuffix); ReplaceWString(text, L"$numPatches", printInto(numPatches)); ReplaceWString(text, L"$exeName", std::wstring(ProcessName)); ReplaceWString(text, L"$date", printTime()); std::wstring compiledate; std::string compiledateASCII(__DATE__); utf8::utf8to16(compiledateASCII.begin(), compiledateASCII.end(), std::back_inserter(compiledate)); ReplaceWString(text, L"$compiledate", compiledate); // save if(SaveFile(exportedname, text)) _plugin_logputs(LoadUTF8String(IDS_SAVESUCCESS).c_str()); else _plugin_logputs(LoadUTF8String(IDS_SAVEFAIL).c_str()); }