1
0
Fork 0

Merge branch 'patch00000007' of https://github.com/torusrxxx/x64dbg into torusrxxx-patch00000007

This commit is contained in:
mrexodia 2016-07-25 23:28:51 +02:00
commit 57b8c59aa9
No known key found for this signature in database
GPG Key ID: D72F9A4FAA0073B4
19 changed files with 237 additions and 74 deletions

View File

@ -690,6 +690,10 @@ typedef struct
THREADPRIORITY Priority;
THREADWAITREASON WaitReason;
DWORD LastError;
FILETIME UserTime;
FILETIME KernelTime;
FILETIME CreationTime;
ULONG64 Cycles; // Windows Vista or greater
} THREADALLINFO;
typedef struct

View File

@ -9,6 +9,15 @@
#include "threading.h"
static std::unordered_map<DWORD, THREADINFO> threadList;
// Function pointer for dynamic linking. Do not link statically for Windows XP compatibility.
// TODO: move this function definition out of thread.cpp
BOOL(WINAPI* QueryThreadCycleTime)(HANDLE ThreadHandle, PULONG64 CycleTime) = nullptr;
BOOL WINAPI QueryThreadCycleTimeUnsupported(HANDLE ThreadHandle, PULONG64 CycleTime)
{
*CycleTime = 0;
return TRUE;
}
void ThreadCreate(CREATE_THREAD_DEBUG_INFO* CreateThread)
{
@ -78,6 +87,13 @@ int ThreadGetCount()
void ThreadGetList(THREADLIST* List)
{
// Initialize function pointer
if(QueryThreadCycleTime == nullptr)
{
QueryThreadCycleTime = (BOOL(WINAPI*)(HANDLE, PULONG64))GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "QueryThreadCycleTime");
if(QueryThreadCycleTime == nullptr)
QueryThreadCycleTime = QueryThreadCycleTimeUnsupported;
}
ASSERT_NONNULL(List);
SHARED_ACQUIRE(LockThreads);
@ -97,6 +113,9 @@ void ThreadGetList(THREADLIST* List)
// Fill out the list data
int index = 0;
// Unused thread exit time
FILETIME threadExitTime;
for(auto & itr : threadList)
{
HANDLE threadHandle = itr.second.Handle;
@ -112,6 +131,8 @@ void ThreadGetList(THREADLIST* List)
List->list[index].Priority = ThreadGetPriority(threadHandle);
List->list[index].WaitReason = ThreadGetWaitReason(threadHandle);
List->list[index].LastError = ThreadGetLastErrorTEB(itr.second.ThreadLocalBase);
GetThreadTimes(threadHandle, &List->list[index].CreationTime, &threadExitTime, &List->list[index].KernelTime, &List->list[index].UserTime);
QueryThreadCycleTime(threadHandle, &List->list[index].Cycles);
index++;
}
}

View File

@ -1403,7 +1403,7 @@ bool valapifromstring(const char* name, duint* value, int* value_size, bool prin
if(szBaseName)
{
szBaseName++;
HMODULE hModule = LoadLibraryExW(szModuleName, 0, DONT_RESOLVE_DLL_REFERENCES | LOAD_LIBRARY_AS_DATAFILE);
HMODULE hModule = LoadLibraryExW(szModuleName, 0, DONT_RESOLVE_DLL_REFERENCES);
if(hModule)
{
ULONG_PTR funcAddress = (ULONG_PTR)GetProcAddress(hModule, name);
@ -1448,6 +1448,21 @@ bool valapifromstring(const char* name, duint* value, int* value_size, bool prin
return true;
}
bool valenvfromstring(const char* string, duint* Address)
{
if(scmp(string, "peb"))
{
*Address = (duint)GetPEBLocation(fdProcessInfo->hProcess);
return true;
}
else if(scmp(string, "teb"))
{
*Address = (duint)GetTEBLocation(hActiveThread);
return true;
}
return false;
}
/**
\brief Check if a string is a valid decimal number. This function also accepts "-" or "." as prefix.
\param string The string to check.
@ -1515,6 +1530,11 @@ bool convertLongLongNumber(const char* str, unsigned long long & result, int rad
return true;
}
/**
\brief Check if a character is a valid hexadecimal digit that is smaller than the size of a pointer.
\param digit The character to check.
\return true if the character is a valid hexadecimal digit.
*/
static bool isdigitduint(char digit)
{
#ifdef _WIN64
@ -1609,7 +1629,8 @@ bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool ba
if(!valfromstring(ptrstring.c_str(), value, silent, baseonly))
{
dprintf("noexpr failed on %s\n", ptrstring.c_str());
if(!silent)
dprintf("noexpr failed on %s\n", ptrstring.c_str());
return false;
}
duint addr = *value;
@ -1702,6 +1723,8 @@ bool valfromstring_noexpr(const char* string, duint* value, bool silent, bool ba
*isvar = true;
return true;
}
else if(valenvfromstring(string, value)) //environment block
return true;
else if(strstr(string, "sub_") == string) //then come sub_ functions
{
auto result = sscanf(string, "sub_%" fext "X", value) == 1;

View File

@ -444,6 +444,37 @@ void StdTable::setupCopyMenu(QMenu* copyMenu)
}
}
void StdTable::setupCopyMenu(MenuBuilder *copyMenu)
{
if(!getColumnCount())
return;
//Copy->Whole Line
copyMenu->addAction(makeAction(tr("&Line"), SLOT(copyLineSlot())));
//Copy->Cropped Table
copyMenu->addAction(makeAction(tr("Cropped &Table"), SLOT(copyTableSlot())));
//Copy->Full Table
copyMenu->addAction(makeAction(tr("&Full Table"), SLOT(copyTableResizeSlot())));
//Copy->Separator
copyMenu->addSeparator();
//Copy->ColName
copyMenu->addBuilder(new MenuBuilder(this, [this](QMenu* menu)
{
for(int i = 0; i < getColumnCount(); i++)
{
if(!getCellContent(getInitialSelection(), i).length()) //skip empty cells
continue;
QString title = mCopyTitles.at(i);
if(!title.length()) //skip empty copy titles
continue;
QAction* action = new QAction(title, menu);
action->setObjectName(QString::number(i));
connect(action, SIGNAL(triggered()), this, SLOT(copyEntrySlot()));
menu->addAction(action);
}
return true;
}));
}
void StdTable::setCopyMenuOnly(bool bSet, bool bDebugOnly)
{
mCopyMenuOnly = bSet;

View File

@ -39,6 +39,7 @@ public:
//context menu helpers
void setupCopyMenu(QMenu* copyMenu);
void setupCopyMenu(MenuBuilder* copyMenu);
void setCopyMenuOnly(bool bSet, bool bDebugOnly = true);
signals:

View File

@ -1311,7 +1311,7 @@ void CPUDisassembly::yaraSlot()
YaraRuleSelectionDialog yaraDialog(this);
if(yaraDialog.exec() == QDialog::Accepted)
{
QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(dsint) * 2, 16, QChar('0')).toUpper();
QString addrText = ToPtrString(rvaToVa(getInitialSelection()));
DbgCmdExec(QString("yara \"%0\",%1").arg(yaraDialog.getSelectedFile()).arg(addrText).toUtf8().constData());
emit displayReferencesWidget();
}

View File

@ -164,7 +164,7 @@ void CPUDump::setupContextMenu()
mMenuBuilder->addAction(makeAction(DIcon("data-copy.png"), tr("Data co&py..."), SLOT(dataCopySlot())));
mMenuBuilder->addAction(makeShortcutAction(DIcon("sync.png"), tr("&Sync with expression"), SLOT(syncWithExpressionSlot()), "ActionSyncWithExpression"));
mMenuBuilder->addAction(makeAction(DIcon("animal-dog.png"), ArchValue(tr("Watch QWORD"), tr("Watch DWORD")), SLOT(watchSlot())));
mMenuBuilder->addAction(makeAction(DIcon("animal-dog.png"), ArchValue(tr("Watch DWORD"), tr("Watch QWORD")), SLOT(watchSlot())));
mMenuBuilder->addAction(makeShortcutAction(DIcon("entropy.png"), tr("Entrop&y..."), SLOT(entropySlot()), "ActionEntropy"));
MenuBuilder* wGotoMenu = new MenuBuilder(this);

View File

@ -193,6 +193,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
#endif //_WIN64
std::vector<JumpLine> jumpLines;
std::vector<LabelArrow> labelArrows;
for(int line = 0; line < viewableRows; line++)
{
@ -270,7 +271,7 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
if(regLabelText.size())
{
regLabelText.chop(1);
drawLabel(&painter, line, regLabelText);
labelArrows.push_back(drawLabel(&painter, line, regLabelText));
}
//debug
@ -291,10 +292,16 @@ void CPUSideBar::paintEvent(QPaintEvent* event)
}
if(jumpLines.size())
{
AllocateJumpOffsets(jumpLines);
AllocateJumpOffsets(jumpLines, labelArrows);
for(auto i : jumpLines)
drawJump(&painter, i.line, i.destLine, i.jumpOffset, i.isConditional, i.isJumpGoingToExecute, i.isSelected);
}
else
{
for(auto i = labelArrows.begin(); i != labelArrows.end(); i++)
i->endX = viewport()->width() - 1 - 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + fontHeight : 0);
}
drawLabelArrows(&painter, labelArrows);
}
void CPUSideBar::mouseReleaseEvent(QMouseEvent* e)
@ -599,7 +606,7 @@ void CPUSideBar::drawBullets(QPainter* painter, int line, bool isbp, bool isbpdi
painter->restore();
}
void CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
CPUSideBar::LabelArrow CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
{
painter->save();
const int LineCoordinate = fontHeight * (1 + Line);
@ -630,7 +637,29 @@ void CPUSideBar::drawLabel(QPainter* painter, int Line, const QString & Text)
painter->setBrush(QBrush(IPLabelBG));
drawStraightArrow(painter, rect.right() + 2, y, this->viewport()->width() - x - 11 - (isFoldingGraphicsPresent(Line) != 0 ? mBulletRadius + fontHeight : 0), y);*/
LabelArrow labelArrow;
labelArrow.line = Line;
labelArrow.startX = rect.right() + 2;
labelArrow.endX = 0;
painter->restore();
return labelArrow;
}
void CPUSideBar::drawLabelArrows(QPainter* painter, const std::vector<LabelArrow> & labelArrows)
{
if(!labelArrows.empty())
{
painter->save();
painter->setPen(QPen(mCipLabelBackgroundColor, 2.0));
for(auto i : labelArrows)
{
int y = fontHeight * (1 + i.line) - 0.5 * fontHeight;
drawStraightArrow(painter, i.startX, y, i.endX, y);
}
painter->restore();
}
}
void CPUSideBar::drawFoldingCheckbox(QPainter* painter, int y, bool state)
@ -660,10 +689,10 @@ void CPUSideBar::drawStraightArrow(QPainter* painter, int x1, int y1, int x2, in
painter->drawLine(x2 - 1, y2, x2 - ArrowSizeX, y2 + ArrowSizeY - 1);// Arrow bottom
}
void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines)
void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vector<LabelArrow> & labelArrows)
{
unsigned int* numLines = new unsigned int[viewableRows];
memset(numLines, 0, sizeof(unsigned int) * viewableRows);
unsigned int* numLines = new unsigned int[viewableRows * 2]; // Low:jump offsets of the vertical jumping line, High:jump offsets of the horizontal jumping line.
memset(numLines, 0, sizeof(unsigned int) * viewableRows * 2);
// preprocessing
for(size_t i = 0; i < jumpLines.size(); i++)
{
@ -707,6 +736,20 @@ void CPUSideBar::AllocateJumpOffsets(std::vector<JumpLine> & jumpLines)
for(int j = jmp.line; j >= jmp.destLine && j >= 0; j--)
numLines[j] = jmp.jumpOffset;
}
if(jmp.line >= 0 && jmp.line < viewableRows)
numLines[jmp.line + viewableRows] = jmp.jumpOffset;
if(jmp.destLine >= 0 && jmp.destLine < viewableRows)
numLines[jmp.destLine + viewableRows] = jmp.jumpOffset;
}
// set label arrows according to jump offsets
auto viewportWidth = viewport()->width();
const int JumpPadding = 11;
for(auto i = labelArrows.begin(); i != labelArrows.end(); i++)
{
if(numLines[i->line + viewableRows] != 0)
i->endX = viewportWidth - numLines[i->line + viewableRows] * JumpPadding - 15 - fontHeight; // This expression should be consistent with drawJump
else
i->endX = viewportWidth - 1- 11 - (isFoldingGraphicsPresent(i->line) != 0 ? mBulletRadius + fontHeight : 0);
}
delete[] numLines;
}

View File

@ -43,7 +43,6 @@ protected:
void mouseReleaseEvent(QMouseEvent* e);
void mouseMoveEvent(QMouseEvent* event);
void drawLabel(QPainter* painter, int Line, const QString & Text);
void drawBullets(QPainter* painter, int line, bool ispb, bool isbpdisabled, bool isbookmark);
bool isJump(int i) const;
void drawJump(QPainter* painter, int startLine, int endLine, int jumpoffset, bool conditional, bool isexecute, bool isactive);
@ -68,12 +67,21 @@ private:
{
int line;
int destLine;
int jumpOffset;
unsigned int jumpOffset;
bool isSelected;
bool isConditional;
bool isJumpGoingToExecute;
};
void AllocateJumpOffsets(std::vector<JumpLine> & jumpLines);
struct LabelArrow
{
int line;
int startX;
int endX;
};
void AllocateJumpOffsets(std::vector<JumpLine> & jumpLines, std::vector<LabelArrow> & labelArrows);
LabelArrow drawLabel(QPainter* painter, int Line, const QString & Text);
void drawLabelArrows(QPainter* painter, const std::vector<LabelArrow> & labelArrows);
// Configuration
QColor mBackgroundColor;

View File

@ -310,13 +310,10 @@ void CPUStack::refreshShortcutsSlot()
void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & richText)
{
// Compute RVA
dsint wRva = rva;
duint wVa = rvaToVa(wRva);
// Compute VA
duint wVa = rvaToVa(rva);
bool wActiveStack = true;
if(wVa < mCsp) //inactive stack
wActiveStack = false;
bool wActiveStack = (wVa >= mCsp); //inactive stack
STACK_COMMENT comment;
RichTextPainter::CustomRichText_t curData;
@ -337,7 +334,7 @@ void CPUStack::getColumnRichText(int col, dsint rva, RichTextPainter::List & ric
}
}
}
else if(col && DbgStackCommentGet(rvaToVa(wRva), &comment)) //paint stack comments
else if(col && DbgStackCommentGet(wVa, &comment)) //paint stack comments
{
if(wActiveStack)
{
@ -407,7 +404,7 @@ QString CPUStack::paintContent(QPainter* painter, dsint rowBase, int rowOffset,
if(background.alpha())
painter->fillRect(QRect(x, y, w, h), QBrush(background)); //fill background when defined
painter->drawText(QRect(x + 4, y , w - 4 , h), Qt::AlignVCenter | Qt::AlignLeft, makeAddrText(wVa));
return "";
return QString();
}
return HexDump::paintContent(painter, rowBase, rowOffset, col, x, y, w, h);;
}

View File

@ -13,22 +13,31 @@ CallStackView::CallStackView(StdTable* parent) : StdTable(parent)
connect(Bridge::getBridge(), SIGNAL(updateCallStack()), this, SLOT(updateCallStack()));
connect(this, SIGNAL(contextMenuSignal(QPoint)), this, SLOT(contextMenuSlot(QPoint)));
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(doubleClickedSlot()));
connect(this, SIGNAL(doubleClickedSignal()), this, SLOT(followTo()));
setupContextMenu();
}
void CallStackView::setupContextMenu()
{
mFollowAddress = new QAction(tr("Follow &Address"), this);
connect(mFollowAddress, SIGNAL(triggered()), this, SLOT(followAddress()));
mFollowTo = new QAction(tr("Follow &To"), this);
mMenuBuilder = new MenuBuilder(this, [](QMenu*)
{
return DbgIsDebugging();
});
mMenuBuilder->addAction(makeAction(tr("Follow &Address"), SLOT(followAddress())));
QAction* mFollowTo = mMenuBuilder->addAction(makeAction(tr("Follow &To"), SLOT(followTo())));
mFollowTo->setShortcutContext(Qt::WidgetShortcut);
mFollowTo->setShortcut(QKeySequence("enter"));
connect(mFollowTo, SIGNAL(triggered()), this, SLOT(followTo()));
connect(this, SIGNAL(enterPressedSignal()), this, SLOT(followTo()));
mFollowFrom = new QAction(tr("Follow &From"), this);
connect(mFollowFrom, SIGNAL(triggered()), this, SLOT(followFrom()));
mMenuBuilder->addAction(makeAction(tr("Follow &From"), SLOT(followFrom())), [this](QMenu*)
{
return !getCellContent(getInitialSelection(), 2).isEmpty();
});
MenuBuilder* mCopyMenu = new MenuBuilder(this);
setupCopyMenu(mCopyMenu);
// Column count cannot be zero
mMenuBuilder->addSeparator();
mMenuBuilder->addMenu(makeMenu(DIcon("copy.png"), tr("&Copy")), mCopyMenu);
}
void CallStackView::updateCallStack()
@ -41,13 +50,13 @@ void CallStackView::updateCallStack()
setRowCount(callstack.total);
for(int i = 0; i < callstack.total; i++)
{
QString addrText = QString("%1").arg((duint)callstack.entries[i].addr, sizeof(duint) * 2, 16, QChar('0')).toUpper();
QString addrText = ToPtrString(callstack.entries[i].addr);
setCellContent(i, 0, addrText);
addrText = QString("%1").arg((duint)callstack.entries[i].to, sizeof(duint) * 2, 16, QChar('0')).toUpper();
addrText = ToPtrString(callstack.entries[i].to);
setCellContent(i, 1, addrText);
if(callstack.entries[i].from)
{
addrText = QString("%1").arg((duint)callstack.entries[i].from, sizeof(duint) * 2, 16, QChar('0')).toUpper();
addrText = ToPtrString(callstack.entries[i].from);
setCellContent(i, 2, addrText);
}
setCellContent(i, 3, callstack.entries[i].comment);
@ -59,29 +68,11 @@ void CallStackView::updateCallStack()
void CallStackView::contextMenuSlot(const QPoint pos)
{
if(!DbgIsDebugging())
return;
QMenu wMenu(this); //create context menu
wMenu.addAction(mFollowAddress);
wMenu.addAction(mFollowTo);
QString wStr = getCellContent(getInitialSelection(), 2);
if(wStr.length())
wMenu.addAction(mFollowFrom);
QMenu wCopyMenu(tr("&Copy"), this);
setupCopyMenu(&wCopyMenu);
if(wCopyMenu.actions().length())
{
wMenu.addSeparator();
wMenu.addMenu(&wCopyMenu);
}
mMenuBuilder->build(&wMenu);
wMenu.exec(mapToGlobal(pos)); //execute context menu
}
void CallStackView::doubleClickedSlot()
{
followTo();
}
void CallStackView::followAddress()
{
QString addrText = getCellContent(getInitialSelection(), 0);

View File

@ -16,15 +16,12 @@ signals:
protected slots:
void updateCallStack();
void contextMenuSlot(const QPoint pos);
void doubleClickedSlot();
void followAddress();
void followTo();
void followFrom();
private:
QAction* mFollowAddress;
QAction* mFollowTo;
QAction* mFollowFrom;
MenuBuilder* mMenuBuilder;
};
#endif // CALLSTACKVIEW_H

View File

@ -1407,7 +1407,8 @@ void MainWindow::changeCommandLine()
void MainWindow::displayManual()
{
// Open the Windows CHM in the upper directory
QDesktopServices::openUrl(QUrl(QUrl::fromLocalFile(QString("%1/../x64dbg.chm").arg(QCoreApplication::applicationDirPath()))));
if(!QDesktopServices::openUrl(QUrl(QUrl::fromLocalFile(QString("%1/../x64dbg.chm").arg(QCoreApplication::applicationDirPath())))))
SimpleErrorBox(this, tr("Error"), tr("Manual cannot be opened. Please check if x64dbg.chm exists and ensure there is no other problems with your system."));
}
void MainWindow::decompileAt(dsint start, dsint end)

View File

@ -202,7 +202,11 @@ ThreadView::ThreadView(StdTable* parent) : StdTable(parent)
addColumnAt(8 + charwidth * 12, tr("Priority"), false);
addColumnAt(8 + charwidth * 12, tr("Wait Reason"), false);
addColumnAt(8 + charwidth * 11, tr("Last Error"), false);
addColumnAt(0, tr("Name"), false);
addColumnAt(8 + charwidth * 12, tr("User Time"), false);
addColumnAt(8 + charwidth * 12, tr("Kernel Time"), false);
addColumnAt(8 + charwidth * 15, tr("Creation Time"), false);
addColumnAt(8 + charwidth * 10, tr("CPU Cycles"), false, "", SortBy::AsInt);
addColumnAt(8, tr("Name"), false);
loadColumnFromConfig("Thread");
//setCopyMenuOnly(true);
@ -223,7 +227,7 @@ void ThreadView::updateThreadList()
for(int i = 0; i < threadList.count; i++)
{
if(!threadList.list[i].BasicInfo.ThreadNumber)
setCellContent(i, 0, "Main");
setCellContent(i, 0, tr("Main"));
else
setCellContent(i, 0, ToDecString(threadList.list[i].BasicInfo.ThreadNumber));
setCellContent(i, 1, ToHexString(threadList.list[i].BasicInfo.ThreadId));
@ -380,7 +384,11 @@ void ThreadView::updateThreadList()
}
setCellContent(i, 7, waitReasonString);
setCellContent(i, 8, QString("%1").arg(threadList.list[i].LastError, sizeof(unsigned int) * 2, 16, QChar('0')).toUpper());
setCellContent(i, 9, threadList.list[i].BasicInfo.threadName);
setCellContent(i, 9, FILETIMEToTime(threadList.list[i].UserTime));
setCellContent(i, 10, FILETIMEToTime(threadList.list[i].KernelTime));
setCellContent(i, 11, FILETIMEToDate(threadList.list[i].CreationTime));
setCellContent(i, 12, ToLongLongHexString(threadList.list[i].Cycles));
setCellContent(i, 13, threadList.list[i].BasicInfo.threadName);
}
mCurrentThreadId = "NONE";
if(threadList.count)

View File

@ -209,7 +209,7 @@ Configuration::Configuration() : QObject(), noMoreMsgbox(false)
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "CallStack", 4);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "SEH", 4);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "Script", 3);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "Thread", 10);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "Thread", 14);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "Handle", 5);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "TcpConnection", 3);
AbstractTableView::setupColumnConfigDefaultValue(guiUint, "Privilege", 2);

View File

@ -97,6 +97,11 @@ public:
return true;
}
inline bool empty() const
{
return _containers.empty();
}
private:
struct Container
{
@ -109,7 +114,8 @@ private:
};
inline Container()
: type(Separator)
: type(Separator),
action(nullptr)
{
}

View File

@ -1,4 +1,5 @@
#include <stdint.h>
#include "main.h"
#include "StringUtil.h"
#include "float128.h"
#include "MiscUtil.h"
@ -208,6 +209,7 @@ QString GetDataTypeString(void* buffer, duint size, ENCODETYPE type)
QString ToDateString(const QDate & date)
{
/*
static const char* months[] =
{
"Jan",
@ -224,4 +226,23 @@ QString ToDateString(const QDate & date)
"Dec"
};
return QString().sprintf("%s %d %d", months[date.month() - 1], date.day(), date.year());
*/
return QLocale(QString(currentLocale)).toString(date);
}
QString FILETIMEToDate(const FILETIME & date)
{
FILETIME localdate;
FileTimeToLocalFileTime(&date, &localdate);
SYSTEMTIME systime;
FileTimeToSystemTime(&localdate, &systime);
QDate qdate = QDate(systime.wYear, systime.wMonth, systime.wDay);
quint64 time100ns = (quint64)localdate.dwHighDateTime << 32 | (quint64)localdate.dwLowDateTime;
time100ns %= (1000ull * 60ull * 60ull * 24ull * 10000ull);
localdate.dwHighDateTime = time100ns >> 32;
localdate.dwLowDateTime = time100ns & 0xFFFFFFFF;
if(qdate != QDate::currentDate())
return ToDateString(qdate) + FILETIMEToTime(localdate);
else // today
return FILETIMEToTime(localdate);
}

View File

@ -17,11 +17,12 @@ static QString ToPtrString(duint Address)
// QString::arg():
// ((int32)0xFFFF0000) == 0xFFFFFFFFFFFF0000 with sign extension
//
char temp[32];
#ifdef _WIN64
char temp[33];
sprintf_s(temp, "%016llX", Address);
#else
char temp[17];
sprintf_s(temp, "%08X", Address);
#endif // _WIN64
@ -30,7 +31,7 @@ static QString ToPtrString(duint Address)
static QString ToLongLongHexString(unsigned long long Value)
{
char temp[32];
char temp[33];
sprintf_s(temp, "%llX", Value);
@ -39,7 +40,7 @@ static QString ToLongLongHexString(unsigned long long Value)
static QString ToHexString(duint Value)
{
char temp[32];
char temp[33];
#ifdef _WIN64
sprintf_s(temp, "%llX", Value);
@ -112,6 +113,22 @@ static T & ArchValue(T & x32value, T & x64value)
#endif //_WIN64
}
// Format : d:hh:mm:ss.1234567
static QString FILETIMEToTime(const FILETIME & time)
{
// FILETIME is in 100ns
quint64 time100ns = (quint64)time.dwHighDateTime << 32 | (quint64)time.dwLowDateTime;
quint64 milliseconds = time100ns / 10000;
quint64 days = milliseconds / (1000 * 60 * 60 * 24);
QTime qtime = QTime::fromMSecsSinceStartOfDay(milliseconds % (1000 * 60 * 60 * 24));
if(days == 0)
return QString().sprintf("%02d:%02d:%02d.%07lld", qtime.hour(), qtime.minute(), qtime.second(), time100ns % 10000000);
else
return QString().sprintf("%lld:%02d:%02d:%02d.%07lld", days, qtime.hour(), qtime.minute(), qtime.second(), time100ns % 10000000);
}
QString FILETIMEToDate(const FILETIME & date);
static bool GetCommentFormat(duint addr, QString & comment, bool* autoComment = nullptr)
{
comment.clear();

View File

@ -17,18 +17,16 @@ UpdateChecker::UpdateChecker(QWidget* parent)
void UpdateChecker::checkForUpdates()
{
get(QNetworkRequest(QUrl("http://jenkins.x64dbg.com/job/vs13/lastSuccessfulBuild/api/json")));
//get(QNetworkRequest(QUrl("http://jenkins.x64dbg.com/job/vs13/lastSuccessfulBuild/api/json")));
//jenkins is disabled.
SimpleErrorBox(mParent, "Error", "Cannot check for updates because the update server is down.");
}
void UpdateChecker::finishedSlot(QNetworkReply* reply)
{
if(reply->error() != QNetworkReply::NoError) //error
{
QMessageBox msg(QMessageBox::Critical, tr("Network Error!"), reply->errorString());
msg.setParent(mParent, Qt::Dialog);
msg.setWindowIcon(DIcon("compile-error.png"));
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
msg.exec();
SimpleErrorBox(mParent, tr("Network Error!"), reply->errorString());
return;
}
bool ok = false;
@ -40,11 +38,7 @@ void UpdateChecker::finishedSlot(QNetworkReply* reply)
reply->close();
if(!ok)
{
QMessageBox msg(QMessageBox::Critical, tr("Error!"), tr("File on server could not be parsed..."));
msg.setParent(mParent, Qt::Dialog);
msg.setWindowIcon(DIcon("compile-error.png"));
msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint));
msg.exec();
SimpleErrorBox(mParent, tr("Error!"), tr("File on server could not be parsed..."));
return;
}
auto server = QDateTime::fromTime_t(timestamp).date();