Compare commits
17 Commits
b86405e029
...
17621d845c
Author | SHA1 | Date |
---|---|---|
Duncan Ogilvie | 17621d845c | |
Duncan Ogilvie | ea631d4539 | |
Duncan Ogilvie | dd76320156 | |
Bluefissure | 4c713b08f4 | |
Bluefissure | 956072ad02 | |
Duncan Ogilvie | 6575efc266 | |
Duncan Ogilvie | f62323765d | |
Duncan Ogilvie | 8cd3e1df5a | |
pitticus | 3b8f95adfa | |
pitticus | 8f06703061 | |
pitticus | 4d725925d0 | |
Michael Maltsev | 1515a5a5fc | |
torusrxxx | ec86ad10d3 | |
Duncan Ogilvie | de494c1fc7 | |
Duncan Ogilvie | 4451b33515 | |
torusrxxx | 2240fbd223 | |
torusrxxx | 415ee4235b |
|
@ -1361,6 +1361,21 @@ BRIDGE_IMPEXP void GuiLogClear()
|
|||
_gui_sendmessage(GUI_CLEAR_LOG, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiLogSave(const char* filename)
|
||||
{
|
||||
_gui_sendmessage(GUI_SAVE_LOG, (void*)filename, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiLogRedirect(const char* filename)
|
||||
{
|
||||
_gui_sendmessage(GUI_REDIRECT_LOG, (void*)filename, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiLogRedirectStop()
|
||||
{
|
||||
_gui_sendmessage(GUI_STOP_REDIRECT_LOG, 0, 0);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP void GuiUpdateEnable(bool updateNow)
|
||||
{
|
||||
bDisableGUIUpdate = false;
|
||||
|
@ -1997,6 +2012,11 @@ BRIDGE_IMPEXP DWORD GuiGetMainThreadId()
|
|||
return (DWORD)(duint)_gui_sendmessage(GUI_GET_MAIN_THREAD_ID, nullptr, nullptr);
|
||||
}
|
||||
|
||||
BRIDGE_IMPEXP bool GuiIsDebuggerFocused()
|
||||
{
|
||||
return (bool)(duint)_gui_sendmessage(GUI_IS_DEBUGGER_FOCUSED, nullptr, nullptr);
|
||||
}
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
|
||||
{
|
||||
hInst = hinstDLL;
|
||||
|
|
|
@ -1126,6 +1126,7 @@ BRIDGE_IMPEXP void DbgGetSymbolInfo(const SYMBOLPTR* symbolptr, SYMBOLINFO* info
|
|||
BRIDGE_IMPEXP DEBUG_ENGINE DbgGetDebugEngine();
|
||||
BRIDGE_IMPEXP bool DbgGetSymbolInfoAt(duint addr, SYMBOLINFO* info);
|
||||
BRIDGE_IMPEXP duint DbgXrefAddMulti(const XREF_EDGE* edges, duint count);
|
||||
BRIDGE_IMPEXP bool GuiIsDebuggerFocused();
|
||||
|
||||
//Gui defines
|
||||
typedef enum
|
||||
|
@ -1274,6 +1275,10 @@ typedef enum
|
|||
GUI_GET_MAIN_THREAD_ID, // param1=unused, param2=unused
|
||||
GUI_ADD_MSG_TO_LOG_HTML, // param1=(const char*)msg, param2=unused
|
||||
GUI_IS_LOG_ENABLED, // param1=unused, param2=unused
|
||||
GUI_IS_DEBUGGER_FOCUSED, // param1=unused, param2=unused
|
||||
GUI_SAVE_LOG, // param1=const char* file name,param2=unused
|
||||
GUI_REDIRECT_LOG, // param1=const char* file name,param2=unused
|
||||
GUI_STOP_REDIRECT_LOG, // param1=unused, param2=unused
|
||||
} GUIMSG;
|
||||
|
||||
//GUI Typedefs
|
||||
|
@ -1343,6 +1348,9 @@ BRIDGE_IMPEXP void GuiSetDebugStateFast(DBGSTATE state);
|
|||
BRIDGE_IMPEXP void GuiAddLogMessage(const char* msg);
|
||||
BRIDGE_IMPEXP void GuiAddLogMessageHtml(const char* msg);
|
||||
BRIDGE_IMPEXP void GuiLogClear();
|
||||
BRIDGE_IMPEXP void GuiLogSave(const char* filename);
|
||||
BRIDGE_IMPEXP void GuiLogRedirect(const char* filename);
|
||||
BRIDGE_IMPEXP void GuiLogRedirectStop();
|
||||
BRIDGE_IMPEXP void GuiUpdateAllViews();
|
||||
BRIDGE_IMPEXP void GuiUpdateRegisterView();
|
||||
BRIDGE_IMPEXP void GuiUpdateDisassemblyView();
|
||||
|
|
|
@ -27,6 +27,10 @@ downslib_error downslib_download(const char* url,
|
|||
HINTERNET hInternet = nullptr;
|
||||
HINTERNET hUrl = nullptr;
|
||||
HANDLE hFile = nullptr;
|
||||
DWORD dwBufferSize = 0;
|
||||
const char* headers = nullptr;
|
||||
DWORD dwHeaderslen = 0;
|
||||
const DWORD chunk_size = 8192;
|
||||
|
||||
Cleanup cleanup([&]()
|
||||
{
|
||||
|
@ -51,6 +55,7 @@ downslib_error downslib_download(const char* url,
|
|||
SetLastError(dwLastError);
|
||||
});
|
||||
|
||||
// Create the PDB file that will be written to
|
||||
hFile = CreateFileW(filename, GENERIC_WRITE | FILE_READ_ATTRIBUTES, 0, NULL, CREATE_ALWAYS, 0, NULL);
|
||||
if(hFile == INVALID_HANDLE_VALUE)
|
||||
return downslib_error::createfile;
|
||||
|
@ -64,57 +69,66 @@ downslib_error downslib_download(const char* url,
|
|||
if(!hInternet)
|
||||
return downslib_error::inetopen;
|
||||
|
||||
// Set a time-out value in milliseconds
|
||||
InternetSetOptionA(hInternet,
|
||||
INTERNET_OPTION_RECEIVE_TIMEOUT,
|
||||
&timeout,
|
||||
sizeof(timeout));
|
||||
|
||||
// Attempt to enable content decoding if the option is supported
|
||||
DWORD gzipDecoding = true;
|
||||
if(InternetSetOptionA(hInternet,
|
||||
INTERNET_OPTION_HTTP_DECODING,
|
||||
&gzipDecoding,
|
||||
sizeof(gzipDecoding)))
|
||||
{
|
||||
// Add the required request headers
|
||||
headers = "Accept-Encoding: gzip\r\n";
|
||||
dwHeaderslen = static_cast<DWORD>(strlen(headers));
|
||||
}
|
||||
|
||||
DWORD dwFlags = INTERNET_FLAG_RELOAD;
|
||||
if(strncmp(url, "https://", 8) == 0)
|
||||
dwFlags |= INTERNET_FLAG_SECURE;
|
||||
|
||||
hUrl = InternetOpenUrlA(hInternet, url, NULL, 0, dwFlags, 0);
|
||||
// Make the HTTP request
|
||||
hUrl = InternetOpenUrlA(hInternet, url, headers, dwHeaderslen, dwFlags, 0);
|
||||
if(!hUrl)
|
||||
return downslib_error::openurl;
|
||||
|
||||
// Get HTTP content length
|
||||
char buffer[2048];
|
||||
memset(buffer, 0, sizeof(buffer));
|
||||
DWORD dwLen = sizeof(buffer);
|
||||
unsigned long long total_bytes = 0;
|
||||
if(HttpQueryInfoA(hUrl, HTTP_QUERY_CONTENT_LENGTH, buffer, &dwLen, 0))
|
||||
{
|
||||
if(sscanf_s(buffer, "%llu", &total_bytes) != 1)
|
||||
total_bytes = 0;
|
||||
}
|
||||
|
||||
// Get HTTP status code
|
||||
dwLen = sizeof(buffer);
|
||||
if(HttpQueryInfoA(hUrl, HTTP_QUERY_STATUS_CODE, buffer, &dwLen, 0))
|
||||
DWORD dwStatusCode;
|
||||
dwBufferSize = sizeof(dwStatusCode);
|
||||
if(HttpQueryInfoA(hUrl, HTTP_QUERY_STATUS_CODE | HTTP_QUERY_FLAG_NUMBER, &dwStatusCode, &dwBufferSize, 0))
|
||||
{
|
||||
int status_code = 0;
|
||||
if(sscanf_s(buffer, "%d", &status_code) != 1)
|
||||
status_code = 500;
|
||||
if(status_code != 200)
|
||||
if(dwStatusCode != 200)
|
||||
{
|
||||
SetLastError(status_code);
|
||||
SetLastError(dwStatusCode);
|
||||
return downslib_error::statuscode;
|
||||
}
|
||||
}
|
||||
|
||||
// Get HTTP content length
|
||||
unsigned long long contentLength = 0;
|
||||
dwBufferSize = sizeof(contentLength);
|
||||
HttpQueryInfoA(hUrl, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, &contentLength, &dwBufferSize, 0);
|
||||
|
||||
// Receive the data from the HINTERNET handle
|
||||
char buffer[chunk_size];
|
||||
DWORD dwRead = 0;
|
||||
DWORD dwWritten = 0;
|
||||
unsigned long long read_bytes = 0;
|
||||
unsigned long long readBytes = 0;
|
||||
unsigned long long totalBytes = contentLength;
|
||||
while(InternetReadFile(hUrl, buffer, sizeof(buffer), &dwRead))
|
||||
{
|
||||
read_bytes += dwRead;
|
||||
readBytes += dwRead;
|
||||
|
||||
// We are done if nothing more to read, so now we can report total size in our final cb call
|
||||
if(dwRead == 0)
|
||||
total_bytes = read_bytes;
|
||||
totalBytes = readBytes;
|
||||
|
||||
// Call the callback to report progress and cancellation
|
||||
if(cb && !cb(userdata, read_bytes, total_bytes))
|
||||
if(cb && !cb(userdata, readBytes, totalBytes))
|
||||
{
|
||||
SetLastError(ERROR_OPERATION_ABORTED);
|
||||
return downslib_error::cancel;
|
||||
|
@ -124,10 +138,19 @@ downslib_error downslib_download(const char* url,
|
|||
if(dwRead == 0)
|
||||
break;
|
||||
|
||||
// Write buffer to PDB file
|
||||
WriteFile(hFile, buffer, dwRead, &dwWritten, nullptr);
|
||||
|
||||
// Check WriteFile successfully wrote the entire buffer
|
||||
if(dwWritten != dwRead)
|
||||
{
|
||||
SetLastError(ERROR_IO_INCOMPLETE);
|
||||
return downslib_error::incomplete;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if(total_bytes > 0 && read_bytes != total_bytes)
|
||||
if(totalBytes > 0 && readBytes != totalBytes)
|
||||
{
|
||||
SetLastError(ERROR_IO_INCOMPLETE);
|
||||
return downslib_error::incomplete;
|
||||
|
|
|
@ -82,7 +82,31 @@ struct EncodeMap : AddrInfoHashMap<LockEncodeMaps, ENCODEMAP, EncodeMapSerialize
|
|||
|
||||
static EncodeMap encmaps;
|
||||
|
||||
static bool EncodeMapGetorCreate(duint addr, ENCODEMAP & map, bool* created = nullptr)
|
||||
static bool EncodeMapValidateModuleInfo(duint key, ENCODEMAP & map, duint segsize)
|
||||
{
|
||||
// The map size might be smaller if it was loaded from cache for another
|
||||
// version of the module. Adjust the size in this case.
|
||||
if(map.size < segsize)
|
||||
{
|
||||
byte* newData = (byte*)VirtualAlloc(NULL, segsize, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE);
|
||||
if(newData == NULL) return false;
|
||||
|
||||
memcpy(newData, map.data, map.size);
|
||||
|
||||
DecreaseReferenceCount(map.data);
|
||||
VirtualFree(map.data, 0, MEM_RELEASE);
|
||||
encmaps.Delete(key);
|
||||
|
||||
map.size = segsize;
|
||||
map.data = newData;
|
||||
IncreaseReferenceCount(map.data);
|
||||
encmaps.Add(map);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool EncodeMapGet(duint addr, ENCODEMAP & map, duint* baseOut = nullptr)
|
||||
{
|
||||
duint base, segsize;
|
||||
|
||||
|
@ -90,8 +114,32 @@ static bool EncodeMapGetorCreate(duint addr, ENCODEMAP & map, bool* created = nu
|
|||
if(!base)
|
||||
return false;
|
||||
|
||||
if(baseOut)
|
||||
*baseOut = base;
|
||||
|
||||
duint key = EncodeMap::VaKey(base);
|
||||
if(!encmaps.Contains(key))
|
||||
if(!encmaps.Get(key, map))
|
||||
return false;
|
||||
|
||||
if(!EncodeMapValidateModuleInfo(key, map, segsize))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool EncodeMapGetorCreate(duint addr, ENCODEMAP & map, duint* baseOut = nullptr, bool* created = nullptr)
|
||||
{
|
||||
duint base, segsize;
|
||||
|
||||
base = MemFindBaseAddr(addr, &segsize);
|
||||
if(!base)
|
||||
return false;
|
||||
|
||||
if(baseOut)
|
||||
*baseOut = base;
|
||||
|
||||
duint key = EncodeMap::VaKey(base);
|
||||
if(!encmaps.Get(key, map))
|
||||
{
|
||||
if(created)
|
||||
*created = true;
|
||||
|
@ -104,7 +152,9 @@ static bool EncodeMapGetorCreate(duint addr, ENCODEMAP & map, bool* created = nu
|
|||
}
|
||||
else
|
||||
{
|
||||
if(!encmaps.Get(key, map))
|
||||
if(created)
|
||||
*created = false;
|
||||
if(!EncodeMapValidateModuleInfo(key, map, segsize))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
@ -112,10 +162,9 @@ static bool EncodeMapGetorCreate(duint addr, ENCODEMAP & map, bool* created = nu
|
|||
|
||||
void* EncodeMapGetBuffer(duint addr, duint* size, bool create)
|
||||
{
|
||||
auto base = MemFindBaseAddr(addr);
|
||||
|
||||
ENCODEMAP map;
|
||||
if(create ? EncodeMapGetorCreate(addr, map) : encmaps.Get(EncodeMap::VaKey(base), map))
|
||||
duint base;
|
||||
if(create ? EncodeMapGetorCreate(addr, map, &base) : EncodeMapGet(addr, map, &base))
|
||||
{
|
||||
auto offset = addr - base;
|
||||
if(offset < map.size)
|
||||
|
@ -188,11 +237,9 @@ static bool IsCodeType(ENCODETYPE type)
|
|||
|
||||
ENCODETYPE EncodeMapGetType(duint addr, duint codesize)
|
||||
{
|
||||
duint size;
|
||||
auto base = MemFindBaseAddr(addr, &size);
|
||||
|
||||
ENCODEMAP map;
|
||||
if(base && encmaps.Get(EncodeMap::VaKey(base), map))
|
||||
duint base;
|
||||
if(EncodeMapGet(addr, map, &base))
|
||||
{
|
||||
auto offset = addr - base;
|
||||
if(offset >= map.size)
|
||||
|
@ -205,12 +252,9 @@ ENCODETYPE EncodeMapGetType(duint addr, duint codesize)
|
|||
|
||||
duint EncodeMapGetSize(duint addr, duint codesize)
|
||||
{
|
||||
auto base = MemFindBaseAddr(addr, nullptr);
|
||||
if(!base)
|
||||
return codesize;
|
||||
|
||||
ENCODEMAP map;
|
||||
if(encmaps.Get(EncodeMap::VaKey(base), map))
|
||||
duint base;
|
||||
if(EncodeMapGet(addr, map, &base))
|
||||
{
|
||||
auto offset = addr - base;
|
||||
if(offset >= map.size)
|
||||
|
@ -227,14 +271,9 @@ duint EncodeMapGetSize(duint addr, duint codesize)
|
|||
|
||||
bool EncodeMapSetType(duint addr, duint size, ENCODETYPE type, bool* created)
|
||||
{
|
||||
auto base = MemFindBaseAddr(addr, nullptr);
|
||||
if(!base)
|
||||
return false;
|
||||
|
||||
ENCODEMAP map;
|
||||
if(created)
|
||||
*created = false;
|
||||
if(!EncodeMapGetorCreate(base, map, created))
|
||||
duint base;
|
||||
if(!EncodeMapGetorCreate(addr, map, &base, created))
|
||||
return false;
|
||||
auto offset = addr - base;
|
||||
size = min(map.size - offset, size);
|
||||
|
|
|
@ -152,6 +152,9 @@ void ExpressionFunctions::Init()
|
|||
//Undocumented
|
||||
RegisterEasy("bpgoto", bpgoto);
|
||||
|
||||
//Other
|
||||
RegisterEasy("isdebuggerfocused", isdebuggerfocused);
|
||||
|
||||
// Strings
|
||||
ExpressionFunctions::Register("utf8", ValueTypeString, { ValueTypeNumber }, Exprfunc::utf8, nullptr);
|
||||
ExpressionFunctions::Register("utf16", ValueTypeString, { ValueTypeNumber }, Exprfunc::utf16, nullptr);
|
||||
|
|
|
@ -600,6 +600,11 @@ namespace Exprfunc
|
|||
return getLastExceptionInfo().ExceptionRecord.ExceptionInformation[index];
|
||||
}
|
||||
|
||||
duint isdebuggerfocused()
|
||||
{
|
||||
return GuiIsDebuggerFocused();
|
||||
}
|
||||
|
||||
bool streq(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata)
|
||||
{
|
||||
assert(argc == 2);
|
||||
|
|
|
@ -86,6 +86,8 @@ namespace Exprfunc
|
|||
duint exinfocount();
|
||||
duint exinfo(duint index);
|
||||
|
||||
duint isdebuggerfocused();
|
||||
|
||||
bool streq(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool strieq(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
bool strstr(ExpressionValue* result, int argc, const ExpressionValue* argv, void* userdata);
|
||||
|
|
|
@ -286,6 +286,7 @@ bool SymDownloadSymbol(duint Base, const char* SymbolStore)
|
|||
|
||||
symprintf(QT_TRANSLATE_NOOP("DBG", "Downloading symbol %s\n Signature: %s\n Destination: %s\n URL: %s\n"), pdbBaseFile, pdbSignature.c_str(), StringUtils::Utf16ToUtf8(symbolPath).c_str(), symbolUrl.c_str());
|
||||
|
||||
DWORD lineDownloadStart = GetTickCount();
|
||||
auto result = downslib_download(symbolUrl.c_str(), symbolPath.c_str(), "x64dbg", 1000, [](void* userdata, unsigned long long read_bytes, unsigned long long total_bytes)
|
||||
{
|
||||
if(total_bytes)
|
||||
|
@ -324,6 +325,10 @@ bool SymDownloadSymbol(duint Base, const char* SymbolStore)
|
|||
__debugbreak();
|
||||
}
|
||||
|
||||
DWORD ms = GetTickCount() - lineDownloadStart;
|
||||
double secs = (double)ms / 1000.0;
|
||||
symprintf(QT_TRANSLATE_NOOP("DBG", "Finished downloading symbol %s in %.03fs\n"), pdbBaseFile, secs);
|
||||
|
||||
{
|
||||
EXCLUSIVE_ACQUIRE(LockModules);
|
||||
auto info = ModInfoFromAddr(Base);
|
||||
|
|
|
@ -50,6 +50,29 @@ static bool cbClearLog(int argc, char* argv[])
|
|||
return true;
|
||||
}
|
||||
|
||||
static bool cbSaveLog(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
GuiLogSave(nullptr);
|
||||
else
|
||||
GuiLogSave(argv[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbRedirectLog(int argc, char* argv[])
|
||||
{
|
||||
if(IsArgumentsLessThan(argc, 2))
|
||||
return false;
|
||||
GuiLogRedirect(argv[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbStopRedirectLog(int argc, char* argv[])
|
||||
{
|
||||
GuiLogRedirectStop();
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cbPrintf(int argc, char* argv[])
|
||||
{
|
||||
if(argc < 2)
|
||||
|
@ -406,6 +429,9 @@ static void registercommands()
|
|||
dbgcmdnew("EnableLog,LogEnable", cbInstrEnableLog, false); //enable log
|
||||
dbgcmdnew("DisableLog,LogDisable", cbInstrDisableLog, false); //disable log
|
||||
dbgcmdnew("ClearLog,cls,lc,lclr", cbClearLog, false); //clear the log
|
||||
dbgcmdnew("SaveLog,LogSave", cbSaveLog, false); //save the log
|
||||
dbgcmdnew("RedirectLog,LogRedirect", cbRedirectLog, false); //redirect the log
|
||||
dbgcmdnew("StopRedirectLog,LogRedirectStop", cbStopRedirectLog, false); //stop redirecting the log
|
||||
dbgcmdnew("AddFavouriteTool", cbInstrAddFavTool, false); //add favourite tool
|
||||
dbgcmdnew("AddFavouriteCommand", cbInstrAddFavCmd, false); //add favourite command
|
||||
dbgcmdnew("AddFavouriteToolShortcut,SetFavouriteToolShortcut", cbInstrSetFavToolShortcut, false); //set favourite tool shortcut
|
||||
|
|
|
@ -62,7 +62,9 @@ SearchListView::SearchListView(QWidget* parent, AbstractSearchList* abstractSear
|
|||
QHBoxLayout* horzLayout = new QHBoxLayout();
|
||||
horzLayout->setContentsMargins(4, 0, (enableRegex || enableLock) ? 0 : 4, 0);
|
||||
horzLayout->setSpacing(2);
|
||||
horzLayout->addWidget(new QLabel(tr("Search: ")));
|
||||
QLabel* label = new QLabel(tr("Search: "), this);
|
||||
label->setBuddy(mSearchBox);
|
||||
horzLayout->addWidget(label);
|
||||
horzLayout->addWidget(mSearchBox);
|
||||
horzLayout->addWidget(mLockCheckbox);
|
||||
horzLayout->addWidget(mRegexCheckbox);
|
||||
|
|
|
@ -127,6 +127,21 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
emit clearLog();
|
||||
break;
|
||||
|
||||
case GUI_SAVE_LOG:
|
||||
if(!param1)
|
||||
emit saveLog();
|
||||
else
|
||||
emit saveLogToFile(QString((const char*)param1));
|
||||
break;
|
||||
|
||||
case GUI_REDIRECT_LOG:
|
||||
emit redirectLogToFile(QString((const char*)param1));
|
||||
break;
|
||||
|
||||
case GUI_STOP_REDIRECT_LOG:
|
||||
emit redirectLogStop();
|
||||
break;
|
||||
|
||||
case GUI_UPDATE_REGISTER_VIEW:
|
||||
emit updateRegisters();
|
||||
break;
|
||||
|
@ -905,6 +920,9 @@ void* Bridge::processMessage(GUIMSG type, void* param1, void* param2)
|
|||
|
||||
case GUI_GET_MAIN_THREAD_ID:
|
||||
return (void*)dwMainThreadId;
|
||||
|
||||
case GUI_IS_DEBUGGER_FOCUSED:
|
||||
return (void*)!!QApplication::activeWindow();
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
|
|
|
@ -53,6 +53,10 @@ signals:
|
|||
void addMsgToLog(QByteArray msg);
|
||||
void addMsgToLogHtml(QByteArray msg);
|
||||
void clearLog();
|
||||
void saveLog();
|
||||
void saveLogToFile(QString file);
|
||||
void redirectLogStop();
|
||||
void redirectLogToFile(QString filename);
|
||||
void shutdown();
|
||||
void updateRegisters();
|
||||
void updateBreakpoints();
|
||||
|
|
|
@ -28,6 +28,9 @@
|
|||
<property name="text">
|
||||
<string>Path:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>lineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -87,6 +87,14 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget)
|
|||
ui->mBotRightFrameLayout->addWidget(mStack);
|
||||
connect(mDisas, SIGNAL(selectionChanged(dsint)), mStack, SLOT(disasmSelectionChanged(dsint)));
|
||||
|
||||
mDisas->setAccessibleName(tr("Disassembly"));
|
||||
mStack->setAccessibleName(tr("Stack"));
|
||||
upperScrollArea->setAccessibleName(tr("Registers"));
|
||||
mDump->setAccessibleName(tr("Dump"));
|
||||
mArgumentWidget->setAccessibleName(tr("Arguments"));
|
||||
mSideBar->setAccessibleName(tr("Sidebar"));
|
||||
mInfo->setAccessibleName(tr("InfoBox"));
|
||||
|
||||
// load column config
|
||||
mDisas->loadColumnFromConfig("CPUDisassembly");
|
||||
mStack->loadColumnFromConfig("CPUStack");
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
<property name="text">
|
||||
<string>Signed:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtSignedDec</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
|
@ -38,6 +41,9 @@
|
|||
<property name="text">
|
||||
<string>Unsigned:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtUnsignedDec</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
|
@ -45,6 +51,9 @@
|
|||
<property name="text">
|
||||
<string>Unicode:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtUnicode</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
|
@ -52,6 +61,9 @@
|
|||
<property name="text">
|
||||
<string>Octal:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtOct</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0">
|
||||
|
@ -59,6 +71,9 @@
|
|||
<property name="text">
|
||||
<string>Expression:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtExpression</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
|
@ -102,6 +117,9 @@
|
|||
<property name="text">
|
||||
<string>Binary:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtBin</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
|
@ -109,6 +127,9 @@
|
|||
<property name="text">
|
||||
<string>ASCII:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtAscii</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
|
@ -222,6 +243,9 @@
|
|||
<property name="text">
|
||||
<string>Hexadecimal:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtHex</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
|
@ -260,6 +284,9 @@
|
|||
<property name="text">
|
||||
<string>Bytes:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>txtBytes</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
|
|
@ -30,6 +30,9 @@
|
|||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editStart</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
|
@ -46,6 +49,9 @@
|
|||
<property name="alignment">
|
||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editEnd</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
|
|
|
@ -137,6 +137,11 @@ HandlesView::HandlesView(QWidget* parent) : QWidget(parent)
|
|||
mTcpConnectionsTable->reloadData();
|
||||
}
|
||||
|
||||
mWindowsTable->setAccessibleName(tr("Windows"));
|
||||
mHandlesTable->setAccessibleName(tr("Handles"));
|
||||
mTcpConnectionsTable->setAccessibleName(tr("TCP Connections"));
|
||||
mPrivilegesTable->setAccessibleName(tr("Privileges"));
|
||||
|
||||
reloadData();
|
||||
refreshShortcuts();
|
||||
}
|
||||
|
|
|
@ -406,6 +406,9 @@
|
|||
<property name="text">
|
||||
<string>Items per line:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinBox</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -36,8 +36,12 @@ LogView::LogView(QWidget* parent) : QTextBrowser(parent), logRedirection(NULL)
|
|||
connect(Config(), SIGNAL(colorsUpdated()), this, SLOT(updateStyle()));
|
||||
connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(updateStyle()));
|
||||
connect(Bridge::getBridge(), SIGNAL(addMsgToLog(QByteArray)), this, SLOT(addMsgToLogSlot(QByteArray)));
|
||||
connect(Bridge::getBridge(), SIGNAL(addMsgToLogHtml(QByteArray)), this, SLOT(addMsgToLogSlotHtml(QByteArray)));
|
||||
connect(Bridge::getBridge(), SIGNAL(addMsgToLogHtml(QByteArray)), this, SLOT(addMsgToLogHtmlSlot(QByteArray)));
|
||||
connect(Bridge::getBridge(), SIGNAL(clearLog()), this, SLOT(clearLogSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(saveLog()), this, SLOT(saveSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(saveLogToFile(QString)), this, SLOT(saveToFileSlot(QString)));
|
||||
connect(Bridge::getBridge(), SIGNAL(redirectLogToFile(QString)), this, SLOT(redirectLogToFileSlot(QString)));
|
||||
connect(Bridge::getBridge(), SIGNAL(redirectLogStop()), this, SLOT(stopRedirectLogSlot()));
|
||||
connect(Bridge::getBridge(), SIGNAL(setLogEnabled(bool)), this, SLOT(setLoggingEnabled(bool)));
|
||||
connect(Bridge::getBridge(), SIGNAL(flushLog()), this, SLOT(flushLogSlot()));
|
||||
connect(this, SIGNAL(anchorClicked(QUrl)), this, SLOT(onAnchorClicked(QUrl)));
|
||||
|
@ -56,9 +60,9 @@ LogView::LogView(QWidget* parent) : QTextBrowser(parent), logRedirection(NULL)
|
|||
*/
|
||||
LogView::~LogView()
|
||||
{
|
||||
if(logRedirection != NULL)
|
||||
if(logRedirection != nullptr)
|
||||
fclose(logRedirection);
|
||||
logRedirection = NULL;
|
||||
logRedirection = nullptr;
|
||||
}
|
||||
|
||||
void LogView::updateStyle()
|
||||
|
@ -148,7 +152,7 @@ void LogView::contextMenuEvent(QContextMenuEvent* event)
|
|||
wMenu.addAction(actionFindInLog);
|
||||
wMenu.addAction(actionFindNext);
|
||||
wMenu.addAction(actionFindPrevious);
|
||||
if(logRedirection == NULL)
|
||||
if(logRedirection == nullptr)
|
||||
actionRedirectLog->setText(tr("&Redirect Log..."));
|
||||
else
|
||||
actionRedirectLog->setText(tr("Stop &Redirection"));
|
||||
|
@ -230,10 +234,10 @@ void LogView::linkify(QString & msg)
|
|||
}
|
||||
|
||||
/**
|
||||
* @brief LogView::addMsgToLogSlotHtml Adds a HTML message to the log view. This function is a slot for Bridge::addMsgToLogHtml.
|
||||
* @brief LogView::addMsgToLogHtmlSlot Adds a HTML message to the log view. This function is a slot for Bridge::addMsgToLogHtml.
|
||||
* @param msg The log message (Which is assumed to contain HTML)
|
||||
*/
|
||||
void LogView::addMsgToLogSlotHtml(QByteArray msg)
|
||||
void LogView::addMsgToLogHtmlSlot(QByteArray msg)
|
||||
{
|
||||
LogView::addMsgToLogSlotRaw(msg, false);
|
||||
}
|
||||
|
@ -265,7 +269,7 @@ void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
|
|||
// redirect the log
|
||||
QString msgUtf16;
|
||||
bool redirectError = false;
|
||||
if(logRedirection != NULL)
|
||||
if(logRedirection != nullptr)
|
||||
{
|
||||
if(utf16Redirect)
|
||||
{
|
||||
|
@ -274,7 +278,7 @@ void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
|
|||
if(!fwrite(msgUtf16.utf16(), msgUtf16.length(), 2, logRedirection))
|
||||
{
|
||||
fclose(logRedirection);
|
||||
logRedirection = NULL;
|
||||
logRedirection = nullptr;
|
||||
redirectError = true;
|
||||
}
|
||||
}
|
||||
|
@ -306,7 +310,7 @@ void LogView::addMsgToLogSlotRaw(QByteArray msg, bool encodeHTML)
|
|||
if(!fwrite(data, buffersize, 1, logRedirection))
|
||||
{
|
||||
fclose(logRedirection);
|
||||
logRedirection = NULL;
|
||||
logRedirection = nullptr;
|
||||
redirectError = true;
|
||||
}
|
||||
if(loggingEnabled)
|
||||
|
@ -375,30 +379,56 @@ void LogView::clearLogSlot()
|
|||
this->clear();
|
||||
}
|
||||
|
||||
void LogView::redirectLogSlot()
|
||||
void LogView::stopRedirectLogSlot()
|
||||
{
|
||||
if(logRedirection != NULL)
|
||||
if(logRedirection != nullptr)
|
||||
{
|
||||
fclose(logRedirection);
|
||||
logRedirection = NULL;
|
||||
logRedirection = nullptr;
|
||||
GuiAddLogMessage(tr("Log redirection is stopped.\n").toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
GuiAddLogMessage(tr("Log is not redirected.\n").toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void LogView::redirectLogToFileSlot(QString filename)
|
||||
{
|
||||
if(logRedirection != nullptr)
|
||||
{
|
||||
fclose(logRedirection);
|
||||
logRedirection = nullptr;
|
||||
GuiAddLogMessage(tr("Log redirection is stopped.\n").toUtf8().constData());
|
||||
}
|
||||
logRedirection = _wfopen(filename.toStdWString().c_str(), L"ab");
|
||||
if(logRedirection == nullptr)
|
||||
GuiAddLogMessage(tr("_wfopen() failed. Log will not be redirected to %1.\n").arg(QString::fromWCharArray(BridgeUserDirectory())).toUtf8().constData());
|
||||
else
|
||||
{
|
||||
if(utf16Redirect && ftell(logRedirection) == 0)
|
||||
{
|
||||
unsigned short BOM = 0xfeff;
|
||||
fwrite(&BOM, 2, 1, logRedirection);
|
||||
}
|
||||
GuiAddLogMessage(tr("Log will be redirected to %1.\n").arg(filename).toUtf8().constData());
|
||||
}
|
||||
}
|
||||
|
||||
void LogView::redirectLogSlot()
|
||||
{
|
||||
if(logRedirection != nullptr)
|
||||
{
|
||||
fclose(logRedirection);
|
||||
logRedirection = nullptr;
|
||||
GuiAddLogMessage(tr("Log redirection is stopped.\n").toUtf8().constData());
|
||||
}
|
||||
else
|
||||
{
|
||||
BrowseDialog browse(this, tr("Redirect log to file"), tr("Enter the file to which you want to redirect log messages."), tr("Log files (*.txt);;All files (*.*)"), QString::fromWCharArray(BridgeUserDirectory()), true);
|
||||
if(browse.exec() == QDialog::Accepted)
|
||||
{
|
||||
logRedirection = _wfopen(browse.path.toStdWString().c_str(), L"ab");
|
||||
if(logRedirection == NULL)
|
||||
GuiAddLogMessage(tr("_wfopen() failed. Log will not be redirected to %1.\n").arg(browse.path).toUtf8().constData());
|
||||
else
|
||||
{
|
||||
if(utf16Redirect && ftell(logRedirection) == 0)
|
||||
{
|
||||
unsigned short BOM = 0xfeff;
|
||||
fwrite(&BOM, 2, 1, logRedirection);
|
||||
}
|
||||
GuiAddLogMessage(tr("Log will be redirected to %1.\n").arg(browse.path).toUtf8().constData());
|
||||
}
|
||||
redirectLogToFileSlot(browse.path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -427,13 +457,8 @@ void LogView::autoScrollSlot()
|
|||
autoScroll = !autoScroll;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LogView::saveSlot Called by "save" action
|
||||
*/
|
||||
void LogView::saveSlot()
|
||||
void LogView::saveToFileSlot(QString fileName)
|
||||
{
|
||||
QString fileName;
|
||||
fileName = QString("log-%1.txt").arg(QDateTime::currentDateTime().toString().replace(QChar(':'), QChar('-')));
|
||||
QFile savedLog(fileName);
|
||||
savedLog.open(QIODevice::Append | QIODevice::Text);
|
||||
if(savedLog.error() != QFile::NoError)
|
||||
|
@ -448,6 +473,16 @@ void LogView::saveSlot()
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief LogView::saveSlot Called by "save" action
|
||||
*/
|
||||
void LogView::saveSlot()
|
||||
{
|
||||
QString fileName;
|
||||
fileName = QString("log-%1.txt").arg(isoDateTime());
|
||||
saveToFileSlot(fileName);
|
||||
}
|
||||
|
||||
void LogView::toggleLoggingSlot()
|
||||
{
|
||||
setLoggingEnabled(!getLoggingEnabled());
|
||||
|
|
|
@ -21,7 +21,9 @@ public slots:
|
|||
void refreshShortcutsSlot();
|
||||
void updateStyle();
|
||||
void addMsgToLogSlot(QByteArray msg); /* Non-HTML Log Function*/
|
||||
void addMsgToLogSlotHtml(QByteArray msg); /* HTML accepting Log Function */
|
||||
void addMsgToLogHtmlSlot(QByteArray msg); /* HTML accepting Log Function */
|
||||
void stopRedirectLogSlot();
|
||||
void redirectLogToFileSlot(QString filename);
|
||||
void redirectLogSlot();
|
||||
void setLoggingEnabled(bool enabled);
|
||||
void autoScrollSlot();
|
||||
|
@ -35,6 +37,7 @@ public slots:
|
|||
void onAnchorClicked(const QUrl & link);
|
||||
|
||||
void clearLogSlot();
|
||||
void saveToFileSlot(QString filename);
|
||||
void saveSlot();
|
||||
void toggleLoggingSlot();
|
||||
void flushTimerSlot();
|
||||
|
|
|
@ -34,6 +34,9 @@
|
|||
<property name="text">
|
||||
<string>Messages:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>cboxMessages</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -451,6 +451,9 @@
|
|||
<property name="text">
|
||||
<string>Animation per-step interval (ms)</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>spinAnimateInterval</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -503,6 +506,9 @@
|
|||
<property name="text">
|
||||
<string>Exception Filters:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>listExceptions</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -986,6 +992,9 @@
|
|||
<property name="text">
|
||||
<string>Symbol Store:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editSymbolStore</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
@ -993,6 +1002,9 @@
|
|||
<property name="text">
|
||||
<string>Symbol Path:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editSymbolCache</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
|
@ -1023,6 +1035,9 @@
|
|||
<property name="text">
|
||||
<string>JIT:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>editJIT</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
|
|
|
@ -63,6 +63,7 @@ int MHTabWidget::addTabEx(QWidget* widget, const QIcon & icon, const QString & l
|
|||
{
|
||||
mNativeNames.append(nativeName);
|
||||
mHistory.push_back((MIDPKey)widget);
|
||||
widget->setAccessibleName(label);
|
||||
return this->addTab(widget, icon, label);
|
||||
}
|
||||
|
||||
|
|
|
@ -31,6 +31,9 @@
|
|||
<property name="text">
|
||||
<string>Expression:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>expressionLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
|
@ -92,6 +95,9 @@
|
|||
<property name="text">
|
||||
<string>Bytes:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>hexLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
|
@ -99,6 +105,9 @@
|
|||
<property name="text">
|
||||
<string>Unsigned:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>unsignedLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
|
@ -106,6 +115,9 @@
|
|||
<property name="text">
|
||||
<string>ASCII:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>asciiLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
|
@ -113,6 +125,9 @@
|
|||
<property name="text">
|
||||
<string>Signed:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>signedLineEdit</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
|
|
|
@ -374,15 +374,7 @@ QString getDbPath(const QString & filename, bool addDateTimeSuffix)
|
|||
{
|
||||
extensionIdx = path.length();
|
||||
}
|
||||
auto now = QDateTime::currentDateTime();
|
||||
auto suffix = QString().sprintf("-%04d%02d%02d-%02d%02d%02d",
|
||||
now.date().year(),
|
||||
now.date().month(),
|
||||
now.date().day(),
|
||||
now.time().hour(),
|
||||
now.time().minute(),
|
||||
now.time().second()
|
||||
);
|
||||
auto suffix = "-" + isoDateTime();
|
||||
path.insert(extensionIdx, suffix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -219,6 +219,19 @@ QString GetDataTypeString(const void* buffer, duint size, ENCODETYPE type)
|
|||
}
|
||||
}
|
||||
|
||||
QString isoDateTime()
|
||||
{
|
||||
auto now = QDateTime::currentDateTime();
|
||||
return QString().sprintf("%04d%02d%02d-%02d%02d%02d",
|
||||
now.date().year(),
|
||||
now.date().month(),
|
||||
now.date().day(),
|
||||
now.time().hour(),
|
||||
now.time().minute(),
|
||||
now.time().second()
|
||||
);
|
||||
}
|
||||
|
||||
QString ToDateString(const QDate & date)
|
||||
{
|
||||
static const char* months[] =
|
||||
|
|
|
@ -104,6 +104,9 @@ inline QString ToDoubleString(const void* buffer, int precision = std::numeric_l
|
|||
|
||||
QString ToLongDoubleString(const void* buffer);
|
||||
|
||||
// yyyyMMdd-HHmmss (useful for file suffix)
|
||||
QString isoDateTime();
|
||||
|
||||
QString ToDateString(const QDate & date);
|
||||
|
||||
QString fillValue(const char* value, int valsize = 2, bool bFpuRegistersLittleEndian = false);
|
||||
|
|
Loading…
Reference in New Issue