1
0
Fork 0

decode function offset in stack (#1243)

* decode function offset in stack

* fix issue 1242

* remove untranslatable thing
This commit is contained in:
Torusrxxx 2016-11-14 07:25:11 +00:00 committed by Duncan Ogilvie
parent 430e59ef74
commit c1f15b2794
10 changed files with 91 additions and 80 deletions

View File

@ -332,7 +332,7 @@ BRIDGE_IMPEXP bool DbgGetLabelAt(duint addr, SEGMENTREG segment, char* text) //(
return false;
ADDRINFO info;
memset(&info, 0, sizeof(info));
info.flags = flaglabel;
info.flags = flaglabel | flagNoFuncOffset;
if(!_dbg_addrinfoget(addr, segment, &info))
{
duint addr_ = 0;

View File

@ -107,13 +107,14 @@ typedef enum
typedef enum
{
flagmodule = 1,
flaglabel = 2,
flagcomment = 4,
flagbookmark = 8,
flagfunction = 16,
flagloop = 32,
flagargs = 64
flagmodule = 0x1,
flaglabel = 0x2,
flagcomment = 0x4,
flagbookmark = 0x8,
flagfunction = 0x10,
flagloop = 0x20,
flagargs = 0x40,
flagNoFuncOffset = 0x80
} ADDRINFOFLAGS;
typedef enum

View File

@ -117,11 +117,12 @@ static bool shouldFilterSymbol(const char* name)
return filterInfo.retval;
}
static bool getLabel(duint addr, char* label)
static bool getLabel(duint addr, char* label, bool noFuncOffset)
{
bool retval = false;
label[0] = 0;
if(LabelGet(addr, label))
retval = true;
return true;
else //no user labels
{
DWORD64 displacement = 0;
@ -157,24 +158,35 @@ static bool getLabel(duint addr, char* label)
}
if(!retval) //search for module entry
{
duint entry = ModEntryFromAddr(addr);
if(entry && entry == addr)
if(addr != 0 && ModEntryFromAddr(addr) == addr)
{
strcpy_s(label, MAX_LABEL_SIZE, "EntryPoint");
retval = true;
return true;
}
}
if(!retval) //search for function+offset
{
duint start;
if(FunctionGet(addr, &start, nullptr) && addr == start)
if(FunctionGet(addr, &start, nullptr))
{
duint rva = addr - start;
if(rva == 0)
{
#ifdef _WIN64
sprintf_s(label, MAX_LABEL_SIZE, "sub_%llX", start);
sprintf_s(label, MAX_LABEL_SIZE, "sub_%llX", start);
#else //x86
sprintf_s(label, MAX_LABEL_SIZE, "sub_%X", start);
sprintf_s(label, MAX_LABEL_SIZE, "sub_%X", start);
#endif //_WIN64
retval = true;
return true;
}
if(noFuncOffset)
return false;
getLabel(start, label, false);
char temp[32];
#ifdef _WIN64
sprintf_s(temp, "+%llX", rva);
#else //x86
sprintf_s(temp, "+%X", rva);
#endif //_WIN64
strcat_s(label, MAX_LABEL_SIZE, temp);
return true;
}
}
}
@ -193,7 +205,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR
}
if(addrinfo->flags & flaglabel)
{
retval = getLabel(addr, addrinfo->label);
retval = getLabel(addr, addrinfo->label, (addrinfo->flags & flagNoFuncOffset) != 0);
}
if(addrinfo->flags & flagbookmark)
{

View File

@ -382,8 +382,15 @@ bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedP
return SUCCEEDED(hres);
}
void WaitForThreadTermination(HANDLE hThread)
void WaitForThreadTermination(HANDLE hThread, DWORD timeout)
{
WaitForSingleObject(hThread, INFINITE);
WaitForSingleObject(hThread, timeout);
CloseHandle(hThread);
}
void WaitForMultipleThreadsTermination(const HANDLE* hThread, int count, DWORD timeout)
{
WaitForMultipleObjects(count, hThread, TRUE, timeout);
for(int i = 0; i < count; i++)
CloseHandle(hThread[i]);
}

View File

@ -87,7 +87,8 @@ bool settingboolget(const char* section, const char* name);
arch GetFileArchitecture(const char* szFileName);
bool IsWow64();
bool ResolveShortcut(HWND hwnd, const wchar_t* szShortcutPath, char* szResolvedPath, size_t nSize);
void WaitForThreadTermination(HANDLE hThread);
void WaitForThreadTermination(HANDLE hThread, DWORD timeout = INFINITE);
void WaitForMultipleThreadsTermination(const HANDLE* hThread, int count, DWORD timeout = INFINITE);
#include "dynamicmem.h"

View File

@ -344,9 +344,8 @@ void dbgstop()
bStopTimeWastedCounterThread = true;
bStopMemMapThread = true;
bStopDumpRefreshThread = true;
WaitForThreadTermination(hTimeWastedCounterThread);
WaitForThreadTermination(hMemMapThread);
WaitForThreadTermination(hDumpRefreshThread);
HANDLE hThreads[] = { hTimeWastedCounterThread, hMemMapThread, hDumpRefreshThread };
WaitForMultipleThreadsTermination(hThreads, _countof(hThreads), 10000); // Total time out is 10 seconds.
}
duint dbgdebuggedbase()

View File

@ -239,7 +239,10 @@ bool ModNameFromAddr(duint Address, char* Name, bool Extension)
auto module = ModInfoFromAddr(Address);
if(!module)
{
Name[0] = '\0';
return false;
}
// Copy initial module name
strcpy_s(Name, MAX_MODULE_SIZE, module->name);

View File

@ -40,6 +40,23 @@ void stackupdateseh()
SehCache = std::move(newcache);
}
static void getSymAddrName(duint addr, char* str)
{
ADDRINFO addrinfo;
if(addr == 0)
{
memcpy(str, "???", 4);
return;
}
addrinfo.flags = flaglabel | flagmodule;
_dbg_addrinfoget(addr, SEG_DEFAULT, &addrinfo);
if(addrinfo.module[0] != '\0')
sprintf_s(str, MAX_COMMENT_SIZE, "%s.", addrinfo.module);
if(addrinfo.label[0] == '\0')
sprintf_s(addrinfo.label, MAX_COMMENT_SIZE, "%p", addr);
strcat_s(str, MAX_COMMENT_SIZE, addrinfo.label);
}
bool stackcommentget(duint addr, STACK_COMMENT* comment)
{
SHARED_ACQUIRE(LockSehCache);
@ -71,39 +88,13 @@ bool stackcommentget(duint addr, STACK_COMMENT* comment)
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);
getSymAddrName(data, returnToAddr);
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);
char returnFromAddr[MAX_COMMENT_SIZE] = "";
getSymAddrName(data, returnFromAddr);
sprintf_s(comment->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from %s")), returnToAddr, returnFromAddr);
strcpy_s(comment->color, "!rtnclr"); // Special token for return address color;
return true;
}
@ -175,21 +166,11 @@ void StackEntryFromFrame(CALLSTACKENTRY* Entry, duint Address, duint From, duint
Entry->from = From;
Entry->to = To;
auto getSymAddrName = [](duint addr)
{
auto symname = SymGetSymbolicName(addr);
if(!symname.length())
symname = StringUtils::sprintf("%p", addr);
return symname;
};
char returnToAddr[MAX_COMMENT_SIZE] = "";
strncpy_s(returnToAddr, getSymAddrName(Entry->to).c_str(), _TRUNCATE);
if(Entry->from)
sprintf_s(Entry->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from %s")), returnToAddr, getSymAddrName(Entry->from).c_str());
else
sprintf_s(Entry->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from ???")), returnToAddr);
getSymAddrName(To, returnToAddr);
char returnFromAddr[MAX_COMMENT_SIZE] = "";
getSymAddrName(From, returnFromAddr);
sprintf_s(Entry->comment, GuiTranslateText(QT_TRANSLATE_NOOP("DBG", "return to %s from %s")), returnToAddr, returnFromAddr);
}
#define MAX_CALLSTACK_CACHE 20

View File

@ -729,7 +729,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal()
dputs(QT_TRANSLATE_NOOP("DBG", "Stopping command thread..."));
bStopCommandLoopThread = true;
MsgFreeStack(gMsgStack);
WaitForThreadTermination(hCommandLoopThread);
WaitForThreadTermination(hCommandLoopThread, 10000);
dputs(QT_TRANSLATE_NOOP("DBG", "Cleaning up allocated data..."));
cmdfree();
varfree();

View File

@ -2499,7 +2499,8 @@ void RegistersView::displayEditDialog()
mLineEdit.setWindowTitle(tr("Edit FPU register"));
mLineEdit.setWindowIcon(DIcon("log.png"));
mLineEdit.setCursorPosition(0);
mLineEdit.ForceSize(GetSizeRegister(mSelected) * 2);
size_t sizeRegister = GetSizeRegister(mSelected);
mLineEdit.ForceSize(sizeRegister * 2);
do
{
errorinput = false;
@ -2516,22 +2517,20 @@ void RegistersView::displayEditDialog()
fpuvalue = (duint) mLineEdit.editText.toUShort(&ok, 16);
else if(mDWORDDISPLAY.contains(mSelected))
fpuvalue = mLineEdit.editText.toUInt(&ok, 16);
else if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected))
else if(mFPUx87_80BITSDISPLAY.contains(mSelected))
{
QByteArray pArray = mLineEdit.editText.toLocal8Bit();
if(!ConfigBool("Gui", "FpuRegistersLittleEndian"))
pArray = ByteReverse(pArray);
if(pArray.size() == GetSizeRegister(mSelected) * 2)
if(pArray.size() == sizeRegister * 2)
{
char* pData = (char*) calloc(1, sizeof(char) * GetSizeRegister(mSelected));
char* pData = (char*) calloc(1, sizeof(char) * sizeRegister);
if(pData != NULL)
{
ok = true;
char actual_char[3];
unsigned int i;
for(i = 0; i < GetSizeRegister(mSelected); i++)
for(i = 0; i < sizeRegister; i++)
{
memset(actual_char, 0, sizeof(actual_char));
memcpy(actual_char, (char*) pArray.data() + (i * 2), 2);
@ -2544,7 +2543,15 @@ void RegistersView::displayEditDialog()
}
if(ok)
setRegister(mSelected, (duint) pData);
{
if(!ConfigBool("Gui", "FpuRegistersLittleEndian")) // reverse byte order if it is big-endian
{
pArray = ByteReverse(QByteArray(pData, sizeRegister));
setRegister(mSelected, reinterpret_cast<duint>(pArray.constData()));
}
else
setRegister(mSelected, reinterpret_cast<duint>(pData));
}
free(pData);