BRIDGE_IMPEXP bool DbgGetBookmarkAt(duint addr) { if(!addr) return false; ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flagbookmark; if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) return false; return info.isbookmark; }
// FIXME required size of arg _text_? BRIDGE_IMPEXP bool DbgGetModuleAt(duint addr, char* text) { if(!text || !addr) return false; ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flagmodule; if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) return false; strcpy_s(text, MAX_MODULE_SIZE, info.module); return true; }
// FIXME required size of arg _text_? BRIDGE_IMPEXP bool DbgGetCommentAt(duint addr, char* text) //comment (not live) { if(!text || !addr) return false; ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flagcomment; if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) return false; strcpy_s(text, MAX_COMMENT_SIZE, info.comment); return true; }
// FIXME required size of arg _text_? BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(module.)+label { if(!text || !addr) return false; ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flaglabel; if(!_dbg_addrinfoget(addr, segment, &info)) { duint addr_ = 0; if(!DbgMemIsValidReadPtr(addr)) return false; DbgMemRead(addr, (unsigned char*)&addr_, sizeof(duint)); ADDRINFO ptrinfo = info; if(!_dbg_addrinfoget(addr_, SEG_DEFAULT, &ptrinfo)) return false; sprintf_s(info.label, "&%s", ptrinfo.label); } strcpy_s(text, MAX_LABEL_SIZE, info.label); return true; }
void StackEntryFromFrame(CALLSTACKENTRY* Entry, uint Address, uint From, uint To) { Entry->addr = Address; Entry->from = From; Entry->to = To; char label[MAX_LABEL_SIZE] = ""; ADDRINFO addrinfo; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(Entry->to, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); char module[MAX_MODULE_SIZE] = ""; ModNameFromAddr(Entry->to, module, false); char returnToAddr[MAX_COMMENT_SIZE] = ""; if(*module) sprintf(returnToAddr, "%s.", module); if(!*label) sprintf(label, fhex, Entry->to); strcat(returnToAddr, label); if(Entry->from) { *label = 0; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(Entry->from, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); *module = 0; ModNameFromAddr(Entry->from, module, false); char returnFromAddr[MAX_COMMENT_SIZE] = ""; if(*module) sprintf(returnFromAddr, "%s.", module); if(!*label) sprintf(label, fhex, Entry->from); strcat(returnFromAddr, label); sprintf_s(Entry->comment, "return to %s from %s", returnToAddr, returnFromAddr); } else sprintf_s(Entry->comment, "return to %s from ???", returnToAddr); }
// FIXME depth BRIDGE_IMPEXP LOOPTYPE DbgGetLoopTypeAt(duint addr, int depth) { ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flagloop; info.loop.depth = depth; if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) return LOOP_NONE; duint start = info.loop.start; duint end = info.loop.end; if(addr == start) return LOOP_BEGIN; else if(addr == end) return LOOP_END; return LOOP_MIDDLE; }
BRIDGE_IMPEXP FUNCTYPE DbgGetFunctionTypeAt(duint addr) { ADDRINFO info; memset(&info, 0, sizeof(info)); info.flags = flagfunction; if(!_dbg_addrinfoget(addr, SEG_DEFAULT, &info)) return FUNC_NONE; duint start = info.function.start; duint end = info.function.end; if(start == end) return FUNC_SINGLE; else if(addr == start) return FUNC_BEGIN; else if(addr == end) return FUNC_END; return FUNC_MIDDLE; }
bool stackcommentget(duint addr, STACK_COMMENT* comment) { SHARED_ACQUIRE(LockSehCache); const auto found = SehCache.find(addr); if(found != SehCache.end()) { *comment = found->second; return true; } SHARED_RELEASE(); duint data = 0; memset(comment, 0, sizeof(STACK_COMMENT)); MemRead(addr, &data, sizeof(duint)); if(!MemIsValidReadPtr(data)) //the stack value is no pointer return false; duint size = 0; duint base = MemFindBaseAddr(data, &size); duint readStart = data - 16 * 4; if(readStart < base) readStart = base; unsigned char disasmData[256]; MemRead(readStart, disasmData, sizeof(disasmData)); duint prev = disasmback(disasmData, 0, sizeof(disasmData), data - readStart, 1); duint previousInstr = readStart + prev; BASIC_INSTRUCTION_INFO basicinfo; bool valid = disasmfast(disasmData + prev, previousInstr, &basicinfo); if(valid && basicinfo.call) //call { char label[MAX_LABEL_SIZE] = ""; ADDRINFO addrinfo; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); char module[MAX_MODULE_SIZE] = ""; ModNameFromAddr(data, module, false); char returnToAddr[MAX_COMMENT_SIZE] = ""; if(*module) sprintf(returnToAddr, "%s.", module); if(!*label) sprintf_s(label, "%p", data); strcat(returnToAddr, label); data = basicinfo.addr; if(data) { *label = 0; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); *module = 0; ModNameFromAddr(data, module, false); char returnFromAddr[MAX_COMMENT_SIZE] = ""; if(*module) sprintf_s(returnFromAddr, "%s.", module); if(!*label) sprintf_s(label, "%p", data); strcat_s(returnFromAddr, label); sprintf_s(comment->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from %s")), returnToAddr, returnFromAddr); } else sprintf_s(comment->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from ???")), returnToAddr); strcpy_s(comment->color, "!rtnclr"); // Special token for return address color; return true; } //string char string[MAX_STRING_SIZE] = ""; if(DbgGetStringAt(data, string)) { strncpy_s(comment->comment, string, _TRUNCATE); return true; } //label char label[MAX_LABEL_SIZE] = ""; ADDRINFO addrinfo; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); char module[MAX_MODULE_SIZE] = ""; ModNameFromAddr(data, module, false); if(*module) //module { if(*label) //+label sprintf_s(comment->comment, "%s.%s", module, label); else //module only sprintf_s(comment->comment, "%s.%p", module, data); return true; } else if(*label) //label only { sprintf_s(comment->comment, "<%s>", label); return true; } return false; }
bool stackcommentget(uint addr, STACK_COMMENT* comment) { uint data = 0; memset(comment, 0, sizeof(STACK_COMMENT)); MemRead(addr, &data, sizeof(uint)); if(!MemIsValidReadPtr(data)) //the stack value is no pointer return false; 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 { char label[MAX_LABEL_SIZE] = ""; ADDRINFO addrinfo; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); char module[MAX_MODULE_SIZE] = ""; ModNameFromAddr(data, module, false); char returnToAddr[MAX_COMMENT_SIZE] = ""; if(*module) sprintf(returnToAddr, "%s.", module); if(!*label) sprintf(label, fhex, data); strcat(returnToAddr, label); data = basicinfo.addr; if(data) { *label = 0; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); *module = 0; ModNameFromAddr(data, module, false); char returnFromAddr[MAX_COMMENT_SIZE] = ""; if(*module) sprintf(returnFromAddr, "%s.", module); if(!*label) sprintf(label, fhex, data); strcat_s(returnFromAddr, label); sprintf_s(comment->comment, "return to %s from %s", returnToAddr, returnFromAddr); } else sprintf_s(comment->comment, "return to %s from ???", returnToAddr); strcpy_s(comment->color, "#ff0000"); return true; } //string STRING_TYPE strtype; char string[512] = ""; if(disasmgetstringat(data, &strtype, string, string, 500)) { if(strtype == str_ascii) sprintf(comment->comment, "\"%s\"", string); else //unicode sprintf(comment->comment, "L\"%s\"", string); return true; } //label char label[MAX_LABEL_SIZE] = ""; ADDRINFO addrinfo; addrinfo.flags = flaglabel; if(_dbg_addrinfoget(data, SEG_DEFAULT, &addrinfo)) strcpy_s(label, addrinfo.label); char module[MAX_MODULE_SIZE] = ""; ModNameFromAddr(data, module, false); if(*module) //module { if(*label) //+label sprintf(comment->comment, "%s.%s", module, label); else //module only sprintf(comment->comment, "%s." fhex, module, data); return true; } else if(*label) //label only { sprintf(comment->comment, "<%s>", label); return true; } return false; }
extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDRINFO* addrinfo) { if(!DbgIsDebugging()) return false; bool retval = false; if(addrinfo->flags & flagmodule) //get module { if(ModNameFromAddr(addr, addrinfo->module, false)) //get module name retval = true; } if(addrinfo->flags & flaglabel) { if(LabelGet(addr, addrinfo->label)) retval = true; else //no user labels { DWORD64 displacement = 0; char buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); pSymbol->MaxNameLen = MAX_LABEL_SIZE; if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) && !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) strcpy_s(addrinfo->label, pSymbol->Name); retval = true; } if(!retval) //search for CALL <jmp.&user32.MessageBoxA> { BASIC_INSTRUCTION_INFO basicinfo; memset(&basicinfo, 0, sizeof(BASIC_INSTRUCTION_INFO)); if(disasmfast(addr, &basicinfo) && basicinfo.branch && !basicinfo.call && basicinfo.memory.value) //thing is a JMP { uint val = 0; if(MemRead(basicinfo.memory.value, &val, sizeof(val))) { if(SafeSymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) && !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; if(!bUndecorateSymbolNames || !SafeUnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name); retval = true; } } } } if(!retval) //search for module entry { uint entry = ModEntryFromAddr(addr); if(entry && entry == addr) { strcpy_s(addrinfo->label, "EntryPoint"); retval = true; } } } } if(addrinfo->flags & flagbookmark) { addrinfo->isbookmark = BookmarkGet(addr); retval = true; } if(addrinfo->flags & flagfunction) { if(FunctionGet(addr, &addrinfo->function.start, &addrinfo->function.end)) retval = true; } if(addrinfo->flags & flagloop) { if(LoopGet(addrinfo->loop.depth, addr, &addrinfo->loop.start, &addrinfo->loop.end)) retval = true; } if(addrinfo->flags & flagcomment) { *addrinfo->comment = 0; if(CommentGet(addr, addrinfo->comment)) retval = true; else { DWORD dwDisplacement; IMAGEHLP_LINE64 line; line.SizeOfStruct = sizeof(IMAGEHLP_LINE64); if(SafeSymGetLineFromAddr64(fdProcessInfo->hProcess, (DWORD64)addr, &dwDisplacement, &line) && !dwDisplacement) { char filename[deflen] = ""; strcpy_s(filename, line.FileName); int len = (int)strlen(filename); while(filename[len] != '\\' && len != 0) len--; if(len) len++; sprintf_s(addrinfo->comment, "\1%s:%u", filename + len, line.LineNumber); retval = true; } else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number { DISASM_INSTR instr; String temp_string; String comment; ADDRINFO newinfo; char ascii[256 * 2] = ""; char unicode[256 * 2] = ""; memset(&instr, 0, sizeof(DISASM_INSTR)); disasmget(addr, &instr); int len_left = MAX_COMMENT_SIZE; for(int i = 0; i < instr.argcount; i++) { memset(&newinfo, 0, sizeof(ADDRINFO)); newinfo.flags = flaglabel; STRING_TYPE strtype = str_none; if(instr.arg[i].constant == instr.arg[i].value) //avoid: call <module.label> ; addr:label { if(instr.type == instr_branch || !disasmgetstringat(instr.arg[i].constant, &strtype, ascii, unicode, len_left) || strtype == str_none) continue; switch(strtype) { case str_none: break; case str_ascii: temp_string = instr.arg[i].mnemonic; temp_string.append(":\""); temp_string.append(ascii); temp_string.append("\""); break; case str_unicode: temp_string = instr.arg[i].mnemonic; temp_string.append(":L\""); temp_string.append(unicode); temp_string.append("\""); break; } } else if(instr.arg[i].memvalue && (disasmgetstringat(instr.arg[i].memvalue, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].memvalue, instr.arg[i].segment, &newinfo))) { switch(strtype) { case str_none: if(*newinfo.label) { temp_string = "["; temp_string.append(instr.arg[i].mnemonic); temp_string.append("]:"); temp_string.append(newinfo.label); } break; case str_ascii: temp_string = "["; temp_string.append(instr.arg[i].mnemonic); temp_string.append("]:"); temp_string.append(ascii); break; case str_unicode: temp_string = "["; temp_string.append(instr.arg[i].mnemonic); temp_string.append("]:"); temp_string.append(unicode); break; } } else if(instr.arg[i].value && (disasmgetstringat(instr.arg[i].value, &strtype, ascii, unicode, len_left) || _dbg_addrinfoget(instr.arg[i].value, instr.arg[i].segment, &newinfo))) { if(instr.type != instr_normal) //stack/jumps (eg add esp,4 or jmp 401110) cannot directly point to strings strtype = str_none; switch(strtype) { case str_none: if(*newinfo.label) { temp_string = instr.arg[i].mnemonic; temp_string.append(":"); temp_string.append(newinfo.label); } break; case str_ascii: temp_string = instr.arg[i].mnemonic; temp_string.append(":\""); temp_string.append(ascii); temp_string.append("\""); break; case str_unicode: temp_string = instr.arg[i].mnemonic; temp_string.append(":L\""); temp_string.append(unicode); temp_string.append("\""); break; } } else continue; if(!strstr(comment.c_str(), temp_string.c_str())) { if(comment.length()) comment.append(", "); comment.append(temp_string); retval = true; } } comment.resize(MAX_COMMENT_SIZE - 2); String fullComment = "\1"; fullComment += comment; strcpy_s(addrinfo->comment, fullComment.c_str()); } } } return retval; }