static BOOL CALLBACK EnumSymbols(PSYMBOL_INFO SymInfo, ULONG SymbolSize, PVOID UserContext) { SYMBOLINFO curSymbol; memset(&curSymbol, 0, sizeof(SYMBOLINFO)); curSymbol.addr = (duint)SymInfo->Address; curSymbol.decoratedSymbol = (char*)BridgeAlloc(strlen(SymInfo->Name) + 1); curSymbol.undecoratedSymbol = (char*)BridgeAlloc(MAX_SYM_NAME); strcpy_s(curSymbol.decoratedSymbol, strlen(SymInfo->Name) + 1, SymInfo->Name); // Skip bad ordinals if(strstr(SymInfo->Name, "Ordinal")) { // Does the symbol point to the module base? if(SymInfo->Address == SymInfo->ModBase) return TRUE; } // Convert a mangled/decorated C++ name to a readable format if(!SafeUnDecorateSymbolName(SymInfo->Name, curSymbol.undecoratedSymbol, MAX_SYM_NAME, UNDNAME_COMPLETE)) { BridgeFree(curSymbol.undecoratedSymbol); curSymbol.undecoratedSymbol = nullptr; } else if(!strcmp(curSymbol.decoratedSymbol, curSymbol.undecoratedSymbol)) { BridgeFree(curSymbol.undecoratedSymbol); curSymbol.undecoratedSymbol = nullptr; } SYMBOLCBDATA* cbData = (SYMBOLCBDATA*)UserContext; cbData->cbSymbolEnum(&curSymbol, cbData->user); return TRUE; }
void DescriptorToCode(SIG_DESCRIPTOR *Descriptor, char **Data, char **Mask) { // // Allocate buffers for the resulting strings // size_t dataSize = Descriptor->Count * strlen("\\x00") + 1; size_t maskSize = Descriptor->Count * strlen("x") + 1; *Data = (char *)BridgeAlloc(dataSize); *Mask = (char *)BridgeAlloc(maskSize); for (ULONG i = 0; i < Descriptor->Count; i++) { if (Descriptor->Entries[i].Wildcard == 0) { char temp[16]; sprintf_s(temp, "\\x%02X", (DWORD)Descriptor->Entries[i].Value); strcat_s(*Data, dataSize, temp); strcat_s(*Mask, maskSize, "x"); } else { strcat_s(*Data, dataSize, "\\x00"); strcat_s(*Mask, maskSize, "?"); } } }
void DescriptorToIDA(SIG_DESCRIPTOR *Descriptor, char **Data) { // // Allocate buffers for the resulting strings. // Worst case scenario: all are 2 bytes (No wildcards) // size_t dataSize = Descriptor->Count * strlen("00 ") + 1; *Data = (char *)BridgeAlloc(dataSize); for (ULONG i = 0; i < Descriptor->Count; i++) { if (Descriptor->Entries[i].Wildcard == 0) { char temp[16]; sprintf_s(temp, "%02X ", (DWORD)Descriptor->Entries[i].Value); strcat_s(*Data, dataSize, temp); } else { strcat_s(*Data, dataSize, "? "); } } // Remove the final space if (strrchr(*Data, ' ')) *strrchr(*Data, ' ') = '\0'; }
SIG_DESCRIPTOR *AllocDescriptor(ULONG Count) { ULONG totalSize = sizeof(SIG_DESCRIPTOR) + (sizeof(SIG_DESCRIPTOR_ENTRY) * Count); SIG_DESCRIPTOR *temp = (SIG_DESCRIPTOR *)BridgeAlloc(totalSize); if (temp) temp->Count = Count; // Return value is gnored; BridgeAlloc will kill the program on failure return temp; }
FunctionPass::FunctionPass(duint VirtualStart, duint VirtualEnd, BBlockArray & MainBlocks) : AnalysisPass(VirtualStart, VirtualEnd, MainBlocks) { // Zero values m_FunctionInfo = nullptr; m_FunctionInfoSize = 0; // This will only be valid if the address range is within a loaded module m_ModuleStart = ModBaseFromAddr(VirtualStart); if(m_ModuleStart != 0) { char modulePath[MAX_PATH]; memset(modulePath, 0, sizeof(modulePath)); ModPathFromAddr(m_ModuleStart, modulePath, ARRAYSIZE(modulePath)); HANDLE fileHandle; DWORD fileSize; HANDLE fileMapHandle; ULONG_PTR fileMapVa; if(StaticFileLoadW( StringUtils::Utf8ToUtf16(modulePath).c_str(), UE_ACCESS_READ, false, &fileHandle, &fileSize, &fileMapHandle, &fileMapVa)) { // Find a pointer to IMAGE_DIRECTORY_ENTRY_EXCEPTION for later use ULONG_PTR virtualOffset = GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALOFFSET); m_FunctionInfoSize = (ULONG)GetPE32DataFromMappedFile(fileMapVa, IMAGE_DIRECTORY_ENTRY_EXCEPTION, UE_SECTIONVIRTUALSIZE); // Unload the file StaticFileUnloadW(nullptr, false, fileHandle, fileSize, fileMapHandle, fileMapVa); // Get a copy of the function table if(virtualOffset) { // Read the table into a buffer m_FunctionInfo = BridgeAlloc(m_FunctionInfoSize); if(m_FunctionInfo) MemRead(virtualOffset + m_ModuleStart, m_FunctionInfo, m_FunctionInfoSize); } } } }
void stackgetcallstack(duint csp, CALLSTACK* callstack) { std::vector<CALLSTACKENTRY> callstackVector; stackgetcallstack(csp, callstackVector, true); // Convert to a C data structure callstack->total = (int)callstackVector.size(); if(callstack->total > 0) { callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY)); // Copy data directly from the vector memcpy(callstack->entries, callstackVector.data(), callstack->total * sizeof(CALLSTACKENTRY)); } }
bool ExHandlerGetInfo(EX_HANDLER_TYPE Type, EX_HANDLER_INFO* Info) { std::vector<duint> handlerEntries; if(!ExHandlerGetInfo(Type, handlerEntries)) { Info->count = 0; Info->addresses = nullptr; return false; } // Convert vector to C-style array Info->count = (int)handlerEntries.size(); Info->addresses = (duint*)BridgeAlloc(Info->count * sizeof(duint)); memcpy(Info->addresses, handlerEntries.data(), Info->count * sizeof(duint)); return true; }
static DWORD WINAPI scriptLoadThread(void* filename) { GuiScriptClear(); GuiScriptEnableHighlighting(true); //enable default script syntax highlighting scriptIp = 0; std::vector<SCRIPTBP>().swap(scriptbplist); //clear breakpoints std::vector<int>().swap(scriptstack); //clear script stack bAbort = false; if(!scriptcreatelinemap((const char*)filename)) return 0; int lines = (int)linemap.size(); const char** script = (const char**)BridgeAlloc(lines * sizeof(const char*)); for(int i = 0; i < lines; i++) //add script lines script[i] = linemap.at(i).raw; GuiScriptAdd(lines, script); scriptIp = scriptinternalstep(0); GuiScriptSetIp(scriptIp); return 0; }
void SymUpdateModuleList() { // Build the vector of modules std::vector<SYMBOLMODULEINFO> modList; if(!SymGetModuleList(&modList)) { GuiSymbolUpdateModuleList(0, nullptr); return; } // Create a new array to be sent to the GUI thread size_t moduleCount = modList.size(); SYMBOLMODULEINFO* data = (SYMBOLMODULEINFO*)BridgeAlloc(moduleCount * sizeof(SYMBOLMODULEINFO)); // Direct copy from std::vector data memcpy(data, modList.data(), moduleCount * sizeof(SYMBOLMODULEINFO)); // Send the module data to the GUI for updating GuiSymbolUpdateModuleList((int)moduleCount, data); }
extern "C" DLL_EXPORT bool _dbg_memmap(MEMMAP* memmap) { SHARED_ACQUIRE(LockMemoryPages); int pagecount = (int)memoryPages.size(); memset(memmap, 0, sizeof(MEMMAP)); memmap->count = pagecount; if(!pagecount) return true; // Allocate memory that is already zeroed memmap->page = (MEMPAGE*)BridgeAlloc(sizeof(MEMPAGE) * pagecount); // Copy all elements over int i = 0; for(auto & itr : memoryPages) memcpy(&memmap->page[i++], &itr.second, sizeof(MEMPAGE)); // Done return true; }
void ThreadGetList(THREADLIST* List) { ASSERT_NONNULL(List); SHARED_ACQUIRE(LockThreads); // // This function converts a C++ std::unordered_map to a C-style THREADLIST[]. // Also assume BridgeAlloc zeros the returned buffer. // List->count = (int)threadList.size(); List->list = nullptr; if(List->count <= 0) return; // Allocate C-style array List->list = (THREADALLINFO*)BridgeAlloc(List->count * sizeof(THREADALLINFO)); // Fill out the list data int index = 0; for(auto & itr : threadList) { HANDLE threadHandle = itr.second.Handle; // Get the debugger's active thread index if(threadHandle == hActiveThread) List->CurrentThread = index; memcpy(&List->list[index].BasicInfo, &itr.second, sizeof(THREADINFO)); List->list[index].ThreadCip = GetContextDataEx(threadHandle, UE_CIP); List->list[index].SuspendCount = ThreadGetSuspendCount(threadHandle); List->list[index].Priority = ThreadGetPriority(threadHandle); List->list[index].WaitReason = ThreadGetWaitReason(threadHandle); List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase); index++; } }
bool ExHandlerGetInfo(EX_HANDLER_TYPE Type, EX_HANDLER_INFO* Info) { bool ret = false; std::vector<duint> handlerEntries; switch(Type) { case EX_HANDLER_SEH: ret = ExHandlerGetSEH(handlerEntries); break; case EX_HANDLER_VEH: ret = ExHandlerGetVEH(handlerEntries); break; case EX_HANDLER_VCH: ret = ExHandlerGetVCH(handlerEntries, false); break; case EX_HANDLER_UNHANDLED: ret = ExHandlerGetUnhandled(handlerEntries); break; } // Check if a call failed if(!ret) { Info->count = 0; Info->addresses = nullptr; return false; } // Convert vector to C-style array Info->count = (int)handlerEntries.size(); Info->addresses = (duint*)BridgeAlloc(Info->count * sizeof(duint)); memcpy(Info->addresses, handlerEntries.data(), Info->count * sizeof(duint)); return false; }
BRIDGE_IMPEXP bool BridgeSettingRead(int* errorLine) { if(errorLine) *errorLine = 0; bool success = false; std::string iniData; HANDLE hFile = CreateFileW(szIniFile, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if(hFile != INVALID_HANDLE_VALUE) { DWORD fileSize = GetFileSize(hFile, nullptr); if(fileSize) { unsigned char utf8bom[] = { 0xEF, 0xBB, 0xBF }; char* fileData = (char*)BridgeAlloc(sizeof(utf8bom) + fileSize + 1); DWORD read = 0; if(ReadFile(hFile, fileData, fileSize, &read, nullptr)) { success = true; if(!memcmp(fileData, utf8bom, sizeof(utf8bom))) iniData.assign(fileData + sizeof(utf8bom)); else iniData.assign(fileData); } BridgeFree(fileData); } CloseHandle(hFile); } if(success) //if we failed to read the file, the current settings are better than none at all { EnterCriticalSection(&csIni); int errline = 0; success = settings.Deserialize(iniData, errline); if(errorLine) *errorLine = errline; LeaveCriticalSection(&csIni); } return success; }
void MakeSigDialogExecute(HWND hwndDlg) { int dataLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT1)) + 1; int maskLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT2)) + 1; char *data = (char *)BridgeAlloc(dataLen); char *mask = (char *)BridgeAlloc(maskLen); GetWindowText(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT1), data, dataLen); GetWindowText(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT2), mask, maskLen); // // Convert the string to a code descriptor // SIG_DESCRIPTOR *desc = nullptr; switch (Settings::LastType) { case SIG_CODE: desc = DescriptorFromCode(data, mask); break; case SIG_IDA: desc = DescriptorFromIDA(data); break; case SIG_PEID: desc = DescriptorFromPEiD(data); break; case SIG_CRC: desc = DescriptorFromCRC(data); break; } // // Scan // std::vector<duint> results; PatternScan(desc, results); // // Log it in the GUI // GuiReferenceDeleteAllColumns(); GuiReferenceAddColumn(20, "Address"); GuiReferenceAddColumn(100, "Disassembly"); GuiReferenceSetRowCount((int)results.size()); GuiReferenceSetProgress(0); int i = 0; for (auto& match : results) { DISASM_INSTR inst; DbgDisasmAt(match, &inst); char temp[32]; sprintf_s(temp, "%p", (PVOID)match); GuiReferenceSetCellContent(i, 0, temp); GuiReferenceSetCellContent(i++, 1, inst.instruction); } _plugin_logprintf("Found %d references(s)\n", results.size()); GuiReferenceSetProgress(100); GuiUpdateAllViews(); // // Cleanup // BridgeFree(data); BridgeFree(mask); BridgeFree(desc); }
void MakeSigDialogConvert(HWND hwndDlg, SIGNATURE_TYPE To, SIGNATURE_TYPE From) { // // Don't convert if destination and source types are the same // if (To == From) return; int dataLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT1)) + 1; int maskLen = GetWindowTextLength(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT2)) + 1; char *data = (char *)BridgeAlloc(dataLen); char *mask = (char *)BridgeAlloc(maskLen); GetWindowText(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT1), data, dataLen); GetWindowText(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT2), mask, maskLen); // // Convert string(s) to the incoming raw code descriptor // SIG_DESCRIPTOR *inDesc = nullptr; switch (From) { case SIG_CODE: inDesc = DescriptorFromCode(data, mask); break; case SIG_IDA: inDesc = DescriptorFromIDA(data); break; case SIG_PEID: inDesc = DescriptorFromPEiD(data); break; case SIG_CRC: inDesc = DescriptorFromCRC(data); break; } // // Free temporary allocations // BridgeFree(data); BridgeFree(mask); data = nullptr; mask = nullptr; // // Convert raw code to destination strings // switch (To) { case SIG_CODE: DescriptorToCode(inDesc, &data, &mask); break; case SIG_IDA: DescriptorToIDA(inDesc, &data); break; case SIG_PEID: DescriptorToPEiD(inDesc, &data); break; case SIG_CRC: DescriptorToCRC(inDesc, &data, &mask); break; } // // Update dialog // SetWindowText(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT1), data ? data : ""); SetWindowText(GetDlgItem(hwndDlg, IDC_SIGMAKE_EDIT2), mask ? mask : ""); if (data) BridgeFree(data); if (mask) BridgeFree(mask); BridgeFree(inDesc); }
void stackgetcallstack(uint csp, CALLSTACK* callstack) { #if 1 callstack->total = 0; if(!DbgIsDebugging() || csp % sizeof(uint)) //alignment problem return; if(!MemIsValidReadPtr(csp)) return; std::vector<CALLSTACKENTRY> callstackVector; uint stacksize = 0; uint stackbase = MemFindBaseAddr(csp, &stacksize, false); if(!stackbase) //super-fail (invalid stack address) return; //walk up the stack uint i = csp; while(i != stackbase + stacksize) { uint data = 0; MemRead(i, &data, sizeof(uint)); if(MemIsValidReadPtr(data) && MemIsCodePage(data, false)) //the stack value is a pointer to an executable page { uint size = 0; uint base = MemFindBaseAddr(data, &size); uint readStart = data - 16 * 4; if(readStart < base) readStart = base; unsigned char disasmData[256]; MemRead(readStart, disasmData, sizeof(disasmData)); uint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1); uint previousInstr = readStart + prev; BASIC_INSTRUCTION_INFO basicinfo; bool valid = disasmfast(disasmData + prev, previousInstr, &basicinfo); if(valid && basicinfo.call) //call { CALLSTACKENTRY curEntry; memset(&curEntry, 0, sizeof(CALLSTACKENTRY)); StackEntryFromFrame(&curEntry, i, basicinfo.addr, data); callstackVector.push_back(curEntry); } } i += sizeof(uint); } callstack->total = (int)callstackVector.size(); if(callstack->total) { callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY)); for(int i = 0; i < callstack->total; i++) { //CALLSTACKENTRY curEntry; //memcpy(&curEntry, &callstackVector.at(i), sizeof(CALLSTACKENTRY)); //dprintf(fhex":" fhex ":" fhex ":%s\n", curEntry.addr, curEntry.to, curEntry.from, curEntry.comment); memcpy(&callstack->entries[i], &callstackVector.at(i), sizeof(CALLSTACKENTRY)); } } #else // Gather context data CONTEXT context; memset(&context, 0, sizeof(CONTEXT)); context.ContextFlags = CONTEXT_CONTROL | CONTEXT_INTEGER; if(SuspendThread(hActiveThread) == -1) return; if(!GetThreadContext(hActiveThread, &context)) return; if(ResumeThread(hActiveThread) == -1) return; // Set up all frame data STACKFRAME64 frame; ZeroMemory(&frame, sizeof(STACKFRAME64)); #ifdef _M_IX86 DWORD machineType = IMAGE_FILE_MACHINE_I386; frame.AddrPC.Offset = context.Eip; frame.AddrPC.Mode = AddrModeFlat; frame.AddrFrame.Offset = context.Ebp; frame.AddrFrame.Mode = AddrModeFlat; frame.AddrStack.Offset = csp; frame.AddrStack.Mode = AddrModeFlat; #elif _M_X64 DWORD machineType = IMAGE_FILE_MACHINE_AMD64; frame.AddrPC.Offset = context.Rip; frame.AddrPC.Mode = AddrModeFlat; frame.AddrFrame.Offset = context.Rsp; frame.AddrFrame.Mode = AddrModeFlat; frame.AddrStack.Offset = csp; frame.AddrStack.Mode = AddrModeFlat; #endif // Container for each callstack entry std::vector<CALLSTACKENTRY> callstackVector; while(true) { if(!StackWalk64( machineType, fdProcessInfo->hProcess, hActiveThread, &frame, &context, StackReadProcessMemoryProc64, SymFunctionTableAccess64, StackGetModuleBaseProc64, StackTranslateAddressProc64)) { // Maybe it failed, maybe we have finished walking the stack break; } if(frame.AddrPC.Offset != 0) { // Valid frame CALLSTACKENTRY entry; memset(&entry, 0, sizeof(CALLSTACKENTRY)); StackEntryFromFrame(&entry, (uint)frame.AddrFrame.Offset, (uint)frame.AddrReturn.Offset, (uint)frame.AddrPC.Offset); callstackVector.push_back(entry); } else { // Base reached break; } } // Convert to a C data structure callstack->total = (int)callstackVector.size(); if(callstack->total > 0) { callstack->entries = (CALLSTACKENTRY*)BridgeAlloc(callstack->total * sizeof(CALLSTACKENTRY)); // Copy data directly from the vector memcpy(callstack->entries, callstackVector.data(), callstack->total * sizeof(CALLSTACKENTRY)); } #endif }
extern "C" DLL_EXPORT int _dbg_getbplist(BPXTYPE type, BPMAP* bpmap) { if(!bpmap) return 0; std::vector<BREAKPOINT> list; int bpcount = BpGetList(&list); if(bpcount == 0) { bpmap->count = 0; return 0; } int retcount = 0; std::vector<BRIDGEBP> bridgeList; BRIDGEBP curBp; unsigned short slot = 0; for(int i = 0; i < bpcount; i++) { memset(&curBp, 0, sizeof(BRIDGEBP)); switch(type) { case bp_none: //all types break; case bp_normal: //normal if(list[i].type != BPNORMAL) continue; break; case bp_hardware: //hardware if(list[i].type != BPHARDWARE) continue; break; case bp_memory: //memory if(list[i].type != BPMEMORY) continue; break; default: return 0; } switch(list[i].type) { case BPNORMAL: curBp.type = bp_normal; break; case BPHARDWARE: curBp.type = bp_hardware; break; case BPMEMORY: curBp.type = bp_memory; break; } switch(((DWORD)list[i].titantype) >> 8) { case UE_DR0: slot = 0; break; case UE_DR1: slot = 1; break; case UE_DR2: slot = 2; break; case UE_DR3: slot = 3; break; } curBp.addr = list[i].addr; curBp.enabled = list[i].enabled; //TODO: fix this if(MemIsValidReadPtr(curBp.addr)) curBp.active = true; strcpy_s(curBp.mod, list[i].mod); strcpy_s(curBp.name, list[i].name); curBp.singleshoot = list[i].singleshoot; curBp.slot = slot; if(curBp.active) { bridgeList.push_back(curBp); retcount++; } } if(!retcount) { bpmap->count = retcount; return retcount; } bpmap->count = retcount; bpmap->bp = (BRIDGEBP*)BridgeAlloc(sizeof(BRIDGEBP) * retcount); for(int i = 0; i < retcount; i++) memcpy(&bpmap->bp[i], &bridgeList.at(i), sizeof(BRIDGEBP)); return retcount; }