1
0
Fork 0

Add undocumented LabelRuntimeFunctions command

This commit is contained in:
Duncan Ogilvie 2020-11-11 23:38:58 +01:00
parent 9f9b1ba1c0
commit a49d32cca8
7 changed files with 97 additions and 13 deletions

View File

@ -90,6 +90,25 @@ bool cbInstrAnalrecur(int argc, char* argv[])
duint entry;
if(!valfromstring(argv[1], &entry, false))
return false;
#ifdef _WIN64
// find the closest function
{
SHARED_ACQUIRE(LockModules);
auto info = ModInfoFromAddr(entry);
if(info)
{
DWORD rva = DWORD(entry - info->base);
auto runtimeFunction = info->findRuntimeFunction(rva);
if(runtimeFunction)
{
if(runtimeFunction->BeginAddress < rva)
{
entry = info->base + runtimeFunction->BeginAddress;
}
}
}
}
#endif // _WIN64
duint size;
auto base = MemFindBaseAddr(entry, &size);
if(!base)

View File

@ -534,3 +534,54 @@ bool cbInstrDebugFlags(int argc, char* argv[])
dprintf_untranslated("DebugFlags = 0x%08X\n", debugFlags);
return true;
}
bool cbInstrLabelRuntimeFunctions(int argc, char* argv[])
{
#ifdef _WIN64
if(argc < 2)
{
dputs_untranslated("Usage: LabelRuntimeFunctions modaddr");
return false;
}
auto modaddr = DbgValFromString(argv[1]);
SHARED_ACQUIRE(LockModules);
auto info = ModInfoFromAddr(modaddr);
if(info)
{
std::vector<COMMENTSINFO> comments;
CommentGetList(comments);
for(const auto & comment : comments)
{
if(comment.modhash == info->hash)
{
if(!comment.manual && comment.text.find("RUNTIME_FUNCTION") == 0)
{
CommentDelete(comment.addr + info->base);
}
}
}
for(const auto & runtimeFunction : info->runtimeFunctions)
{
auto setComment = [info](duint addr, const char* prefix)
{
char comment[MAX_COMMENT_SIZE] = "";
if(!CommentGet(addr, comment))
strncpy_s(comment, "RUNTIME_FUNCTION", _TRUNCATE);
strncat_s(comment, " ", _TRUNCATE);
strncat_s(comment, prefix, _TRUNCATE);
CommentSet(addr, comment, false);
};
setComment(info->base + runtimeFunction.BeginAddress, "BeginAddress");
setComment(info->base + runtimeFunction.EndAddress, "EndAddress");
}
GuiUpdateAllViews();
}
else
{
dprintf_untranslated("No module found at %p\n", modaddr);
}
return true;
#else
return false;
#endif // _WIN64
}

View File

@ -15,4 +15,5 @@ bool cbInstrFocusinfo(int argc, char* argv[]);
bool cbInstrFlushlog(int argc, char* argv[]);
bool cbInstrAnimateWait(int argc, char* argv[]);
bool cbInstrDbdecompress(int argc, char* argv[]);
bool cbInstrDebugFlags(int argc, char* argv[]);
bool cbInstrDebugFlags(int argc, char* argv[]);
bool cbInstrLabelRuntimeFunctions(int argc, char* argv[]);

View File

@ -1231,6 +1231,19 @@ bool ModRelocationsInRange(duint Address, duint Size, std::vector<MODRELOCATIONI
return !Relocations.empty();
}
const RUNTIME_FUNCTION* MODINFO::findRuntimeFunction(DWORD rva) const
{
const auto found = std::lower_bound(runtimeFunctions.cbegin(), runtimeFunctions.cend(), rva, [](const RUNTIME_FUNCTION & a, const DWORD & rva)
{
return a.EndAddress <= rva;
});
if(found != runtimeFunctions.cend() && rva >= found->BeginAddress)
return &*found;
return nullptr;
}
bool MODINFO::loadSymbols(const String & pdbPath, bool forceLoad)
{
unloadSymbols();

View File

@ -92,6 +92,8 @@ struct MODINFO
std::vector<duint> tlsCallbacks;
#if _WIN64
std::vector<RUNTIME_FUNCTION> runtimeFunctions; //sorted by (begin, end)
const RUNTIME_FUNCTION* findRuntimeFunction(DWORD rva) const;
#endif // _WIN64
MODEXPORT entrySymbol;

View File

@ -158,20 +158,17 @@ static PVOID CALLBACK StackSymFunctionTableAccess64(HANDLE hProcess, DWORD64 Add
#ifdef _WIN64
// https://github.com/dotnet/coreclr/blob/master/src/unwinder/amd64/dbs_stack_x64.cpp
MODINFO* info = ModInfoFromAddr(AddrBase);
if(!info)
return nullptr;
DWORD rva = DWORD(AddrBase - info->base);
auto found = std::lower_bound(info->runtimeFunctions.begin(), info->runtimeFunctions.end(), rva, [](const RUNTIME_FUNCTION & a, const DWORD & rva)
if(info)
{
return a.EndAddress <= rva;
});
if(found != info->runtimeFunctions.end() && rva >= found->BeginAddress)
return &found->BeginAddress;
#endif // _WIN64
return (PVOID)info->findRuntimeFunction(DWORD(AddrBase - info->base));
}
else
{
return nullptr;
}
#else
return SymFunctionTableAccess64(hProcess, AddrBase);
#endif // _WIN64
}
static DWORD64 CALLBACK StackGetModuleBaseProc64(HANDLE hProcess, DWORD64 Address)

View File

@ -447,6 +447,7 @@ static void registercommands()
dbgcmdnew("AnimateWait", cbInstrAnimateWait, true); //Wait for the debuggee to pause.
dbgcmdnew("dbdecompress", cbInstrDbdecompress, false); //Decompress a database.
dbgcmdnew("DebugFlags", cbInstrDebugFlags, false); //Set ntdll LdrpDebugFlags
dbgcmdnew("LabelRuntimeFunctions", cbInstrLabelRuntimeFunctions, true); //Label exception directory entries
};
bool cbCommandProvider(char* cmd, int maxlen)