From 08b367e6613c167303e884d64c71ee62831687a6 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Tue, 30 Sep 2014 14:50:43 +0200 Subject: [PATCH 01/58] basic FPU support + bug fixes in registersview + titanengine update + new get context stuff --- x64_dbg_bridge/bridgemain.h | 35 +- x64_dbg_dbg/TitanEngine/TitanEngine.h | 70 +++ x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 100200 -> 100430 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.a | Bin 326424 -> 0 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 103944 -> 104178 bytes x64_dbg_dbg/_exports.cpp | 64 +- x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp | 24 +- x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp | 1 + x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 567 ++++++++++++++---- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 10 +- 10 files changed, 543 insertions(+), 228 deletions(-) delete mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x86.a diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 283d64f53..6c92f10df 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -2,6 +2,7 @@ #define _BRIDGEMAIN_H_ #include +#include "..\x64_dbg_dbg\TitanEngine\TitanEngine.h" #ifndef __cplusplus #include @@ -369,39 +370,9 @@ typedef struct typedef struct { - duint cax; - duint ccx; - duint cdx; - duint cbx; - duint csp; - duint cbp; - duint csi; - duint cdi; -#ifdef _WIN64 - duint r8; - duint r9; - duint r10; - duint r11; - duint r12; - duint r13; - duint r14; - duint r15; -#endif //_WIN64 - duint cip; - unsigned int eflags; + TITAN_ENGINE_CONTEXT_t titcontext; FLAGS flags; - unsigned short gs; - unsigned short fs; - unsigned short es; - unsigned short ds; - unsigned short cs; - unsigned short ss; - duint dr0; - duint dr1; - duint dr2; - duint dr3; - duint dr6; - duint dr7; + } REGDUMP; typedef struct diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index 58cf38ab6..c76020514 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -8,6 +8,7 @@ #endif #include +#include #pragma pack(push, 1) @@ -253,6 +254,74 @@ #define UE_SEG_CS 41 #define UE_SEG_SS 42 +#ifndef CONTEXT_EXTENDED_REGISTERS +#define CONTEXT_EXTENDED_REGISTERS 0 +#endif + +typedef struct +{ + BYTE data[10]; + int st_value; +} x87FPURegister_t; + +typedef struct +{ + DWORD ControlWord; + DWORD StatusWord; + DWORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + x87FPURegister_t x87FPURegister[8]; + DWORD Cr0NpxState; +} x87FPU_t; + +typedef struct +{ + ULONG_PTR cax; + ULONG_PTR ccx; + ULONG_PTR cdx; + ULONG_PTR cbx; + ULONG_PTR csp; + ULONG_PTR cbp; + ULONG_PTR csi; + ULONG_PTR cdi; +#ifdef _WIN64 + ULONG_PTR r8; + ULONG_PTR r9; + ULONG_PTR r10; + ULONG_PTR r11; + ULONG_PTR r12; + ULONG_PTR r13; + ULONG_PTR r14; + ULONG_PTR r15; +#endif //_WIN64 + ULONG_PTR cip; + unsigned int eflags; + unsigned short gs; + unsigned short fs; + unsigned short es; + unsigned short ds; + unsigned short cs; + unsigned short ss; + ULONG_PTR dr0; + ULONG_PTR dr1; + ULONG_PTR dr2; + ULONG_PTR dr3; + ULONG_PTR dr6; + ULONG_PTR dr7; + BYTE RegisterArea[80]; + x87FPU_t x87fpu; + DWORD MxCsr; + uint64_t mmx[8]; +#ifdef _WIN64 + M128A XmmRegisters[16]; +#else // x86 + M128A XmmRegisters[8]; +#endif +} TITAN_ENGINE_CONTEXT_t; + typedef struct { DWORD PE32Offset; @@ -696,6 +765,7 @@ __declspec(dllexport) bool TITCALL SetMemoryBPX(ULONG_PTR MemoryStart, SIZE_T Si __declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack); __declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory); __declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); +__declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister); __declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister); __declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib index 96105936000ecfd42e8d67d1dcb1562eeca04bb7..64b135338a754e3a4a3f0151edca29d0fcbb8cf1 100644 GIT binary patch delta 18856 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
  • s4VXvu01=hL`-DfO!ZdvkF&iJZZ7Sg4yAzkCu2jkh6 z<<33L1eH9237Ct}MD^?hp8b5jo1|(@G-8l%{w5=bWB(MO9-qi&AM%3sZzGj62?uJg zNvzVGt@HK$L24csF(P@2`g{_LWcEV>^`FT&%jQnz%8ei@P`f7c*@G(eq)5+63TaZ5 z{|r>UA7axFnXW}>gs0ge0qU)X*ch7&)pQk=U)4N4D74j^p`OTR22g5izeKBoDL7;Y zPT{5-bK6WcV+wOR-5E?_Luc$+Fl$iezyWzPiVCLZSuvLzyGdj`t(*<#CTB#b!l}F+ z;|1Itb!aL(Qy9TNSM@1i!GD+S-#j$X@6V0Yg#zwEdTK|HgtZ^(*!3{^G5L*X^-v*8 zRx=Qap=#xyLlyq>fUmi=r(+PdX4L9wV^@5G#1BhV|HQb&SCs#%^V+pA&L&`E`P)~@fu{@BCMsJsQ-!+e9eMt$~&bpKUL}>X+1H$J)?zH8M}?>zr7Uai9QGGf*g`h!b~w{ZC>`+h5^9}Vxsd%x zMXR70M+?yG_aX@dTID0_Rec#szd|-%XsxF}T026&&2-NXcB95GV_s5GkMKtMdc8rt z^avkE1cBai(~9;N^xE&OVAXUn3lq~Z8zGW4D#XZ6bIJRwy1kf>i1Bh7zfoAi^PfgU tH&1Ks-=I5bbdb8WggKp!=-x7nXkpnOj_BXjp)xk2Mh0(E-IvNn{|Agu?=1iT delta 18602 zcma)?34BgR+y7@sH6=)7-yE7FQCnM8l=pYdIl0eF^7?=NKA*3-?=#oA=9+7nnRD*!UtH

    gl=jp2Vem4&D{P>9d=3$e{xh%Y+`@!b}i?<)ww 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 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a deleted file mode 100644 index 6fdc39f74a5d337ef527bf4e57e11110ae1519bf..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 326424 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 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index 17f6c591a49ac6fdf46bcfe2df737af9d6741e5a..b8a422d47a2458a388d55d4976f3e4c41da85b97 100644 GIT binary patch delta 18335 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 QI^E7nu6O9Wb+X3)0wmO`lK=n! delta 18220 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 diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index b59c02d71..c0d6e9f82 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -340,59 +340,19 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) return true; } - REGDUMP & r = *regdump; + if(!GetFullContextDataEx(hActiveThread, & (regdump->titcontext))) + return false; -#ifdef _WIN64 - r.cax = GetContextDataEx(hActiveThread, UE_RAX); - r.ccx = GetContextDataEx(hActiveThread, UE_RCX); - r.cdx = GetContextDataEx(hActiveThread, UE_RDX); - r.cbx = GetContextDataEx(hActiveThread, UE_RBX); - r.cbp = GetContextDataEx(hActiveThread, UE_RBP); - r.csi = GetContextDataEx(hActiveThread, UE_RSI); - r.cdi = GetContextDataEx(hActiveThread, UE_RDI); - r.r8 = GetContextDataEx(hActiveThread, UE_R8); - r.r9 = GetContextDataEx(hActiveThread, UE_R9); - r.r10 = GetContextDataEx(hActiveThread, UE_R10); - r.r11 = GetContextDataEx(hActiveThread, UE_R11); - r.r12 = GetContextDataEx(hActiveThread, UE_R12); - r.r13 = GetContextDataEx(hActiveThread, UE_R13); - r.r14 = GetContextDataEx(hActiveThread, UE_R14); - r.r15 = GetContextDataEx(hActiveThread, UE_R15); -#else - r.cax = GetContextDataEx(hActiveThread, UE_EAX); - r.ccx = GetContextDataEx(hActiveThread, UE_ECX); - r.cdx = GetContextDataEx(hActiveThread, UE_EDX); - r.cbx = GetContextDataEx(hActiveThread, UE_EBX); - r.cbp = GetContextDataEx(hActiveThread, UE_EBP); - r.csi = GetContextDataEx(hActiveThread, UE_ESI); - r.cdi = GetContextDataEx(hActiveThread, UE_EDI); -#endif - - r.csp = GetContextDataEx(hActiveThread, UE_CSP); - r.cip = GetContextDataEx(hActiveThread, UE_CIP); - r.eflags = (unsigned int)GetContextDataEx(hActiveThread, UE_EFLAGS); - r.gs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_GS) & 0xFFFF); - r.fs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_FS) & 0xFFFF); - r.es = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_ES) & 0xFFFF); - r.ds = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_DS) & 0xFFFF); - r.cs = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_CS) & 0xFFFF); - r.ss = (unsigned short)(GetContextDataEx(hActiveThread, UE_SEG_SS) & 0xFFFF); - r.dr0 = GetContextDataEx(hActiveThread, UE_DR0); - r.dr1 = GetContextDataEx(hActiveThread, UE_DR1); - r.dr2 = GetContextDataEx(hActiveThread, UE_DR2); - r.dr3 = GetContextDataEx(hActiveThread, UE_DR3); - r.dr6 = GetContextDataEx(hActiveThread, UE_DR6); - r.dr7 = GetContextDataEx(hActiveThread, UE_DR7); - duint cflags = r.eflags; - r.flags.c = valflagfromstring(cflags, "cf"); - r.flags.p = valflagfromstring(cflags, "pf"); - r.flags.a = valflagfromstring(cflags, "af"); - r.flags.z = valflagfromstring(cflags, "zf"); - r.flags.s = valflagfromstring(cflags, "sf"); - r.flags.t = valflagfromstring(cflags, "tf"); - r.flags.i = valflagfromstring(cflags, "if"); - r.flags.d = valflagfromstring(cflags, "df"); - r.flags.o = valflagfromstring(cflags, "of"); + duint cflags = regdump->titcontext.eflags; + regdump->flags.c = valflagfromstring(cflags, "cf"); + regdump->flags.p = valflagfromstring(cflags, "pf"); + regdump->flags.a = valflagfromstring(cflags, "af"); + regdump->flags.z = valflagfromstring(cflags, "zf"); + regdump->flags.s = valflagfromstring(cflags, "sf"); + regdump->flags.t = valflagfromstring(cflags, "tf"); + regdump->flags.i = valflagfromstring(cflags, "if"); + regdump->flags.d = valflagfromstring(cflags, "df"); + regdump->flags.o = valflagfromstring(cflags, "of"); return true; } diff --git a/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp b/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp index fb52b3ef3..9b6508dc6 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp @@ -158,19 +158,19 @@ void CPUSideBar::paintEvent(QPaintEvent* event) const int_t cur_VA = CodePtr->getBase() + InstrBuffer->at(line).rva; #ifdef _WIN64 - if(cur_VA == regDump.cax) drawLabel(&painter, line, "RAX"); - if(cur_VA == regDump.cbx) drawLabel(&painter, line, "RBX"); - if(cur_VA == regDump.ccx) drawLabel(&painter, line, "RCX"); - if(cur_VA == regDump.cdx) drawLabel(&painter, line, "RDX"); - if(cur_VA == regDump.csi) drawLabel(&painter, line, "RSI"); - if(cur_VA == regDump.cdi) drawLabel(&painter, line, "RDI"); + if(cur_VA == regDump.titcontext.cax) drawLabel(&painter, line, "RAX"); + if(cur_VA == regDump.titcontext.cbx) drawLabel(&painter, line, "RBX"); + if(cur_VA == regDump.titcontext.ccx) drawLabel(&painter, line, "RCX"); + if(cur_VA == regDump.titcontext.cdx) drawLabel(&painter, line, "RDX"); + if(cur_VA == regDump.titcontext.csi) drawLabel(&painter, line, "RSI"); + if(cur_VA == regDump.titcontext.cdi) drawLabel(&painter, line, "RDI"); #else //x86 - if(cur_VA == regDump.cax) drawLabel(&painter, line, "EAX"); - if(cur_VA == regDump.cbx) drawLabel(&painter, line, "EBX"); - if(cur_VA == regDump.ccx) drawLabel(&painter, line, "ECX"); - if(cur_VA == regDump.cdx) drawLabel(&painter, line, "EDX"); - if(cur_VA == regDump.csi) drawLabel(&painter, line, "ESI"); - if(cur_VA == regDump.cdi) drawLabel(&painter, line, "EDI"); + if(cur_VA == regDump.titcontext.cax) drawLabel(&painter, line, "EAX"); + if(cur_VA == regDump.titcontext.cbx) drawLabel(&painter, line, "EBX"); + if(cur_VA == regDump.titcontext.ccx) drawLabel(&painter, line, "ECX"); + if(cur_VA == regDump.titcontext.cdx) drawLabel(&painter, line, "EDX"); + if(cur_VA == regDump.titcontext.csi) drawLabel(&painter, line, "ESI"); + if(cur_VA == regDump.titcontext.cdi) drawLabel(&painter, line, "EDI"); #endif } diff --git a/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp b/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp index 52d0e331b..af739e32c 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp @@ -33,6 +33,7 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget) mGeneralRegs = new RegistersView(0); mGeneralRegs->setFixedWidth(1000); + mGeneralRegs->setFixedHeight(700); QScrollArea* scrollArea = new QScrollArea; scrollArea->setWidget(mGeneralRegs); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 0e78e6905..17ffddfbb 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -2,6 +2,7 @@ #include #include "Configuration.h" #include "WordEditDialog.h" +#include "LineEditDialog.h" RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) @@ -64,6 +65,24 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFlags.insert(DF); mFlags.insert(OF); + // FPU x87 and MMX registers + mFPUx87.insert(x87r0); + mFPUx87.insert(x87r1); + mFPUx87.insert(x87r2); + mFPUx87.insert(x87r3); + mFPUx87.insert(x87r4); + mFPUx87.insert(x87r5); + mFPUx87.insert(x87r6); + mFPUx87.insert(x87r7); + mFPUMMX.insert(MM0); + mFPUMMX.insert(MM1); + mFPUMMX.insert(MM2); + mFPUMMX.insert(MM3); + mFPUMMX.insert(MM4); + mFPUMMX.insert(MM5); + mFPUMMX.insert(MM6); + mFPUMMX.insert(MM7); + //registers that should not be changed mNoChange.insert(GS); mNoChange.insert(FS); @@ -191,18 +210,57 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterPlaces.insert(SS, Register_Position(offset + 5, 9, 3, 4)); offset++; + + mRegisterMapping.insert(x87r0, "x87r0"); + mRegisterPlaces.insert(x87r0, Register_Position(offset + 6, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r1, "x87r1"); + mRegisterPlaces.insert(x87r1, Register_Position(offset + 7, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r2, "x87r2"); + mRegisterPlaces.insert(x87r2, Register_Position(offset + 8, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r3, "x87r3"); + mRegisterPlaces.insert(x87r3, Register_Position(offset + 9, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r4, "x87r4"); + mRegisterPlaces.insert(x87r4, Register_Position(offset + 10, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r5, "x87r5"); + mRegisterPlaces.insert(x87r5, Register_Position(offset + 11, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r6, "x87r6"); + mRegisterPlaces.insert(x87r6, Register_Position(offset + 12, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r7, "x87r7"); + mRegisterPlaces.insert(x87r7, Register_Position(offset + 13, 0, 6, 10 * 2)); + + offset++; + + mRegisterMapping.insert(MM0, "MM0"); + mRegisterPlaces.insert(MM0, Register_Position(offset + 14, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM1, "MM1"); + mRegisterPlaces.insert(MM1, Register_Position(offset + 15, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM2, "MM2"); + mRegisterPlaces.insert(MM2, Register_Position(offset + 16, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM3, "MM3"); + mRegisterPlaces.insert(MM3, Register_Position(offset + 17, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM4, "MM4"); + mRegisterPlaces.insert(MM4, Register_Position(offset + 18, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM5, "MM5"); + mRegisterPlaces.insert(MM5, Register_Position(offset + 19, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM6, "MM6"); + mRegisterPlaces.insert(MM6, Register_Position(offset + 20, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM7, "MM7"); + mRegisterPlaces.insert(MM7, Register_Position(offset + 21, 0, 4, 8 * 2)); + + offset++; + mRegisterMapping.insert(DR0, "DR0"); - mRegisterPlaces.insert(DR0, Register_Position(offset + 6, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR0, Register_Position(offset + 22, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR1, "DR1"); - mRegisterPlaces.insert(DR1, Register_Position(offset + 7, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR1, Register_Position(offset + 23, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR2, "DR2"); - mRegisterPlaces.insert(DR2, Register_Position(offset + 8, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR2, Register_Position(offset + 24, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR3, "DR3"); - mRegisterPlaces.insert(DR3, Register_Position(offset + 9, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR3, Register_Position(offset + 25, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR6, "DR6"); - mRegisterPlaces.insert(DR6, Register_Position(offset + 10, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR6, Register_Position(offset + 26, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR7, "DR7"); - mRegisterPlaces.insert(DR7, Register_Position(offset + 11, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR7, Register_Position(offset + 27, 0, 4, sizeof(uint_t) * 2)); fontsUpdatedSlot(); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); @@ -332,8 +390,8 @@ void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) // do we find a corresponding register? if(!identifyRegister(y, x, 0)) return; - // is current register general purposes register ? - if(mGPR.contains(mSelected)) + // is current register general purposes register or FPU register? + if(mGPR.contains(mSelected) || mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) { wCM_Modify->trigger(); } @@ -379,19 +437,19 @@ QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) char module_text[MAX_MODULE_SIZE] = ""; char string_text[MAX_STRING_SIZE] = ""; - QString valueText = QString("%1").arg(registerValue(&wRegDumpStruct, register_selected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - duint register_value = registerValue(&wRegDumpStruct, register_selected); + QString valueText = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, register_selected))), mRegisterPlaces[register_selected].valuesize, 16, QChar('0')).toUpper(); + duint register_value = (* ((uint_t*) registerValue(&wRegDumpStruct, register_selected))); QString newText = QString(""); bool hasString = DbgGetStringAt(register_value, string_text); bool hasLabel = DbgGetLabelAt(register_value, SEG_DEFAULT, label_text); bool hasModule = DbgGetModuleAt(register_value, module_text); - if(hasString) + if(hasString && register_selected != CIP) { newText = string_text; } - else if(hasLabel && hasModule) + else if(hasLabel && hasModule && register_selected != CIP) { newText = "<" + QString(module_text) + "." + QString(label_text) + ">"; } @@ -399,18 +457,161 @@ QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) { newText = QString(module_text) + "." + valueText; } - else if(hasLabel) + else if(hasLabel && register_selected != CIP) { newText = "<" + QString(label_text) + ">"; } + else if(register_selected != CIP) + { + bool isCharacter = false; + if(register_value == (register_value & 0xFF)) + { + QChar c = QChar((char)register_value); + if(c.isPrint()) + { + newText = QString("'%1'").arg((char)register_value); + isCharacter = IsCharacterRegister(register_selected); + } + } + else if(register_value == (register_value & 0xFFF)) //UNICODE? + { + QChar c = QChar((wchar_t)register_value); + if(c.isPrint()) + { + newText = "L'" + QString(c) + "'"; + isCharacter = IsCharacterRegister(register_selected); + } + } + } return newText; } -void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, uint_t value) + +#include +#include +double readFloat80(const uint8_t buffer[10]) +{ + /* + * WE ARE LOSSING 2 BYTES WITH THIS FUNCTION. + * TODO: CHANGE THIS FOR ONE BETTER. + */ + //80 bit floating point value according to IEEE-754: + //1 bit sign, 15 bit exponent, 64 bit mantissa + + const uint16_t SIGNBIT = 1 << 15; + const uint16_t EXP_BIAS = (1 << 14) - 1; // 2^(n-1) - 1 = 16383 + const uint16_t SPECIALEXP = (1 << 15) - 1; // all bits set + const uint64_t HIGHBIT = (uint64_t)1 << 63; + const uint64_t QUIETBIT = (uint64_t)1 << 62; + + // Extract sign, exponent and mantissa + uint16_t exponent = *((uint16_t*)&buffer[8]); + uint64_t mantissa = *((uint64_t*)&buffer[0]); + + double sign = (exponent & SIGNBIT) ? -1.0 : 1.0; + exponent &= ~SIGNBIT; + + // Check for undefined values + if((!exponent && (mantissa & HIGHBIT)) || (exponent && !(mantissa & HIGHBIT))) + { + return std::numeric_limits::quiet_NaN(); + } + + // Check for special values (infinity, NaN) + if(exponent == 0) + { + if(mantissa == 0) + { + return sign * 0.0; + } + else + { + // denormalized + } + } + else if(exponent == SPECIALEXP) + { + if(!(mantissa & ~HIGHBIT)) + { + return sign * std::numeric_limits::infinity(); + } + else + { + if(mantissa & QUIETBIT) + { + return std::numeric_limits::quiet_NaN(); + } + else + { + return std::numeric_limits::signaling_NaN(); + } + } + } + + //value = (-1)^s * (m / 2^63) * 2^(e - 16383) + double significand = ((double)mantissa / ((uint64_t)1 << 63)); + return sign * ldexp(significand, exponent - EXP_BIAS); +} + +void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) { // is the register-id known? if(mRegisterMapping.contains(reg)) { + uint_t nouint_value; + bool enable_label_detection = false; + switch(reg) + { + case CAX: + case CCX: + case CDX: + case CBX: + case CDI: + case CBP: + case CSI: + case CSP: + case R8: + case R9: + case R10: + case R11: + case R12: + case R13: + case R14: + case R15: + case CIP: + case DR0: + case DR1: + case DR2: + case DR3: + case DR6: + case DR7: + enable_label_detection = true; + break; + + case CF: + case PF: + case AF: + case ZF: + case SF: + case TF: + case IF: + case DF: + case OF: + nouint_value = * ((bool*) value); + value = (char*) & nouint_value; + break; + + case GS: + case FS: + case ES: + case DS: + case CS: + case SS: + nouint_value = * ((unsigned short*) value); + value = (char*) & nouint_value; + break; + } + // padding to the left is at least one character (looks better) int x = mCharWidth * (1 + mRegisterPlaces[reg].start); int ySpace = yTopSpacing; @@ -446,58 +647,61 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, uint_t value) //p->fillRect(QRect(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line)+2, mRegisterPlaces[reg].valuesize*mCharWidth, mRowHeight), QBrush(ConfigColor("RegistersSelectionColor"))); } + QString valueText; // draw value - QString valueText = QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + if(mFPUx87.contains(reg) || mFPUMMX.contains(reg)) + { + SIZE_T size; + if(mFPUx87.contains(reg)) + size = 10; + else + size = 8; + valueText = QString(QByteArray(value, size).toHex()).toUpper(); + } + else + valueText = QString("%1").arg((* ((uint_t*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); width = mCharWidth * valueText.length(); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText); //p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper()); - // do we have a label ? - QString newText = getRegisterLabel(reg); - bool isCharacter = false; x += valueText.length() * mCharWidth; - x += 5 * mCharWidth; //5 spaces - bool has_label; - if(newText != "") - has_label = true; - else + if((mFPUx87.contains(reg) || mFPUMMX.contains(reg)) && DbgIsDebugging()) { - has_label = false; - // can we interpret the character as ASCII ?? - if(mGPR.contains(reg)) + x += 1 * mCharWidth; //1 space + QString newText; + if(mFPUx87.contains(reg)) { - if(value == (value & 0xFF)) - { - QChar c = QChar((char)value); - if(c.isPrint()) - { - newText = QString("'%1'").arg((char)value); - isCharacter = IsCharacterRegister(reg); - } - } - else if(value == (value & 0xFFF)) //UNICODE? - { - QChar c = QChar((wchar_t)value); - if(c.isPrint()) - { - newText = "L'" + QString(c) + "'"; - isCharacter = IsCharacterRegister(reg); - } - } + newText = QString("ST%1 ").arg(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->st_value); + newText += QString::number(readFloat80(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); + } + else + { + newText = QString::number(* (double*)(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); } - } - // are there additional informations? - if(has_label || isCharacter) - { width = newText.length() * mCharWidth; p->setPen(ConfigColor("RegistersExtraInfoColor")); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); - //p->drawText(x,mRowHeight*(mRegisterPlaces[reg].line+1),newText); + } + + // do we have a label ? + if(enable_label_detection) + { + x += 5 * mCharWidth; //5 spaces + + QString newText = getRegisterLabel(reg); + + // are there additional informations? + if(newText != "") + { + width = newText.length() * mCharWidth; + p->setPen(ConfigColor("RegistersExtraInfoColor")); + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + //p->drawText(x,mRowHeight*(mRegisterPlaces[reg].line+1),newText); + } } } - } void RegistersView::updateRegistersSlot() @@ -512,22 +716,46 @@ void RegistersView::updateRegistersSlot() void RegistersView::displayEditDialog() { - WordEditDialog wEditDial(this); - wEditDial.setup(QString("Edit"), registerValue(&wRegDumpStruct, mSelected), sizeof(int_t)); - if(wEditDial.exec() == QDialog::Accepted) //OK button clicked - setRegister(mSelected, wEditDial.getVal()); + if(!mFPUx87.contains(mSelected) && !mFPUMMX.contains(mSelected)) + { + WordEditDialog wEditDial(this); + wEditDial.setup(QString("Edit"), (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), sizeof(int_t)); + if(wEditDial.exec() == QDialog::Accepted) //OK button clicked + setRegister(mSelected, wEditDial.getVal()); + } + else + { + /* + LineEditDialog mLineEdit(this); + SIZE_T size; + if (mFPUx87.contains(mSelected)) + size = 10 * 2; + else if (mFPUMMX.contains(mSelected)) + size = 8 * 2; + else + size = sizeof(int_t) * 2; + + mLineEdit.setText(QString("%1").arg((uint_t)registerValue(&wRegDumpStruct, mSelected), size, 16, QChar('0')).toUpper()); + mLineEdit.setWindowTitle("Edit FPU register"); + mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); + mLineEdit.setCursorPosition(0); + + if(mLineEdit.exec() != QDialog::Accepted) + return; //pressed cancel + */ + } } void RegistersView::onIncrementAction() { if(mGPR.contains(mSelected)) - setRegister(mSelected, registerValue(&wRegDumpStruct, mSelected) + 1); + setRegister(mSelected, (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) + 1); } void RegistersView::onDecrementAction() { if(mGPR.contains(mSelected)) - setRegister(mSelected, registerValue(&wRegDumpStruct, mSelected) - 1); + setRegister(mSelected, (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) - 1); } void RegistersView::onZeroAction() @@ -544,17 +772,20 @@ void RegistersView::onSetToOneAction() void RegistersView::onModifyAction() { - if(mGPR.contains(mSelected)) + if(mGPR.contains(mSelected) || mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) displayEditDialog(); } void RegistersView::onToggleValueAction() { if(mFlags.contains(mSelected)) - setRegister(mSelected, ((int)registerValue(&wRegDumpStruct, mSelected)) ^ 1); + { + int value = (int)(* (bool*) registerValue(&wRegDumpStruct, mSelected)); + setRegister(mSelected, value ^ 1); + } else { - int_t val = registerValue(&wRegDumpStruct, mSelected); + int_t val = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); val++; val *= -1; setRegister(mSelected, val); @@ -564,23 +795,45 @@ void RegistersView::onToggleValueAction() void RegistersView::onCopyToClipboardAction() { QClipboard* clipboard = QApplication::clipboard(); - clipboard->setText(QString("%1").arg((uint_t)registerValue(&wRegDumpStruct, mSelected), sizeof(int_t) * 2, 16, QChar('0')).toUpper()); + QString valueText; + if(mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) + { + SIZE_T size; + char* value; + if(mFPUx87.contains(mSelected)) + { + value = (char*)((x87FPURegister_t*) registerValue(&wRegDumpStruct, mSelected))->data; + size = 10; + } + else + { + value = (char*) registerValue(&wRegDumpStruct, mSelected); + size = 8; + } + valueText = QString(QByteArray(value, size).toHex()).toUpper(); + } + else + valueText = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + clipboard->setText(valueText); } void RegistersView::onCopySymbolToClipboardAction() { - QClipboard* clipboard = QApplication::clipboard(); - QString symbol = getRegisterLabel(mSelected); - if(symbol != "") - clipboard->setText(symbol); + if(mGPR.contains(mSelected)) + { + QClipboard* clipboard = QApplication::clipboard(); + QString symbol = getRegisterLabel(mSelected); + if(symbol != "") + clipboard->setText(symbol); + } } void RegistersView::onFollowInDisassembly() { if(mGPR.contains(mSelected)) { - QString addr = QString("%1").arg(registerValue(&wRegDumpStruct, mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - if(DbgMemIsValidReadPtr(registerValue(&wRegDumpStruct, mSelected))) + QString addr = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + if(DbgMemIsValidReadPtr((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))))) DbgCmdExec(QString().sprintf("disasm \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); } } @@ -589,8 +842,8 @@ void RegistersView::onFollowInDump() { if(mGPR.contains(mSelected)) { - QString addr = QString("%1").arg(registerValue(&wRegDumpStruct, mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - if(DbgMemIsValidReadPtr(registerValue(&wRegDumpStruct, mSelected))) + QString addr = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + if(DbgMemIsValidReadPtr((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))))) DbgCmdExec(QString().sprintf("dump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); } } @@ -599,8 +852,8 @@ void RegistersView::onFollowInStack() { if(mGPR.contains(mSelected)) { - QString addr = QString("%1").arg(registerValue(&wRegDumpStruct, mSelected), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - if(DbgMemIsValidReadPtr(registerValue(&wRegDumpStruct, mSelected))) + QString addr = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); + if(DbgMemIsValidReadPtr((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))))) DbgCmdExec(QString().sprintf("sdump \"%s\"", addr.toUtf8().constData()).toUtf8().constData()); } } @@ -613,30 +866,34 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) if(mSelected != UNKNOWN) { - if(!mNoChange.contains(mSelected)) + if(!mNoChange.contains(mSelected) && !mFPUx87.contains(mSelected) && !mFPUMMX.contains(mSelected)) { - if(registerValue(&wRegDumpStruct, mSelected) >= 1) + if((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) >= 1) wMenu.addAction(wCM_Zero); - if(registerValue(&wRegDumpStruct, mSelected) == 0) + if((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) == 0) wMenu.addAction(wCM_SetToOne); wMenu.addAction(wCM_ToggleValue); } - if(mGPR.contains(mSelected)) + if(mGPR.contains(mSelected) || mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) { wMenu.addAction(wCM_Modify); - wMenu.addAction(wCM_Increment); - wMenu.addAction(wCM_Decrement); - uint_t addr = registerValue(&wRegDumpStruct, mSelected); - if(DbgMemIsValidReadPtr(addr)) + if(mGPR.contains(mSelected)) { - wMenu.addAction(wCM_FollowInDump); - wMenu.addAction(wCM_FollowInDisassembly); - duint size = 0; - duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); - if(addr >= base && addr < base + size) - wMenu.addAction(wCM_FollowInStack); + wMenu.addAction(wCM_Increment); + wMenu.addAction(wCM_Decrement); + + uint_t addr = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); + if(DbgMemIsValidReadPtr(addr)) + { + wMenu.addAction(wCM_FollowInDump); + wMenu.addAction(wCM_FollowInDisassembly); + duint size = 0; + duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); + if(addr >= base && addr < base + size) + wMenu.addAction(wCM_FollowInStack); + } } } wMenu.addAction(wCM_CopyToClipboard); @@ -695,76 +952,126 @@ void RegistersView::repaint() this->viewport()->repaint(); } -int_t RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) + +uint_t RegistersView::GetUintValue(REGISTER_NAME reg, char* value) { + switch(reg) + { + case CF: + case PF: + case AF: + case ZF: + case SF: + case TF: + case IF: + case DF: + case OF: + return (uint_t) * ((bool*) value); + break; + + case GS: + case FS: + case ES: + case DS: + case CS: + case SS: + return (uint_t) * ((unsigned short*) value); + break; + } + + return * ((uint_t*) value); +} + +char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) +{ + static int null_value = 0; // this is probably the most efficient general method to access the values of the struct - if(reg == CAX) return regd->cax; - if(reg == CBX) return regd->cbx; - if(reg == CCX) return regd->ccx; - if(reg == CDX) return regd->cdx; - if(reg == CSI) return regd->csi; - if(reg == CDI) return regd->cdi; - if(reg == CBP) return regd->cbp; - if(reg == CSP) return regd->csp; + if(reg == CAX) return (char*) & (regd->titcontext.cax); + if(reg == CBX) return (char*) & (regd->titcontext.cbx); + if(reg == CCX) return (char*) & (regd->titcontext.ccx); + if(reg == CDX) return (char*) & (regd->titcontext.cdx); + if(reg == CSI) return (char*) & (regd->titcontext.csi); + if(reg == CDI) return (char*) & (regd->titcontext.cdi); + if(reg == CBP) return (char*) & (regd->titcontext.cbp); + if(reg == CSP) return (char*) & (regd->titcontext.csp); - if(reg == CIP) return regd->cip; - if(reg == EFLAGS) return regd->eflags; + if(reg == CIP) return (char*) & (regd->titcontext.cip); + if(reg == EFLAGS) return (char*) & (regd->titcontext.eflags); #ifdef _WIN64 - if(reg == R8) return regd->r8; - if(reg == R9) return regd->r9; - if(reg == R10) return regd->r10; - if(reg == R11) return regd->r11; - if(reg == R12) return regd->r12; - if(reg == R13) return regd->r13; - if(reg == R14) return regd->r14; - if(reg == R15) return regd->r15; + if(reg == R8) return (char*) & (regd->titcontext.r8); + if(reg == R9) return (char*) & (regd->titcontext.r9); + if(reg == R10) return (char*) & (regd->titcontext.r10); + if(reg == R11) return (char*) & (regd->titcontext.r11); + if(reg == R12) return (char*) & (regd->titcontext.r12); + if(reg == R13) return (char*) & (regd->titcontext.r13); + if(reg == R14) return (char*) & (regd->titcontext.r14); + if(reg == R15) return (char*) & (regd->titcontext.r15); #endif // CF,PF,AF,ZF,SF,TF,IF,DF,OF - if(reg == CF) return regd->flags.c; - if(reg == PF) return regd->flags.p; - if(reg == AF) return regd->flags.a; - if(reg == ZF) return regd->flags.z; - if(reg == SF) return regd->flags.s; - if(reg == TF) return regd->flags.t; - if(reg == IF) return regd->flags.i; - if(reg == DF) return regd->flags.d; - if(reg == OF) return regd->flags.o; + if(reg == CF) return (char*) & (regd->flags.c); + if(reg == PF) return (char*) & (regd->flags.p); + if(reg == AF) return (char*) & (regd->flags.a); + if(reg == ZF) return (char*) & (regd->flags.z); + if(reg == SF) return (char*) & (regd->flags.s); + if(reg == TF) return (char*) & (regd->flags.t); + if(reg == IF) return (char*) & (regd->flags.i); + if(reg == DF) return (char*) & (regd->flags.d); + if(reg == OF) return (char*) & (regd->flags.o); // GS,FS,ES,DS,CS,SS - if(reg == GS) return regd->gs; - if(reg == FS) return regd->fs; - if(reg == ES) return regd->es; - if(reg == DS) return regd->ds; - if(reg == CS) return regd->cs; - if(reg == SS) return regd->ss; + if(reg == GS) return (char*) & (regd->titcontext.gs); + if(reg == FS) return (char*) & (regd->titcontext.fs); + if(reg == ES) return (char*) & (regd->titcontext.es); + if(reg == DS) return (char*) & (regd->titcontext.ds); + if(reg == CS) return (char*) & (regd->titcontext.cs); + if(reg == SS) return (char*) & (regd->titcontext.ss); - if(reg == DR0) return regd->dr0; - if(reg == DR1) return regd->dr1; - if(reg == DR2) return regd->dr2; - if(reg == DR3) return regd->dr3; - if(reg == DR6) return regd->dr6; - if(reg == DR7) return regd->dr7; + if(reg == DR0) return (char*) & (regd->titcontext.dr0); + if(reg == DR1) return (char*) & (regd->titcontext.dr1); + if(reg == DR2) return (char*) & (regd->titcontext.dr2); + if(reg == DR3) return (char*) & (regd->titcontext.dr3); + if(reg == DR6) return (char*) & (regd->titcontext.dr6); + if(reg == DR7) return (char*) & (regd->titcontext.dr7); - return 0; + if(reg == MM0) return (char*) & (regd->titcontext.mmx[0]); + if(reg == MM1) return (char*) & (regd->titcontext.mmx[1]); + if(reg == MM2) return (char*) & (regd->titcontext.mmx[2]); + if(reg == MM3) return (char*) & (regd->titcontext.mmx[3]); + if(reg == MM4) return (char*) & (regd->titcontext.mmx[4]); + if(reg == MM5) return (char*) & (regd->titcontext.mmx[5]); + if(reg == MM6) return (char*) & (regd->titcontext.mmx[6]); + if(reg == MM7) return (char*) & (regd->titcontext.mmx[7]); + + if(reg == x87r0) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[0]); + if(reg == x87r1) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[1]); + if(reg == x87r2) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[2]); + if(reg == x87r3) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[3]); + if(reg == x87r4) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[4]); + if(reg == x87r5) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[5]); + if(reg == x87r6) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[6]); + if(reg == x87r7) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[7]); + + return (char*) & null_value; } void RegistersView::setRegisters(REGDUMP* reg) { // tests if new-register-value == old-register-value holds - if(mCip != reg->cip) //CIP changed + if(mCip != reg->titcontext.cip) //CIP changed { wCipRegDumpStruct = wRegDumpStruct; mRegisterUpdates.clear(); - mCip = reg->cip; + mCip = reg->titcontext.cip; } QMap::const_iterator it = mRegisterMapping.begin(); // iterate all ids (CAX, CBX, ...) while(it != mRegisterMapping.end()) { - // does a register-value change happens? - if(registerValue(reg, it.key()) != registerValue(&wCipRegDumpStruct, it.key())) + uint_t old_value = GetUintValue((REGISTER_NAME) it.key(), registerValue(reg, it.key())); + uint_t new_value = GetUintValue((REGISTER_NAME) it.key(), registerValue(&wCipRegDumpStruct, it.key())); + if(old_value != new_value) mRegisterUpdates.insert(it.key()); else if(mRegisterUpdates.contains(it.key())) //registers are equal mRegisterUpdates.remove(it.key()); @@ -774,7 +1081,7 @@ void RegistersView::setRegisters(REGDUMP* reg) // now we can save the values wRegDumpStruct = (*reg); - if(mCip != reg->cip) + if(mCip != reg->titcontext.cip) wCipRegDumpStruct = wRegDumpStruct; // force repaint diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 8409a7c2b..469b07714 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -27,6 +27,8 @@ public: EFLAGS, CF, PF, AF, ZF, SF, TF, IF, DF, OF, GS, FS, ES, DS, CS, SS, DR0, DR1, DR2, DR3, DR6, DR7, + x87r0, x87r1, x87r2, x87r3, x87r4, x87r5, x87r6, x87r7, + MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, UNKNOWN }; @@ -78,9 +80,9 @@ protected: virtual void keyPressEvent(QKeyEvent* event); // use-in-class-only methods - void drawRegister(QPainter* p, REGISTER_NAME reg, uint_t value); + void drawRegister(QPainter* p, REGISTER_NAME reg, char* value); void setRegisters(REGDUMP* reg); - int_t registerValue(const REGDUMP* regd, const REGISTER_NAME reg); + char* registerValue(const REGDUMP* regd, const REGISTER_NAME reg); bool identifyRegister(const int y, const int x, REGISTER_NAME* clickedReg); void displayEditDialog(); @@ -99,6 +101,7 @@ protected slots: void onFollowInDump(); void onFollowInStack(); QString getRegisterLabel(REGISTER_NAME); + uint_t GetUintValue(REGISTER_NAME, char*); private: int mVScrollOffset; @@ -110,6 +113,9 @@ private: QSet mGPR; // all flags QSet mFlags; + // FPU x87 and MMX registers + QSet mFPUx87; + QSet mFPUMMX; // contains all id's of registers if there occurs a change QSet mRegisterUpdates; // registers that do not allow changes From 29dcc60da5b9ef5de0a7fef72bae67dac808fd4f Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Tue, 30 Sep 2014 14:55:27 +0200 Subject: [PATCH 02/58] new titanengine header --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 374 +++++++++++++------------- 1 file changed, 187 insertions(+), 187 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index c2f69fba8..c76020514 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -594,66 +594,66 @@ extern "C" // Global.Function.Declaration: // TitanEngine.Dumper.functions: -__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, const char* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, const char* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, const char* szDebuggedFileName); -__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDebuggedFileName); -__declspec(dllexport) bool TITCALL ExtractSection(const char* szFileName, const char* szDumpFileName, DWORD SectionNumber); -__declspec(dllexport) bool TITCALL ExtractSectionW(const wchar_t* szFileName, const wchar_t* szDumpFileName, DWORD SectionNumber); -__declspec(dllexport) bool TITCALL ResortFileSections(const char* szFileName); -__declspec(dllexport) bool TITCALL ResortFileSectionsW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL FindOverlay(const char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); -__declspec(dllexport) bool TITCALL FindOverlayW(const wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); -__declspec(dllexport) bool TITCALL ExtractOverlay(const char* szFileName, const char* szExtactedFileName); -__declspec(dllexport) bool TITCALL ExtractOverlayW(const wchar_t* szFileName, const wchar_t* szExtactedFileName); -__declspec(dllexport) bool TITCALL AddOverlay(const char* szFileName, const char* szOverlayFileName); -__declspec(dllexport) bool TITCALL AddOverlayW(const wchar_t* szFileName, const wchar_t* szOverlayFileName); -__declspec(dllexport) bool TITCALL CopyOverlay(const char* szInFileName, const char* szOutFileName); -__declspec(dllexport) bool TITCALL CopyOverlayW(const wchar_t* szInFileName, const wchar_t* szOutFileName); -__declspec(dllexport) bool TITCALL RemoveOverlay(const char* szFileName); -__declspec(dllexport) bool TITCALL RemoveOverlayW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(const char* szFileName); -__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(const wchar_t* szFileName); -__declspec(dllexport) long TITCALL AddNewSectionEx(const char* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); -__declspec(dllexport) long TITCALL AddNewSectionExW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); -__declspec(dllexport) long TITCALL AddNewSection(const char* szFileName, const char* szSectionName, DWORD SectionSize); -__declspec(dllexport) long TITCALL AddNewSectionW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize); -__declspec(dllexport) bool TITCALL ResizeLastSection(const char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); -__declspec(dllexport) bool TITCALL ResizeLastSectionW(const wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); -__declspec(dllexport) void TITCALL SetSharedOverlay(const char* szFileName); -__declspec(dllexport) void TITCALL SetSharedOverlayW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, char* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, wchar_t* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, char* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, wchar_t* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, char* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, char* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, char* szDebuggedFileName); +__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, wchar_t* szDebuggedFileName); +__declspec(dllexport) bool TITCALL ExtractSection(char* szFileName, char* szDumpFileName, DWORD SectionNumber); +__declspec(dllexport) bool TITCALL ExtractSectionW(wchar_t* szFileName, wchar_t* szDumpFileName, DWORD SectionNumber); +__declspec(dllexport) bool TITCALL ResortFileSections(char* szFileName); +__declspec(dllexport) bool TITCALL ResortFileSectionsW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL FindOverlay(char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); +__declspec(dllexport) bool TITCALL FindOverlayW(wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); +__declspec(dllexport) bool TITCALL ExtractOverlay(char* szFileName, char* szExtactedFileName); +__declspec(dllexport) bool TITCALL ExtractOverlayW(wchar_t* szFileName, wchar_t* szExtactedFileName); +__declspec(dllexport) bool TITCALL AddOverlay(char* szFileName, char* szOverlayFileName); +__declspec(dllexport) bool TITCALL AddOverlayW(wchar_t* szFileName, wchar_t* szOverlayFileName); +__declspec(dllexport) bool TITCALL CopyOverlay(char* szInFileName, char* szOutFileName); +__declspec(dllexport) bool TITCALL CopyOverlayW(wchar_t* szInFileName, wchar_t* szOutFileName); +__declspec(dllexport) bool TITCALL RemoveOverlay(char* szFileName); +__declspec(dllexport) bool TITCALL RemoveOverlayW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(char* szFileName); +__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(wchar_t* szFileName); +__declspec(dllexport) long TITCALL AddNewSectionEx(char* szFileName, char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); +__declspec(dllexport) long TITCALL AddNewSectionExW(wchar_t* szFileName, char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); +__declspec(dllexport) long TITCALL AddNewSection(char* szFileName, char* szSectionName, DWORD SectionSize); +__declspec(dllexport) long TITCALL AddNewSectionW(wchar_t* szFileName, char* szSectionName, DWORD SectionSize); +__declspec(dllexport) bool TITCALL ResizeLastSection(char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); +__declspec(dllexport) bool TITCALL ResizeLastSectionW(wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); +__declspec(dllexport) void TITCALL SetSharedOverlay(char* szFileName); +__declspec(dllexport) void TITCALL SetSharedOverlayW(wchar_t* szFileName); __declspec(dllexport) char* TITCALL GetSharedOverlay(); __declspec(dllexport) wchar_t* TITCALL GetSharedOverlayW(); -__declspec(dllexport) bool TITCALL DeleteLastSection(const char* szFileName); -__declspec(dllexport) bool TITCALL DeleteLastSectionW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL DeleteLastSectionEx(const char* szFileName, DWORD NumberOfSections); -__declspec(dllexport) bool TITCALL DeleteLastSectionExW(const wchar_t* szFileName, DWORD NumberOfSections); +__declspec(dllexport) bool TITCALL DeleteLastSection(char* szFileName); +__declspec(dllexport) bool TITCALL DeleteLastSectionW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL DeleteLastSectionEx(char* szFileName, DWORD NumberOfSections); +__declspec(dllexport) bool TITCALL DeleteLastSectionExW(wchar_t* szFileName, DWORD NumberOfSections); __declspec(dllexport) ULONG_PTR TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(char* szFileName, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(wchar_t* szFileName, DWORD WhichSection, DWORD WhichData); __declspec(dllexport) bool TITCALL GetPE32DataFromMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL GetPE32DataEx(const char* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL GetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL GetPE32DataEx(char* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL GetPE32DataExW(wchar_t* szFileName, LPVOID DataStorage); __declspec(dllexport) bool TITCALL SetPE32DataForMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32Data(char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32DataW(wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); __declspec(dllexport) bool TITCALL SetPE32DataForMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataEx(const char* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataEx(char* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataExW(wchar_t* szFileName, LPVOID DataStorage); __declspec(dllexport) long TITCALL GetPE32SectionNumberFromVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert); __declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType); __declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType); @@ -662,19 +662,19 @@ __declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVAEx(ULONG_PTR FileMa __declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); __declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten); // TitanEngine.Realigner.functions: -__declspec(dllexport) bool TITCALL FixHeaderCheckSum(const char* szFileName); -__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL FixHeaderCheckSum(char* szFileName); +__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(wchar_t* szFileName); __declspec(dllexport) long TITCALL RealignPE(ULONG_PTR FileMapVA, DWORD FileSize, DWORD RealingMode); -__declspec(dllexport) long TITCALL RealignPEEx(const char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); -__declspec(dllexport) long TITCALL RealignPEExW(const wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); -__declspec(dllexport) bool TITCALL WipeSection(const char* szFileName, int WipeSectionNumber, bool RemovePhysically); -__declspec(dllexport) bool TITCALL WipeSectionW(const wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically); -__declspec(dllexport) bool TITCALL IsPE32FileValidEx(const char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); -__declspec(dllexport) bool TITCALL IsPE32FileValidExW(const wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); -__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(const char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); -__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(const wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); -__declspec(dllexport) bool TITCALL IsFileDLL(const char* szFileName, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA); +__declspec(dllexport) long TITCALL RealignPEEx(char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); +__declspec(dllexport) long TITCALL RealignPEExW(wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); +__declspec(dllexport) bool TITCALL WipeSection(char* szFileName, int WipeSectionNumber, bool RemovePhysically); +__declspec(dllexport) bool TITCALL WipeSectionW(wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically); +__declspec(dllexport) bool TITCALL IsPE32FileValidEx(char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); +__declspec(dllexport) bool TITCALL IsPE32FileValidExW(wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); +__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); +__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); +__declspec(dllexport) bool TITCALL IsFileDLL(char* szFileName, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL IsFileDLLW(wchar_t* szFileName, ULONG_PTR FileMapVA); // TitanEngine.Hider.functions: __declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess); __declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess); @@ -688,31 +688,31 @@ __declspec(dllexport) void TITCALL RelocaterInit(DWORD MemorySize, ULONG_PTR Old __declspec(dllexport) void TITCALL RelocaterAddNewRelocation(HANDLE hProcess, ULONG_PTR RelocateAddress, DWORD RelocateState); __declspec(dllexport) long TITCALL RelocaterEstimatedSize(); __declspec(dllexport) bool TITCALL RelocaterExportRelocation(ULONG_PTR StorePlace, DWORD StorePlaceRVA, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(const char* szFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(const wchar_t* szFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(char* szFileName, char* szSectionName); +__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(wchar_t* szFileName, char* szSectionName); __declspec(dllexport) bool TITCALL RelocaterGrabRelocationTable(HANDLE hProcess, ULONG_PTR MemoryStart, DWORD MemorySize); __declspec(dllexport) bool TITCALL RelocaterGrabRelocationTableEx(HANDLE hProcess, ULONG_PTR MemoryStart, ULONG_PTR MemorySize, DWORD NtSizeOfImage); -__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, const char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); -__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, const wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); -__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const char* szDumpFile1, const char* szDumpFile2, ULONG_PTR MemStart); -__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const wchar_t* szDumpFile1, const wchar_t* szDumpFile2, ULONG_PTR MemStart); -__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(const char* szFileName, ULONG_PTR NewImageBase); -__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(const wchar_t* szFileName, ULONG_PTR NewImageBase); +__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); +__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); +__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, char* szDumpFile1, char* szDumpFile2, ULONG_PTR MemStart); +__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, wchar_t* szDumpFile1, wchar_t* szDumpFile2, ULONG_PTR MemStart); +__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(char* szFileName, ULONG_PTR NewImageBase); +__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(wchar_t* szFileName, ULONG_PTR NewImageBase); __declspec(dllexport) bool TITCALL RelocaterRelocateMemoryBlock(ULONG_PTR FileMapVA, ULONG_PTR MemoryLocation, void* RelocateMemory, DWORD RelocateMemorySize, ULONG_PTR CurrentLoadedBase, ULONG_PTR RelocateBase); -__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(const char* szFileName); -__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(char* szFileName); +__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(wchar_t* szFileName); // TitanEngine.Resourcer.functions: -__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUse(const char* szFileName); -__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUseW(const wchar_t* szFileName); +__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUse(char* szFileName); +__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUseW(wchar_t* szFileName); __declspec(dllexport) bool TITCALL ResourcerFreeLoadedFile(LPVOID LoadedFileBase); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(const char* szFileName, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(const wchar_t* szFileName, char* szResourceType, const char* szResourceName, const char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerFindResource(const char* szFileName, const char* szResourceType, DWORD ResourceType, const char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) bool TITCALL ResourcerFindResourceW(const wchar_t* szFileName, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) void TITCALL ResourcerEnumerateResource(const char* szFileName, void* CallBack); -__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(const wchar_t* szFileName, void* CallBack); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, char* szResourceType, char* szResourceName, char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(char* szFileName, char* szResourceType, char* szResourceName, char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(wchar_t* szFileName, char* szResourceType, char* szResourceName, char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerFindResource(char* szFileName, char* szResourceType, DWORD ResourceType, char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) bool TITCALL ResourcerFindResourceW(wchar_t* szFileName, wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) void TITCALL ResourcerEnumerateResource(char* szFileName, void* CallBack); +__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(wchar_t* szFileName, void* CallBack); __declspec(dllexport) void TITCALL ResourcerEnumerateResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, void* CallBack); // TitanEngine.Threader.functions: __declspec(dllexport) bool TITCALL ThreaderImportRunningThreadData(DWORD ProcessId); @@ -745,11 +745,11 @@ __declspec(dllexport) long TITCALL StaticLengthDisassemble(LPVOID DisassmAddress __declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID DisassmAddress); __declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); __declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); -__declspec(dllexport) void* TITCALL InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder); -__declspec(dllexport) void* TITCALL InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDebugExW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDLLDebug(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDebugExW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDLLDebug(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDLLDebugW(wchar_t* szFileName, bool ReserveModuleBase, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllexport) bool TITCALL StopDebug(); __declspec(dllexport) void TITCALL SetBPXOptions(long DefaultBreakPointType); __declspec(dllexport) bool TITCALL IsBPXEnabled(ULONG_PTR bpxAddress); @@ -814,25 +814,25 @@ __declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnEx __declspec(dllexport) bool TITCALL DetachDebugger(DWORD ProcessId); __declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId); __declspec(dllexport) void TITCALL DebugLoopEx(DWORD TimeOut); -__declspec(dllexport) void TITCALL AutoDebugEx(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); -__declspec(dllexport) void TITCALL AutoDebugExW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); +__declspec(dllexport) void TITCALL AutoDebugEx(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); +__declspec(dllexport) void TITCALL AutoDebugExW(wchar_t* szFileName, bool ReserveModuleBase, wchar_t* szCommandLine, wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); __declspec(dllexport) bool TITCALL IsFileBeingDebugged(); __declspec(dllexport) void TITCALL SetErrorModel(bool DisplayErrorMessages); // TitanEngine.FindOEP.functions: __declspec(dllexport) void TITCALL FindOEPInit(); -__declspec(dllexport) bool TITCALL FindOEPGenerically(const char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); -__declspec(dllexport) bool TITCALL FindOEPGenericallyW(const wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); +__declspec(dllexport) bool TITCALL FindOEPGenerically(char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); +__declspec(dllexport) bool TITCALL FindOEPGenericallyW(wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); // TitanEngine.Importer.functions: -__declspec(dllexport) void TITCALL ImporterAddNewDll(const char* szDLLName, ULONG_PTR FirstThunk); -__declspec(dllexport) void TITCALL ImporterAddNewAPI(const char* szAPIName, ULONG_PTR ThunkValue); +__declspec(dllexport) void TITCALL ImporterAddNewDll(char* szDLLName, ULONG_PTR FirstThunk); +__declspec(dllexport) void TITCALL ImporterAddNewAPI(char* szAPIName, ULONG_PTR ThunkValue); __declspec(dllexport) void TITCALL ImporterAddNewOrdinalAPI(ULONG_PTR OrdinalNumber, ULONG_PTR ThunkValue); __declspec(dllexport) long TITCALL ImporterGetAddedDllCount(); __declspec(dllexport) long TITCALL ImporterGetAddedAPICount(); __declspec(dllexport) bool TITCALL ImporterExportIAT(ULONG_PTR StorePlace, ULONG_PTR FileMapVA, HANDLE hFileMap); __declspec(dllexport) long TITCALL ImporterEstimatedSize(); -__declspec(dllexport) bool TITCALL ImporterExportIATEx(const char* szDumpFileName, const char* szExportFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL ImporterExportIATExW(const wchar_t* szDumpFileName, const wchar_t* szExportFileName, const wchar_t* szSectionName = L".RL!TEv2"); -__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIWriteLocation(const char* szAPIName); +__declspec(dllexport) bool TITCALL ImporterExportIATEx(char* szDumpFileName, char* szExportFileName, char* szSectionName); +__declspec(dllexport) bool TITCALL ImporterExportIATExW(wchar_t* szDumpFileName, wchar_t* szExportFileName, wchar_t* szSectionName = L".RL!TEv2"); +__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIWriteLocation(char* szAPIName); __declspec(dllexport) ULONG_PTR TITCALL ImporterFindOrdinalAPIWriteLocation(ULONG_PTR OrdinalNumber); __declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIByWriteLocation(ULONG_PTR APIWriteLocation); __declspec(dllexport) ULONG_PTR TITCALL ImporterFindDLLByWriteLocation(ULONG_PTR APIWriteLocation); @@ -842,7 +842,7 @@ __declspec(dllexport) void* TITCALL ImporterGetAPIName(ULONG_PTR APIAddress); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumber(ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetAPINameEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddressEx(const char* szDLLName, const char* szAPIName); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddressEx(char* szDLLName, char* szAPIName); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetLocalAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugeeW(HANDLE hProcess, ULONG_PTR APIAddress); @@ -851,8 +851,8 @@ __declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumberFromDebugee(H __declspec(dllexport) long TITCALL ImporterGetDLLIndexEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); __declspec(dllexport) long TITCALL ImporterGetDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBase(HANDLE hProcess, HMODULE LocalModuleBase); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, const char* szModuleName); -__declspec(dllexport) void* TITCALL ImporterGetRemoteDLLBaseExW(HANDLE hProcess, const wchar_t* szModuleName); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, char* szModuleName); +__declspec(dllexport) void* TITCALL ImporterGetRemoteDLLBaseExW(HANDLE hProcess, wchar_t* szModuleName); __declspec(dllexport) bool TITCALL ImporterIsForwardedAPI(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetForwardedAPIName(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetForwardedDLLName(HANDLE hProcess, ULONG_PTR APIAddress); @@ -860,20 +860,20 @@ __declspec(dllexport) long TITCALL ImporterGetForwardedDLLIndex(HANDLE hProcess, __declspec(dllexport) ULONG_PTR TITCALL ImporterGetForwardedAPIOrdinalNumber(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetNearestAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetNearestAPIName(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(const char* szOriginalFile, const char* szDumpFile); -__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile); -__declspec(dllexport) bool TITCALL ImporterLoadImportTable(const char* szFileName); -__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(const char* szOriginalFile, const char* szDumpFile, const char* szSectionName); -__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile, const char* szSectionName); -__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(DWORD ProcessId, const char* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); -__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessIds, const wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(char* szOriginalFile, char* szDumpFile); +__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(wchar_t* szOriginalFile, wchar_t* szDumpFile); +__declspec(dllexport) bool TITCALL ImporterLoadImportTable(char* szFileName); +__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(char* szOriginalFile, char* szDumpFile, char* szSectionName); +__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(wchar_t* szOriginalFile, wchar_t* szDumpFile, char* szSectionName); +__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(DWORD ProcessId, char* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessIds, wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); __declspec(dllexport) void TITCALL ImporterAutoSearchIATEx(DWORD ProcessId, ULONG_PTR ImageBase, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); __declspec(dllexport) void TITCALL ImporterEnumAddedData(LPVOID EnumCallBack); -__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, const char* szDumpedFile, const char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); -__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, const wchar_t* szDumpedFile, const wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); -__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, const char* szDumpedFile, ULONG_PTR SearchStart); -__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, const wchar_t* szDumpedFile, ULONG_PTR SearchStart); +__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, char* szDumpedFile, char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); +__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, wchar_t* szDumpedFile, wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); +__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, char* szDumpedFile, ULONG_PTR SearchStart); +__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, wchar_t* szDumpedFile, ULONG_PTR SearchStart); __declspec(dllexport) bool TITCALL ImporterDeleteAPI(DWORD_PTR apiAddr); // Global.Engine.Hook.functions: __declspec(dllexport) bool TITCALL HooksSafeTransitionEx(LPVOID HookAddressArray, int NumberOfHooks, bool TransitionStart); @@ -882,17 +882,17 @@ __declspec(dllexport) bool TITCALL HooksIsAddressRedirected(LPVOID HookAddress); __declspec(dllexport) void* TITCALL HooksGetTrampolineAddress(LPVOID HookAddress); __declspec(dllexport) void* TITCALL HooksGetHookEntryDetails(LPVOID HookAddress); __declspec(dllexport) bool TITCALL HooksInsertNewRedirection(LPVOID HookAddress, LPVOID RedirectTo, int HookType); -__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, const char* szHookFunction, LPVOID RedirectTo); -__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(const char* szModuleName, const char* szHookFunction, LPVOID RedirectTo); +__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, char* szHookFunction, LPVOID RedirectTo); +__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(char* szModuleName, char* szHookFunction, LPVOID RedirectTo); __declspec(dllexport) bool TITCALL HooksRemoveRedirection(LPVOID HookAddress, bool RemoveAll); __declspec(dllexport) bool TITCALL HooksRemoveRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(const char* szModuleName, const char* szHookFunction, bool RemoveAll); +__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(char* szModuleName, char* szHookFunction, bool RemoveAll); __declspec(dllexport) bool TITCALL HooksDisableRedirection(LPVOID HookAddress, bool DisableAll); __declspec(dllexport) bool TITCALL HooksDisableRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(const char* szModuleName, const char* szHookFunction, bool DisableAll); +__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(char* szModuleName, char* szHookFunction, bool DisableAll); __declspec(dllexport) bool TITCALL HooksEnableRedirection(LPVOID HookAddress, bool EnableAll); __declspec(dllexport) bool TITCALL HooksEnableRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(const char* szModuleName, const char* szHookFunction, bool EnableAll); +__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(char* szModuleName, char* szHookFunction, bool EnableAll); __declspec(dllexport) void TITCALL HooksScanModuleMemory(HMODULE ModuleBase, LPVOID CallBack); __declspec(dllexport) void TITCALL HooksScanEntireProcessMemory(LPVOID CallBack); __declspec(dllexport) void TITCALL HooksScanEntireProcessMemoryEx(); @@ -903,53 +903,53 @@ __declspec(dllexport) ULONG_PTR TITCALL HashTracerLevel1(HANDLE hProcess, ULONG_ __declspec(dllexport) long TITCALL TracerDetectRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace); __declspec(dllexport) ULONG_PTR TITCALL TracerFixKnownRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD RedirectionId); __declspec(dllexport) ULONG_PTR TITCALL TracerFixRedirectionViaModule(HMODULE hModuleHandle, HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD IdParameter); -__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, const char* szPluginName, ULONG_PTR AddressToTrace); +__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, char* szPluginName, ULONG_PTR AddressToTrace); // TitanEngine.Exporter.functions: __declspec(dllexport) void TITCALL ExporterCleanup(); __declspec(dllexport) void TITCALL ExporterSetImageBase(ULONG_PTR ImageBase); -__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, const char* szExportModuleName); -__declspec(dllexport) bool TITCALL ExporterAddNewExport(const char* szExportName, DWORD ExportRelativeAddress); +__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, char* szExportModuleName); +__declspec(dllexport) bool TITCALL ExporterAddNewExport(char* szExportName, DWORD ExportRelativeAddress); __declspec(dllexport) bool TITCALL ExporterAddNewOrdinalExport(DWORD OrdinalNumber, DWORD ExportRelativeAddress); __declspec(dllexport) long TITCALL ExporterGetAddedExportCount(); __declspec(dllexport) long TITCALL ExporterEstimatedSize(); __declspec(dllexport) bool TITCALL ExporterBuildExportTable(ULONG_PTR StorePlace, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(const char* szExportFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(const wchar_t* szExportFileName, const char* szSectionName); -__declspec(dllexport) bool TITCALL ExporterLoadExportTable(const char* szFileName); -__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(char* szExportFileName, char* szSectionName); +__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(wchar_t* szExportFileName, char* szSectionName); +__declspec(dllexport) bool TITCALL ExporterLoadExportTable(char* szFileName); +__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(wchar_t* szFileName); // TitanEngine.Librarian.functions: -__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(const char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(const char* szLibraryName, DWORD bpxType); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(const char* szLibraryName); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(const wchar_t* szLibraryName); +__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(char* szLibraryName, DWORD bpxType); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(char* szLibraryName); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(wchar_t* szLibraryName); __declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoEx(void* BaseOfDll); __declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoExW(void* BaseOfDll); __declspec(dllexport) void TITCALL LibrarianEnumLibraryInfo(void* EnumCallBack); __declspec(dllexport) void TITCALL LibrarianEnumLibraryInfoW(void* EnumCallBack); // TitanEngine.Process.functions: -__declspec(dllexport) long TITCALL GetActiveProcessId(const char* szImageName); -__declspec(dllexport) long TITCALL GetActiveProcessIdW(const wchar_t* szImageName); -__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(const char* szLibraryName, void* EnumFunction); +__declspec(dllexport) long TITCALL GetActiveProcessId(char* szImageName); +__declspec(dllexport) long TITCALL GetActiveProcessIdW(wchar_t* szImageName); +__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(char* szLibraryName, void* EnumFunction); __declspec(dllexport) HANDLE TITCALL TitanOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId); // TitanEngine.TLSFixer.functions: __declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSGrabCallBackData(const char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(const wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(const char* szFileName, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(const wchar_t* szFileName, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSRemoveCallback(const char* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveTable(const char* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveTableW(const wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSBackupData(const char* szFileName); -__declspec(dllexport) bool TITCALL TLSBackupDataW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSGrabCallBackData(char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(char* szFileName, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(wchar_t* szFileName, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSRemoveCallback(char* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveTable(char* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSBackupData(char* szFileName); +__declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName); __declspec(dllexport) bool TITCALL TLSRestoreData(); __declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_PTR StorePlace, ULONG_PTR StorePlaceRVA, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(const char* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(const wchar_t* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(char* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(wchar_t* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); // TitanEngine.TranslateName.functions: -__declspec(dllexport) void* TITCALL TranslateNativeName(const char* szNativeName); -__declspec(dllexport) void* TITCALL TranslateNativeNameW(const wchar_t* szNativeName); +__declspec(dllexport) void* TITCALL TranslateNativeName(char* szNativeName); +__declspec(dllexport) void* TITCALL TranslateNativeNameW(wchar_t* szNativeName); // TitanEngine.Handler.functions: __declspec(dllexport) long TITCALL HandlerGetActiveHandleCount(DWORD ProcessId); __declspec(dllexport) bool TITCALL HandlerIsHandleOpen(DWORD ProcessId, HANDLE hHandle); @@ -959,30 +959,30 @@ __declspec(dllexport) long TITCALL HandlerEnumerateOpenHandles(DWORD ProcessId, __declspec(dllexport) ULONG_PTR TITCALL HandlerGetHandleDetails(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, DWORD InformationReturn); __declspec(dllexport) bool TITCALL HandlerCloseRemoteHandle(HANDLE hProcess, HANDLE hHandle); __declspec(dllexport) long TITCALL HandlerEnumerateLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); -__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); -__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerIsFileLocked(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); +__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerIsFileLocked(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); // TitanEngine.Handler[Mutex].functions: __declspec(dllexport) long TITCALL HandlerEnumerateOpenMutexes(HANDLE hProcess, DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, const char* szMutexString); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, const wchar_t* szMutexString); -__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(const char* szMutexString); -__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(const wchar_t* szMutexString); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, char* szMutexString); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, wchar_t* szMutexString); +__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(char* szMutexString); +__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(wchar_t* szMutexString); // TitanEngine.Injector.functions: -__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, const char* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, const wchar_t* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, const char* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, const wchar_t* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, char* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, wchar_t* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, char* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, wchar_t* szLibraryFile, bool WaitForThreadExit); __declspec(dllexport) bool TITCALL RemoteExitProcess(HANDLE hProcess, DWORD ExitCode); // TitanEngine.StaticUnpacker.functions: -__declspec(dllexport) bool TITCALL StaticFileLoad(const char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileUnload(const char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileOpen(const char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); -__declspec(dllexport) bool TITCALL StaticFileOpenW(const wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); +__declspec(dllexport) bool TITCALL StaticFileLoad(char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileLoadW(wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileUnload(char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileUnloadW(wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileOpen(char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); +__declspec(dllexport) bool TITCALL StaticFileOpenW(wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); __declspec(dllexport) bool TITCALL StaticFileGetContent(HANDLE FileHandle, DWORD FilePositionLow, LPDWORD FilePositionHigh, void* Buffer, DWORD Size); __declspec(dllexport) void TITCALL StaticFileClose(HANDLE FileHandle); __declspec(dllexport) void TITCALL StaticMemoryDecrypt(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); @@ -990,40 +990,40 @@ __declspec(dllexport) void TITCALL StaticMemoryDecryptEx(LPVOID MemoryStart, DWO __declspec(dllexport) void TITCALL StaticMemoryDecryptSpecial(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, DWORD SpecDecryptionType, void* DecryptionCallBack); __declspec(dllexport) void TITCALL StaticSectionDecrypt(ULONG_PTR FileMapVA, DWORD SectionNumber, bool SimulateLoad, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); __declspec(dllexport) bool TITCALL StaticMemoryDecompress(void* Source, DWORD SourceSize, void* Destination, DWORD DestinationSize, int Algorithm); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, wchar_t* szDumpFileName); __declspec(dllexport) bool TITCALL StaticHashMemory(void* MemoryToHash, DWORD SizeOfMemory, void* HashDigest, bool OutputString, int Algorithm); -__declspec(dllexport) bool TITCALL StaticHashFileW(const wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm); -__declspec(dllexport) bool TITCALL StaticHashFile(const char* szFileName, char* HashDigest, bool OutputString, int Algorithm); +__declspec(dllexport) bool TITCALL StaticHashFileW(wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm); +__declspec(dllexport) bool TITCALL StaticHashFile(char* szFileName, char* HashDigest, bool OutputString, int Algorithm); // TitanEngine.Engine.functions: -__declspec(dllexport) void TITCALL EngineUnpackerInitialize(const char* szFileName, const char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); -__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(const wchar_t* szFileName, const wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); +__declspec(dllexport) void TITCALL EngineUnpackerInitialize(char* szFileName, char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); +__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(wchar_t* szFileName, wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); __declspec(dllexport) bool TITCALL EngineUnpackerSetBreakCondition(void* SearchStart, DWORD SearchSize, void* SearchPattern, DWORD PatternSize, DWORD PatternDelta, ULONG_PTR BreakType, bool SingleBreak, DWORD Parameter1, DWORD Parameter2); __declspec(dllexport) void TITCALL EngineUnpackerSetEntryPointAddress(ULONG_PTR UnpackedEntryPointAddress); __declspec(dllexport) void TITCALL EngineUnpackerFinalizeUnpacking(); // TitanEngine.Engine.functions: __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet); -__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(const char* szFileName, const char* szOutputFolder, bool LogCreatedFiles); -__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(const wchar_t* szFileName, const wchar_t* szOutputFolder, bool LogCreatedFiles); +__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles); +__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(wchar_t* szFileName, wchar_t* szOutputFolder, bool LogCreatedFiles); __declspec(dllexport) bool TITCALL EngineFakeMissingDependencies(HANDLE hProcess); __declspec(dllexport) bool TITCALL EngineDeleteCreatedDependencies(); -__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(const char* WindowUnpackerTitle, const char* WindowUnpackerLongTitle, const char* WindowUnpackerName, const char* WindowUnpackerAuthor, void* StartUnpackingCallBack); -__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(const char* szLogMessage); +__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(char* WindowUnpackerTitle, char* WindowUnpackerLongTitle, char* WindowUnpackerName, char* WindowUnpackerAuthor, void* StartUnpackingCallBack); +__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(char* szLogMessage); __declspec(dllexport) bool TITCALL EngineCheckStructAlignment(DWORD StructureType, ULONG_PTR StructureSize); // Global.Engine.Extension.Functions: -__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(const char* szPluginName); -__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(char* szPluginName); __declspec(dllexport) bool TITCALL ExtensionManagerDisableAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(char* szPluginName); __declspec(dllexport) bool TITCALL ExtensionManagerEnableAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(char* szPluginName); __declspec(dllexport) bool TITCALL ExtensionManagerUnloadAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(const char* szPluginName); -__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(char* szPluginName); +__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(char* szPluginName); #ifdef __cplusplus } From 04c6affcf7b3faf9c6e937e9c0f1da9bfba7eecd Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Wed, 8 Oct 2014 15:48:36 +0200 Subject: [PATCH 03/58] DBG: cleanup --- x64_dbg_dbg/data.h | 31 --- x64_dbg_dbg/log.h | 10 +- x64_dbg_dbg/x64_dbg.cpp | 1 - x64_dbg_dbg/x64_dbg_dbg.vcxproj | 1 - x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters | 305 +++++++++++++----------- 5 files changed, 167 insertions(+), 181 deletions(-) delete mode 100644 x64_dbg_dbg/data.h diff --git a/x64_dbg_dbg/data.h b/x64_dbg_dbg/data.h deleted file mode 100644 index 1d1329dce..000000000 --- a/x64_dbg_dbg/data.h +++ /dev/null @@ -1,31 +0,0 @@ -#ifndef _DATA_H -#define _DATA_H - -#include "_global.h" - -enum DATA_TYPE //how to display the current struct entry? -{ - thex, //%X - tint, //%d - tuint, //%u - ttext, //%c -}; - -struct STRUCT_INFO -{ - unsigned int size; //size of one entry (with type) (max 256) - DATA_TYPE display_type; //display type - unsigned int count; //number of entries with the same content (reserved[12]) - void* description; //reserved for later use (for example name of variable) -}; - -struct DATA -{ - uint page_start; //remote/local memory - uint page_size; //size of memory - uint ip; //real start of data (relative from page_start) - int struct_size; //number of entries in a struct - STRUCT_INFO* info; //actual info -}; - -#endif // _DATA_H diff --git a/x64_dbg_dbg/log.h b/x64_dbg_dbg/log.h index 0070507fd..2550b0a17 100644 --- a/x64_dbg_dbg/log.h +++ b/x64_dbg_dbg/log.h @@ -1,5 +1,8 @@ -#pragma once +#ifndef _LOG_H +#define _LOG_H + #include + // a Qt's QDebug like message logging // usage: "log() << "hi" << "there"; class log @@ -7,8 +10,8 @@ class log public: log(); ~log(); -public: +public: template inline log & operator<<(const T & x) { @@ -16,8 +19,9 @@ public: message << x; return *this; } + private: std::ostringstream message; - }; +#endif _LOG_H \ No newline at end of file diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 2b564cc46..196425944 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -4,7 +4,6 @@ #include "variable.h" #include "instruction.h" #include "debugger.h" -#include "data.h" #include "simplescript.h" #include "console.h" #include "math.h" diff --git a/x64_dbg_dbg/x64_dbg_dbg.vcxproj b/x64_dbg_dbg/x64_dbg_dbg.vcxproj index e978a9fdb..535b793e4 100644 --- a/x64_dbg_dbg/x64_dbg_dbg.vcxproj +++ b/x64_dbg_dbg/x64_dbg_dbg.vcxproj @@ -58,7 +58,6 @@ - diff --git a/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters b/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters index 1db244173..090009caa 100644 --- a/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters +++ b/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters @@ -13,30 +13,6 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav - - {6028af23-e8de-4db7-b1c7-bee2b5a4402b} - - - {5623fb24-3b6d-49a6-a0d3-1cfcc46f87bd} - - - {23226861-3b20-42db-8dd6-c5d276ba7a83} - - - {6b85ff77-8866-4618-9d46-006d8c349f8f} - - - {f4eb1487-15d6-4836-9d20-339d0f18c31f} - - - {b63305e2-2b10-46eb-839f-5e9080fa8ad8} - - - {6a8d58f0-1417-4bff-aecd-0f9f5e0641f9} - - - {adf51b13-6f3b-4b04-9ba9-21fb7a38150d} - {ee24febc-948e-4226-ba0e-68a9b449fb23} @@ -55,6 +31,48 @@ {52e2c3ae-0223-4216-b896-41d9f171f731} + + {164592cf-e2c9-4c98-abf6-ea47d37653a1} + + + {d2362bf7-ff20-493d-be01-0fb7e6dca8c9} + + + {23226861-3b20-42db-8dd6-c5d276ba7a83} + + + {adf51b13-6f3b-4b04-9ba9-21fb7a38150d} + + + {6b85ff77-8866-4618-9d46-006d8c349f8f} + + + {6028af23-e8de-4db7-b1c7-bee2b5a4402b} + + + {5623fb24-3b6d-49a6-a0d3-1cfcc46f87bd} + + + {f4eb1487-15d6-4836-9d20-339d0f18c31f} + + + {b63305e2-2b10-46eb-839f-5e9080fa8ad8} + + + {6a8d58f0-1417-4bff-aecd-0f9f5e0641f9} + + + {714f2eb1-20d7-47ed-a641-ba8a66da2e7a} + + + {938130d5-63d6-44c2-9604-70f1f101890c} + + + {ccf4c0a0-bb97-4090-acc5-bc6b343300bf} + + + {b006b04c-d7ea-49cb-b097-0cac1388f98e} + @@ -164,161 +182,158 @@ - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - Header Files - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - Header Files\BeaEngine + Header Files\Third Party\BeaEngine - Header Files\BeaEngine + Header Files\Third Party\BeaEngine - Header Files\BeaEngine + Header Files\Third Party\BeaEngine - Header Files\BeaEngine + Header Files\Third Party\BeaEngine - Header Files\dbghelp + Header Files\Third Party\dbghelp - Header Files\XEDParse + Header Files\Third Party\XEDParse - Header Files\TitanEngine + Header Files\Third Party\TitanEngine - Header Files\DeviceNameResolver + Header Files\Third Party\DeviceNameResolver - Header Files\jansson + Header Files\Third Party\jansson - Header Files\jansson - - - Header Files + Header Files\Third Party\jansson - Header Files\lz4 + Header Files\Third Party\lz4 - Header Files\lz4 + Header Files\Third Party\lz4 - Header Files\lz4 - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files - - - Header Files + Header Files\Third Party\lz4 - Header Files\UString + Header Files\Third Party\UString - Header Files\UString + Header Files\Third Party\UString - Header Files\UString + Header Files\Third Party\UString + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Core + + + Header Files\Debugger Core + + + Header Files\Debugger Core + + + Header Files\Debugger Core + + + Header Files\Information + + + Header Files\Information + + + Header Files\Information + + + Header Files\Information + + + Header Files\Interfaces/Exports + + + Header Files\Interfaces/Exports + + + Header Files\Interfaces/Exports + + + Header Files\Interfaces/Exports + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Utilities + + + Header Files\Debugger Core \ No newline at end of file From a1a0d02c8b790ae0ef45d824aaab2dd6e70f3bc5 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Tue, 21 Oct 2014 21:04:55 +0200 Subject: [PATCH 04/58] last fpu support --- x64_dbg_bridge/bridgemain.h | 3 +- x64_dbg_dbg/TitanEngine/TitanEngine.h | 385 +++++------ x64_dbg_dbg/TitanEngine/TitanEngine_x64.a | Bin 327286 -> 0 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 100430 -> 102168 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 104178 -> 105896 bytes x64_dbg_dbg/XEDParse/XEDParse_x64.a | Bin 2912 -> 0 bytes x64_dbg_dbg/XEDParse/XEDParse_x86.a | Bin 2940 -> 0 bytes x64_dbg_dbg/XEDParse/XEDParse_x86.lib | Bin 1934 -> 1934 bytes x64_dbg_dbg/_exports.cpp | 3 + x64_dbg_dbg/lz4/lz4.h | 40 +- x64_dbg_dbg/lz4/lz4_x64.a | Bin 33634 -> 0 bytes x64_dbg_dbg/lz4/lz4_x86.a | Bin 33554 -> 0 bytes x64_dbg_dbg/lz4/lz4_x86.lib | Bin 11606 -> 11606 bytes x64_dbg_dbg/lz4/lz4file.h | 8 +- x64_dbg_dbg/lz4/lz4hc.h | 36 +- x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp | 7 +- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 597 ++++++++++++++---- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 30 +- 18 files changed, 729 insertions(+), 380 deletions(-) delete mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x64.a delete mode 100644 x64_dbg_dbg/XEDParse/XEDParse_x64.a delete mode 100644 x64_dbg_dbg/XEDParse/XEDParse_x86.a delete mode 100644 x64_dbg_dbg/lz4/lz4_x64.a delete mode 100644 x64_dbg_dbg/lz4/lz4_x86.a diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 6c92f10df..9ffafc22c 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -372,7 +372,8 @@ typedef struct { TITAN_ENGINE_CONTEXT_t titcontext; FLAGS flags; - + x87FPURegister_t x87FPURegisters[8]; + uint64_t mmx[8]; } REGDUMP; typedef struct diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index c76020514..f111e4ec2 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -262,18 +262,18 @@ typedef struct { BYTE data[10]; int st_value; + int tag; } x87FPURegister_t; typedef struct { - DWORD ControlWord; - DWORD StatusWord; - DWORD TagWord; + WORD ControlWord; + WORD StatusWord; + WORD TagWord; DWORD ErrorOffset; DWORD ErrorSelector; DWORD DataOffset; DWORD DataSelector; - x87FPURegister_t x87FPURegister[8]; DWORD Cr0NpxState; } x87FPU_t; @@ -314,7 +314,6 @@ typedef struct BYTE RegisterArea[80]; x87FPU_t x87fpu; DWORD MxCsr; - uint64_t mmx[8]; #ifdef _WIN64 M128A XmmRegisters[16]; #else // x86 @@ -594,66 +593,66 @@ extern "C" // Global.Function.Declaration: // TitanEngine.Dumper.functions: -__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, char* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, wchar_t* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, char* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, wchar_t* szDumpFileName, ULONG_PTR EntryPoint); -__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, char* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, char* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); -__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, char* szDumpFileName); -__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, char* szDebuggedFileName); -__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, wchar_t* szDebuggedFileName); -__declspec(dllexport) bool TITCALL ExtractSection(char* szFileName, char* szDumpFileName, DWORD SectionNumber); -__declspec(dllexport) bool TITCALL ExtractSectionW(wchar_t* szFileName, wchar_t* szDumpFileName, DWORD SectionNumber); -__declspec(dllexport) bool TITCALL ResortFileSections(char* szFileName); -__declspec(dllexport) bool TITCALL ResortFileSectionsW(wchar_t* szFileName); -__declspec(dllexport) bool TITCALL FindOverlay(char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); -__declspec(dllexport) bool TITCALL FindOverlayW(wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); -__declspec(dllexport) bool TITCALL ExtractOverlay(char* szFileName, char* szExtactedFileName); -__declspec(dllexport) bool TITCALL ExtractOverlayW(wchar_t* szFileName, wchar_t* szExtactedFileName); -__declspec(dllexport) bool TITCALL AddOverlay(char* szFileName, char* szOverlayFileName); -__declspec(dllexport) bool TITCALL AddOverlayW(wchar_t* szFileName, wchar_t* szOverlayFileName); -__declspec(dllexport) bool TITCALL CopyOverlay(char* szInFileName, char* szOutFileName); -__declspec(dllexport) bool TITCALL CopyOverlayW(wchar_t* szInFileName, wchar_t* szOutFileName); -__declspec(dllexport) bool TITCALL RemoveOverlay(char* szFileName); -__declspec(dllexport) bool TITCALL RemoveOverlayW(wchar_t* szFileName); -__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(char* szFileName); -__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(wchar_t* szFileName); -__declspec(dllexport) long TITCALL AddNewSectionEx(char* szFileName, char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); -__declspec(dllexport) long TITCALL AddNewSectionExW(wchar_t* szFileName, char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); -__declspec(dllexport) long TITCALL AddNewSection(char* szFileName, char* szSectionName, DWORD SectionSize); -__declspec(dllexport) long TITCALL AddNewSectionW(wchar_t* szFileName, char* szSectionName, DWORD SectionSize); -__declspec(dllexport) bool TITCALL ResizeLastSection(char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); -__declspec(dllexport) bool TITCALL ResizeLastSectionW(wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); -__declspec(dllexport) void TITCALL SetSharedOverlay(char* szFileName); -__declspec(dllexport) void TITCALL SetSharedOverlayW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL DumpProcess(HANDLE hProcess, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessEx(DWORD ProcessId, LPVOID ImageBase, const char* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpProcessExW(DWORD ProcessId, LPVOID ImageBase, const wchar_t* szDumpFileName, ULONG_PTR EntryPoint); +__declspec(dllexport) bool TITCALL DumpMemory(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryW(HANDLE hProcess, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryEx(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpMemoryExW(DWORD ProcessId, LPVOID MemoryStart, ULONG_PTR MemorySize, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpRegions(HANDLE hProcess, const char* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsW(HANDLE hProcess, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsEx(DWORD ProcessId, const char* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpRegionsExW(DWORD ProcessId, const wchar_t* szDumpFolder, bool DumpAboveImageBaseOnly); +__declspec(dllexport) bool TITCALL DumpModule(HANDLE hProcess, LPVOID ModuleBase, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleW(HANDLE hProcess, LPVOID ModuleBase, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleEx(DWORD ProcessId, LPVOID ModuleBase, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL DumpModuleExW(DWORD ProcessId, LPVOID ModuleBase, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL PastePEHeader(HANDLE hProcess, LPVOID ImageBase, const char* szDebuggedFileName); +__declspec(dllexport) bool TITCALL PastePEHeaderW(HANDLE hProcess, LPVOID ImageBase, const wchar_t* szDebuggedFileName); +__declspec(dllexport) bool TITCALL ExtractSection(const char* szFileName, const char* szDumpFileName, DWORD SectionNumber); +__declspec(dllexport) bool TITCALL ExtractSectionW(const wchar_t* szFileName, const wchar_t* szDumpFileName, DWORD SectionNumber); +__declspec(dllexport) bool TITCALL ResortFileSections(const char* szFileName); +__declspec(dllexport) bool TITCALL ResortFileSectionsW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL FindOverlay(const char* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); +__declspec(dllexport) bool TITCALL FindOverlayW(const wchar_t* szFileName, LPDWORD OverlayStart, LPDWORD OverlaySize); +__declspec(dllexport) bool TITCALL ExtractOverlay(const char* szFileName, const char* szExtactedFileName); +__declspec(dllexport) bool TITCALL ExtractOverlayW(const wchar_t* szFileName, const wchar_t* szExtactedFileName); +__declspec(dllexport) bool TITCALL AddOverlay(const char* szFileName, const char* szOverlayFileName); +__declspec(dllexport) bool TITCALL AddOverlayW(const wchar_t* szFileName, const wchar_t* szOverlayFileName); +__declspec(dllexport) bool TITCALL CopyOverlay(const char* szInFileName, const char* szOutFileName); +__declspec(dllexport) bool TITCALL CopyOverlayW(const wchar_t* szInFileName, const wchar_t* szOutFileName); +__declspec(dllexport) bool TITCALL RemoveOverlay(const char* szFileName); +__declspec(dllexport) bool TITCALL RemoveOverlayW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL MakeAllSectionsRWE(const char* szFileName); +__declspec(dllexport) bool TITCALL MakeAllSectionsRWEW(const wchar_t* szFileName); +__declspec(dllexport) long TITCALL AddNewSectionEx(const char* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); +__declspec(dllexport) long TITCALL AddNewSectionExW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize, DWORD SectionAttributes, LPVOID SectionContent, DWORD ContentSize); +__declspec(dllexport) long TITCALL AddNewSection(const char* szFileName, const char* szSectionName, DWORD SectionSize); +__declspec(dllexport) long TITCALL AddNewSectionW(const wchar_t* szFileName, const char* szSectionName, DWORD SectionSize); +__declspec(dllexport) bool TITCALL ResizeLastSection(const char* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); +__declspec(dllexport) bool TITCALL ResizeLastSectionW(const wchar_t* szFileName, DWORD NumberOfExpandBytes, bool AlignResizeData); +__declspec(dllexport) void TITCALL SetSharedOverlay(const char* szFileName); +__declspec(dllexport) void TITCALL SetSharedOverlayW(const wchar_t* szFileName); __declspec(dllexport) char* TITCALL GetSharedOverlay(); __declspec(dllexport) wchar_t* TITCALL GetSharedOverlayW(); -__declspec(dllexport) bool TITCALL DeleteLastSection(char* szFileName); -__declspec(dllexport) bool TITCALL DeleteLastSectionW(wchar_t* szFileName); -__declspec(dllexport) bool TITCALL DeleteLastSectionEx(char* szFileName, DWORD NumberOfSections); -__declspec(dllexport) bool TITCALL DeleteLastSectionExW(wchar_t* szFileName, DWORD NumberOfSections); +__declspec(dllexport) bool TITCALL DeleteLastSection(const char* szFileName); +__declspec(dllexport) bool TITCALL DeleteLastSectionW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL DeleteLastSectionEx(const char* szFileName, DWORD NumberOfSections); +__declspec(dllexport) bool TITCALL DeleteLastSectionExW(const wchar_t* szFileName, DWORD NumberOfSections); __declspec(dllexport) ULONG_PTR TITCALL GetPE32DataFromMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(char* szFileName, DWORD WhichSection, DWORD WhichData); -__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(wchar_t* szFileName, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData); +__declspec(dllexport) ULONG_PTR TITCALL GetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData); __declspec(dllexport) bool TITCALL GetPE32DataFromMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL GetPE32DataEx(char* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL GetPE32DataExW(wchar_t* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL GetPE32DataEx(const char* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL GetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); __declspec(dllexport) bool TITCALL SetPE32DataForMappedFile(ULONG_PTR FileMapVA, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32Data(char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); -__declspec(dllexport) bool TITCALL SetPE32DataW(wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32Data(const char* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); +__declspec(dllexport) bool TITCALL SetPE32DataW(const wchar_t* szFileName, DWORD WhichSection, DWORD WhichData, ULONG_PTR NewDataValue); __declspec(dllexport) bool TITCALL SetPE32DataForMappedFileEx(ULONG_PTR FileMapVA, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataEx(char* szFileName, LPVOID DataStorage); -__declspec(dllexport) bool TITCALL SetPE32DataExW(wchar_t* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataEx(const char* szFileName, LPVOID DataStorage); +__declspec(dllexport) bool TITCALL SetPE32DataExW(const wchar_t* szFileName, LPVOID DataStorage); __declspec(dllexport) long TITCALL GetPE32SectionNumberFromVA(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert); __declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffset(ULONG_PTR FileMapVA, ULONG_PTR AddressToConvert, bool ReturnType); __declspec(dllexport) ULONG_PTR TITCALL ConvertVAtoFileOffsetEx(ULONG_PTR FileMapVA, DWORD FileSize, ULONG_PTR ImageBase, ULONG_PTR AddressToConvert, bool AddressIsRVA, bool ReturnType); @@ -662,19 +661,19 @@ __declspec(dllexport) ULONG_PTR TITCALL ConvertFileOffsetToVAEx(ULONG_PTR FileMa __declspec(dllexport) bool TITCALL MemoryReadSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesRead); __declspec(dllexport) bool TITCALL MemoryWriteSafe(HANDLE hProcess, LPVOID lpBaseAddress, LPCVOID lpBuffer, SIZE_T nSize, SIZE_T* lpNumberOfBytesWritten); // TitanEngine.Realigner.functions: -__declspec(dllexport) bool TITCALL FixHeaderCheckSum(char* szFileName); -__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL FixHeaderCheckSum(const char* szFileName); +__declspec(dllexport) bool TITCALL FixHeaderCheckSumW(const wchar_t* szFileName); __declspec(dllexport) long TITCALL RealignPE(ULONG_PTR FileMapVA, DWORD FileSize, DWORD RealingMode); -__declspec(dllexport) long TITCALL RealignPEEx(char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); -__declspec(dllexport) long TITCALL RealignPEExW(wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); -__declspec(dllexport) bool TITCALL WipeSection(char* szFileName, int WipeSectionNumber, bool RemovePhysically); -__declspec(dllexport) bool TITCALL WipeSectionW(wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically); -__declspec(dllexport) bool TITCALL IsPE32FileValidEx(char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); -__declspec(dllexport) bool TITCALL IsPE32FileValidExW(wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); -__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); -__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); -__declspec(dllexport) bool TITCALL IsFileDLL(char* szFileName, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL IsFileDLLW(wchar_t* szFileName, ULONG_PTR FileMapVA); +__declspec(dllexport) long TITCALL RealignPEEx(const char* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); +__declspec(dllexport) long TITCALL RealignPEExW(const wchar_t* szFileName, DWORD RealingFileSize, DWORD ForcedFileAlignment); +__declspec(dllexport) bool TITCALL WipeSection(const char* szFileName, int WipeSectionNumber, bool RemovePhysically); +__declspec(dllexport) bool TITCALL WipeSectionW(const wchar_t* szFileName, int WipeSectionNumber, bool RemovePhysically); +__declspec(dllexport) bool TITCALL IsPE32FileValidEx(const char* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); +__declspec(dllexport) bool TITCALL IsPE32FileValidExW(const wchar_t* szFileName, DWORD CheckDepth, LPVOID FileStatusInfo); +__declspec(dllexport) bool TITCALL FixBrokenPE32FileEx(const char* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); +__declspec(dllexport) bool TITCALL FixBrokenPE32FileExW(const wchar_t* szFileName, LPVOID FileStatusInfo, LPVOID FileFixInfo); +__declspec(dllexport) bool TITCALL IsFileDLL(const char* szFileName, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL IsFileDLLW(const wchar_t* szFileName, ULONG_PTR FileMapVA); // TitanEngine.Hider.functions: __declspec(dllexport) void* TITCALL GetPEBLocation(HANDLE hProcess); __declspec(dllexport) void* TITCALL GetPEBLocation64(HANDLE hProcess); @@ -688,31 +687,31 @@ __declspec(dllexport) void TITCALL RelocaterInit(DWORD MemorySize, ULONG_PTR Old __declspec(dllexport) void TITCALL RelocaterAddNewRelocation(HANDLE hProcess, ULONG_PTR RelocateAddress, DWORD RelocateState); __declspec(dllexport) long TITCALL RelocaterEstimatedSize(); __declspec(dllexport) bool TITCALL RelocaterExportRelocation(ULONG_PTR StorePlace, DWORD StorePlaceRVA, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(char* szFileName, char* szSectionName); -__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(wchar_t* szFileName, char* szSectionName); +__declspec(dllexport) bool TITCALL RelocaterExportRelocationEx(const char* szFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL RelocaterExportRelocationExW(const wchar_t* szFileName, const char* szSectionName); __declspec(dllexport) bool TITCALL RelocaterGrabRelocationTable(HANDLE hProcess, ULONG_PTR MemoryStart, DWORD MemorySize); __declspec(dllexport) bool TITCALL RelocaterGrabRelocationTableEx(HANDLE hProcess, ULONG_PTR MemoryStart, ULONG_PTR MemorySize, DWORD NtSizeOfImage); -__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); -__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); -__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, char* szDumpFile1, char* szDumpFile2, ULONG_PTR MemStart); -__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, wchar_t* szDumpFile1, wchar_t* szDumpFile2, ULONG_PTR MemStart); -__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(char* szFileName, ULONG_PTR NewImageBase); -__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(wchar_t* szFileName, ULONG_PTR NewImageBase); +__declspec(dllexport) bool TITCALL RelocaterMakeSnapshot(HANDLE hProcess, const char* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); +__declspec(dllexport) bool TITCALL RelocaterMakeSnapshotW(HANDLE hProcess, const wchar_t* szSaveFileName, LPVOID MemoryStart, ULONG_PTR MemorySize); +__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshots(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const char* szDumpFile1, const char* szDumpFile2, ULONG_PTR MemStart); +__declspec(dllexport) bool TITCALL RelocaterCompareTwoSnapshotsW(HANDLE hProcess, ULONG_PTR LoadedImageBase, ULONG_PTR NtSizeOfImage, const wchar_t* szDumpFile1, const wchar_t* szDumpFile2, ULONG_PTR MemStart); +__declspec(dllexport) bool TITCALL RelocaterChangeFileBase(const char* szFileName, ULONG_PTR NewImageBase); +__declspec(dllexport) bool TITCALL RelocaterChangeFileBaseW(const wchar_t* szFileName, ULONG_PTR NewImageBase); __declspec(dllexport) bool TITCALL RelocaterRelocateMemoryBlock(ULONG_PTR FileMapVA, ULONG_PTR MemoryLocation, void* RelocateMemory, DWORD RelocateMemorySize, ULONG_PTR CurrentLoadedBase, ULONG_PTR RelocateBase); -__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(char* szFileName); -__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTable(const char* szFileName); +__declspec(dllexport) bool TITCALL RelocaterWipeRelocationTableW(const wchar_t* szFileName); // TitanEngine.Resourcer.functions: -__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUse(char* szFileName); -__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUseW(wchar_t* szFileName); +__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUse(const char* szFileName); +__declspec(dllexport) ULONG_PTR TITCALL ResourcerLoadFileForResourceUseW(const wchar_t* szFileName); __declspec(dllexport) bool TITCALL ResourcerFreeLoadedFile(LPVOID LoadedFileBase); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, char* szResourceType, char* szResourceName, char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(char* szFileName, char* szResourceType, char* szResourceName, char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(wchar_t* szFileName, char* szResourceType, char* szResourceName, char* szExtractedFileName); -__declspec(dllexport) bool TITCALL ResourcerFindResource(char* szFileName, char* szResourceType, DWORD ResourceType, char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) bool TITCALL ResourcerFindResourceW(wchar_t* szFileName, wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, wchar_t* szResourceType, DWORD ResourceType, wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); -__declspec(dllexport) void TITCALL ResourcerEnumerateResource(char* szFileName, void* CallBack); -__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(wchar_t* szFileName, void* CallBack); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileEx(ULONG_PTR FileMapVA, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFile(const char* szFileName, const char* szResourceType, const char* szResourceName, const char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerExtractResourceFromFileW(const wchar_t* szFileName, char* szResourceType, const char* szResourceName, const char* szExtractedFileName); +__declspec(dllexport) bool TITCALL ResourcerFindResource(const char* szFileName, const char* szResourceType, DWORD ResourceType, const char* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) bool TITCALL ResourcerFindResourceW(const wchar_t* szFileName, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) bool TITCALL ResourcerFindResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, const wchar_t* szResourceType, DWORD ResourceType, const wchar_t* szResourceName, DWORD ResourceName, DWORD ResourceLanguage, PULONG_PTR pResourceData, LPDWORD pResourceSize); +__declspec(dllexport) void TITCALL ResourcerEnumerateResource(const char* szFileName, void* CallBack); +__declspec(dllexport) void TITCALL ResourcerEnumerateResourceW(const wchar_t* szFileName, void* CallBack); __declspec(dllexport) void TITCALL ResourcerEnumerateResourceEx(ULONG_PTR FileMapVA, DWORD FileSize, void* CallBack); // TitanEngine.Threader.functions: __declspec(dllexport) bool TITCALL ThreaderImportRunningThreadData(DWORD ProcessId); @@ -745,11 +744,11 @@ __declspec(dllexport) long TITCALL StaticLengthDisassemble(LPVOID DisassmAddress __declspec(dllexport) long TITCALL LengthDisassembleEx(HANDLE hProcess, LPVOID DisassmAddress); __declspec(dllexport) long TITCALL LengthDisassemble(LPVOID DisassmAddress); __declspec(dllexport) void* TITCALL InitDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder); -__declspec(dllexport) void* TITCALL InitDebugW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder); -__declspec(dllexport) void* TITCALL InitDebugEx(char* szFileName, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDebugExW(wchar_t* szFileName, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDLLDebug(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, LPVOID EntryCallBack); -__declspec(dllexport) void* TITCALL InitDLLDebugW(wchar_t* szFileName, bool ReserveModuleBase, wchar_t* szCommandLine, wchar_t* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder); +__declspec(dllexport) void* TITCALL InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDebugExW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDLLDebug(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack); +__declspec(dllexport) void* TITCALL InitDLLDebugW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, LPVOID EntryCallBack); __declspec(dllexport) bool TITCALL StopDebug(); __declspec(dllexport) void TITCALL SetBPXOptions(long DefaultBreakPointType); __declspec(dllexport) bool TITCALL IsBPXEnabled(ULONG_PTR bpxAddress); @@ -765,6 +764,8 @@ __declspec(dllexport) bool TITCALL SetMemoryBPX(ULONG_PTR MemoryStart, SIZE_T Si __declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory, DWORD BreakPointType, bool RestoreOnHit, LPVOID bpxCallBack); __declspec(dllexport) bool TITCALL RemoveMemoryBPX(ULONG_PTR MemoryStart, SIZE_T SizeOfMemory); __declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); +__declspec(dllexport) void TITCALL Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) void TITCALL GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister); __declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister); @@ -814,25 +815,25 @@ __declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnEx __declspec(dllexport) bool TITCALL DetachDebugger(DWORD ProcessId); __declspec(dllexport) bool TITCALL DetachDebuggerEx(DWORD ProcessId); __declspec(dllexport) void TITCALL DebugLoopEx(DWORD TimeOut); -__declspec(dllexport) void TITCALL AutoDebugEx(char* szFileName, bool ReserveModuleBase, char* szCommandLine, char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); -__declspec(dllexport) void TITCALL AutoDebugExW(wchar_t* szFileName, bool ReserveModuleBase, wchar_t* szCommandLine, wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); +__declspec(dllexport) void TITCALL AutoDebugEx(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); +__declspec(dllexport) void TITCALL AutoDebugExW(const wchar_t* szFileName, bool ReserveModuleBase, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder, DWORD TimeOut, LPVOID EntryCallBack); __declspec(dllexport) bool TITCALL IsFileBeingDebugged(); __declspec(dllexport) void TITCALL SetErrorModel(bool DisplayErrorMessages); // TitanEngine.FindOEP.functions: __declspec(dllexport) void TITCALL FindOEPInit(); -__declspec(dllexport) bool TITCALL FindOEPGenerically(char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); -__declspec(dllexport) bool TITCALL FindOEPGenericallyW(wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); +__declspec(dllexport) bool TITCALL FindOEPGenerically(const char* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); +__declspec(dllexport) bool TITCALL FindOEPGenericallyW(const wchar_t* szFileName, LPVOID TraceInitCallBack, LPVOID CallBack); // TitanEngine.Importer.functions: -__declspec(dllexport) void TITCALL ImporterAddNewDll(char* szDLLName, ULONG_PTR FirstThunk); -__declspec(dllexport) void TITCALL ImporterAddNewAPI(char* szAPIName, ULONG_PTR ThunkValue); +__declspec(dllexport) void TITCALL ImporterAddNewDll(const char* szDLLName, ULONG_PTR FirstThunk); +__declspec(dllexport) void TITCALL ImporterAddNewAPI(const char* szAPIName, ULONG_PTR ThunkValue); __declspec(dllexport) void TITCALL ImporterAddNewOrdinalAPI(ULONG_PTR OrdinalNumber, ULONG_PTR ThunkValue); __declspec(dllexport) long TITCALL ImporterGetAddedDllCount(); __declspec(dllexport) long TITCALL ImporterGetAddedAPICount(); __declspec(dllexport) bool TITCALL ImporterExportIAT(ULONG_PTR StorePlace, ULONG_PTR FileMapVA, HANDLE hFileMap); __declspec(dllexport) long TITCALL ImporterEstimatedSize(); -__declspec(dllexport) bool TITCALL ImporterExportIATEx(char* szDumpFileName, char* szExportFileName, char* szSectionName); -__declspec(dllexport) bool TITCALL ImporterExportIATExW(wchar_t* szDumpFileName, wchar_t* szExportFileName, wchar_t* szSectionName = L".RL!TEv2"); -__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIWriteLocation(char* szAPIName); +__declspec(dllexport) bool TITCALL ImporterExportIATEx(const char* szDumpFileName, const char* szExportFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL ImporterExportIATExW(const wchar_t* szDumpFileName, const wchar_t* szExportFileName, const wchar_t* szSectionName = L".RL!TEv2"); +__declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIWriteLocation(const char* szAPIName); __declspec(dllexport) ULONG_PTR TITCALL ImporterFindOrdinalAPIWriteLocation(ULONG_PTR OrdinalNumber); __declspec(dllexport) ULONG_PTR TITCALL ImporterFindAPIByWriteLocation(ULONG_PTR APIWriteLocation); __declspec(dllexport) ULONG_PTR TITCALL ImporterFindDLLByWriteLocation(ULONG_PTR APIWriteLocation); @@ -842,7 +843,7 @@ __declspec(dllexport) void* TITCALL ImporterGetAPIName(ULONG_PTR APIAddress); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumber(ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetAPINameEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddressEx(char* szDLLName, char* szAPIName); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteAPIAddressEx(const char* szDLLName, const char* szAPIName); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetLocalAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugee(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetDLLNameFromDebugeeW(HANDLE hProcess, ULONG_PTR APIAddress); @@ -851,8 +852,8 @@ __declspec(dllexport) ULONG_PTR TITCALL ImporterGetAPIOrdinalNumberFromDebugee(H __declspec(dllexport) long TITCALL ImporterGetDLLIndexEx(ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); __declspec(dllexport) long TITCALL ImporterGetDLLIndex(HANDLE hProcess, ULONG_PTR APIAddress, ULONG_PTR DLLBasesList); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBase(HANDLE hProcess, HMODULE LocalModuleBase); -__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, char* szModuleName); -__declspec(dllexport) void* TITCALL ImporterGetRemoteDLLBaseExW(HANDLE hProcess, wchar_t* szModuleName); +__declspec(dllexport) ULONG_PTR TITCALL ImporterGetRemoteDLLBaseEx(HANDLE hProcess, const char* szModuleName); +__declspec(dllexport) void* TITCALL ImporterGetRemoteDLLBaseExW(HANDLE hProcess, const wchar_t* szModuleName); __declspec(dllexport) bool TITCALL ImporterIsForwardedAPI(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetForwardedAPIName(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetForwardedDLLName(HANDLE hProcess, ULONG_PTR APIAddress); @@ -860,20 +861,20 @@ __declspec(dllexport) long TITCALL ImporterGetForwardedDLLIndex(HANDLE hProcess, __declspec(dllexport) ULONG_PTR TITCALL ImporterGetForwardedAPIOrdinalNumber(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) ULONG_PTR TITCALL ImporterGetNearestAPIAddress(HANDLE hProcess, ULONG_PTR APIAddress); __declspec(dllexport) void* TITCALL ImporterGetNearestAPIName(HANDLE hProcess, ULONG_PTR APIAddress); -__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(char* szOriginalFile, char* szDumpFile); -__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(wchar_t* szOriginalFile, wchar_t* szDumpFile); -__declspec(dllexport) bool TITCALL ImporterLoadImportTable(char* szFileName); -__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(wchar_t* szFileName); -__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(char* szOriginalFile, char* szDumpFile, char* szSectionName); -__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(wchar_t* szOriginalFile, wchar_t* szDumpFile, char* szSectionName); -__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(DWORD ProcessId, char* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); -__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessIds, wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) bool TITCALL ImporterCopyOriginalIAT(const char* szOriginalFile, const char* szDumpFile); +__declspec(dllexport) bool TITCALL ImporterCopyOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile); +__declspec(dllexport) bool TITCALL ImporterLoadImportTable(const char* szFileName); +__declspec(dllexport) bool TITCALL ImporterLoadImportTableW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL ImporterMoveOriginalIAT(const char* szOriginalFile, const char* szDumpFile, const char* szSectionName); +__declspec(dllexport) bool TITCALL ImporterMoveOriginalIATW(const wchar_t* szOriginalFile, const wchar_t* szDumpFile, const char* szSectionName); +__declspec(dllexport) void TITCALL ImporterAutoSearchIAT(DWORD ProcessId, const char* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); +__declspec(dllexport) void TITCALL ImporterAutoSearchIATW(DWORD ProcessIds, const wchar_t* szFileName, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); __declspec(dllexport) void TITCALL ImporterAutoSearchIATEx(DWORD ProcessId, ULONG_PTR ImageBase, ULONG_PTR SearchStart, LPVOID pIATStart, LPVOID pIATSize); __declspec(dllexport) void TITCALL ImporterEnumAddedData(LPVOID EnumCallBack); -__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, char* szDumpedFile, char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); -__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, wchar_t* szDumpedFile, wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); -__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, char* szDumpedFile, ULONG_PTR SearchStart); -__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, wchar_t* szDumpedFile, ULONG_PTR SearchStart); +__declspec(dllexport) long TITCALL ImporterAutoFixIATEx(DWORD ProcessId, const char* szDumpedFile, const char* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); +__declspec(dllexport) long TITCALL ImporterAutoFixIATExW(DWORD ProcessId, const wchar_t* szDumpedFile, const wchar_t* szSectionName, bool DumpRunningProcess, bool RealignFile, ULONG_PTR EntryPointAddress, ULONG_PTR ImageBase, ULONG_PTR SearchStart, bool TryAutoFix, bool FixEliminations, LPVOID UnknownPointerFixCallback); +__declspec(dllexport) long TITCALL ImporterAutoFixIAT(DWORD ProcessId, const char* szDumpedFile, ULONG_PTR SearchStart); +__declspec(dllexport) long TITCALL ImporterAutoFixIATW(DWORD ProcessId, const wchar_t* szDumpedFile, ULONG_PTR SearchStart); __declspec(dllexport) bool TITCALL ImporterDeleteAPI(DWORD_PTR apiAddr); // Global.Engine.Hook.functions: __declspec(dllexport) bool TITCALL HooksSafeTransitionEx(LPVOID HookAddressArray, int NumberOfHooks, bool TransitionStart); @@ -882,17 +883,17 @@ __declspec(dllexport) bool TITCALL HooksIsAddressRedirected(LPVOID HookAddress); __declspec(dllexport) void* TITCALL HooksGetTrampolineAddress(LPVOID HookAddress); __declspec(dllexport) void* TITCALL HooksGetHookEntryDetails(LPVOID HookAddress); __declspec(dllexport) bool TITCALL HooksInsertNewRedirection(LPVOID HookAddress, LPVOID RedirectTo, int HookType); -__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, char* szHookFunction, LPVOID RedirectTo); -__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(char* szModuleName, char* szHookFunction, LPVOID RedirectTo); +__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirectionEx(ULONG_PTR FileMapVA, ULONG_PTR LoadedModuleBase, const char* szHookFunction, LPVOID RedirectTo); +__declspec(dllexport) bool TITCALL HooksInsertNewIATRedirection(const char* szModuleName, const char* szHookFunction, LPVOID RedirectTo); __declspec(dllexport) bool TITCALL HooksRemoveRedirection(LPVOID HookAddress, bool RemoveAll); __declspec(dllexport) bool TITCALL HooksRemoveRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(char* szModuleName, char* szHookFunction, bool RemoveAll); +__declspec(dllexport) bool TITCALL HooksRemoveIATRedirection(const char* szModuleName, const char* szHookFunction, bool RemoveAll); __declspec(dllexport) bool TITCALL HooksDisableRedirection(LPVOID HookAddress, bool DisableAll); __declspec(dllexport) bool TITCALL HooksDisableRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(char* szModuleName, char* szHookFunction, bool DisableAll); +__declspec(dllexport) bool TITCALL HooksDisableIATRedirection(const char* szModuleName, const char* szHookFunction, bool DisableAll); __declspec(dllexport) bool TITCALL HooksEnableRedirection(LPVOID HookAddress, bool EnableAll); __declspec(dllexport) bool TITCALL HooksEnableRedirectionsForModule(HMODULE ModuleBase); -__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(char* szModuleName, char* szHookFunction, bool EnableAll); +__declspec(dllexport) bool TITCALL HooksEnableIATRedirection(const char* szModuleName, const char* szHookFunction, bool EnableAll); __declspec(dllexport) void TITCALL HooksScanModuleMemory(HMODULE ModuleBase, LPVOID CallBack); __declspec(dllexport) void TITCALL HooksScanEntireProcessMemory(LPVOID CallBack); __declspec(dllexport) void TITCALL HooksScanEntireProcessMemoryEx(); @@ -903,53 +904,53 @@ __declspec(dllexport) ULONG_PTR TITCALL HashTracerLevel1(HANDLE hProcess, ULONG_ __declspec(dllexport) long TITCALL TracerDetectRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace); __declspec(dllexport) ULONG_PTR TITCALL TracerFixKnownRedirection(HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD RedirectionId); __declspec(dllexport) ULONG_PTR TITCALL TracerFixRedirectionViaModule(HMODULE hModuleHandle, HANDLE hProcess, ULONG_PTR AddressToTrace, DWORD IdParameter); -__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, char* szPluginName, ULONG_PTR AddressToTrace); +__declspec(dllexport) long TITCALL TracerFixRedirectionViaImpRecPlugin(HANDLE hProcess, const char* szPluginName, ULONG_PTR AddressToTrace); // TitanEngine.Exporter.functions: __declspec(dllexport) void TITCALL ExporterCleanup(); __declspec(dllexport) void TITCALL ExporterSetImageBase(ULONG_PTR ImageBase); -__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, char* szExportModuleName); -__declspec(dllexport) bool TITCALL ExporterAddNewExport(char* szExportName, DWORD ExportRelativeAddress); +__declspec(dllexport) void TITCALL ExporterInit(DWORD MemorySize, ULONG_PTR ImageBase, DWORD ExportOrdinalBase, const char* szExportModuleName); +__declspec(dllexport) bool TITCALL ExporterAddNewExport(const char* szExportName, DWORD ExportRelativeAddress); __declspec(dllexport) bool TITCALL ExporterAddNewOrdinalExport(DWORD OrdinalNumber, DWORD ExportRelativeAddress); __declspec(dllexport) long TITCALL ExporterGetAddedExportCount(); __declspec(dllexport) long TITCALL ExporterEstimatedSize(); __declspec(dllexport) bool TITCALL ExporterBuildExportTable(ULONG_PTR StorePlace, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(char* szExportFileName, char* szSectionName); -__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(wchar_t* szExportFileName, char* szSectionName); -__declspec(dllexport) bool TITCALL ExporterLoadExportTable(char* szFileName); -__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL ExporterBuildExportTableEx(const char* szExportFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL ExporterBuildExportTableExW(const wchar_t* szExportFileName, const char* szSectionName); +__declspec(dllexport) bool TITCALL ExporterLoadExportTable(const char* szFileName); +__declspec(dllexport) bool TITCALL ExporterLoadExportTableW(const wchar_t* szFileName); // TitanEngine.Librarian.functions: -__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(char* szLibraryName, DWORD bpxType); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(char* szLibraryName); -__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(wchar_t* szLibraryName); +__declspec(dllexport) bool TITCALL LibrarianSetBreakPoint(const char* szLibraryName, DWORD bpxType, bool SingleShoot, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL LibrarianRemoveBreakPoint(const char* szLibraryName, DWORD bpxType); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfo(const char* szLibraryName); +__declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoW(const wchar_t* szLibraryName); __declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoEx(void* BaseOfDll); __declspec(dllexport) void* TITCALL LibrarianGetLibraryInfoExW(void* BaseOfDll); __declspec(dllexport) void TITCALL LibrarianEnumLibraryInfo(void* EnumCallBack); __declspec(dllexport) void TITCALL LibrarianEnumLibraryInfoW(void* EnumCallBack); // TitanEngine.Process.functions: -__declspec(dllexport) long TITCALL GetActiveProcessId(char* szImageName); -__declspec(dllexport) long TITCALL GetActiveProcessIdW(wchar_t* szImageName); -__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(char* szLibraryName, void* EnumFunction); +__declspec(dllexport) long TITCALL GetActiveProcessId(const char* szImageName); +__declspec(dllexport) long TITCALL GetActiveProcessIdW(const wchar_t* szImageName); +__declspec(dllexport) void TITCALL EnumProcessesWithLibrary(const char* szLibraryName, void* EnumFunction); __declspec(dllexport) HANDLE TITCALL TitanOpenProcess(DWORD dwDesiredAccess, bool bInheritHandle, DWORD dwProcessId); // TitanEngine.TLSFixer.functions: __declspec(dllexport) bool TITCALL TLSBreakOnCallBack(LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSGrabCallBackData(char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(char* szFileName, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(wchar_t* szFileName, LPVOID bpxCallBack); -__declspec(dllexport) bool TITCALL TLSRemoveCallback(char* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveTable(char* szFileName); -__declspec(dllexport) bool TITCALL TLSRemoveTableW(wchar_t* szFileName); -__declspec(dllexport) bool TITCALL TLSBackupData(char* szFileName); -__declspec(dllexport) bool TITCALL TLSBackupDataW(wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSGrabCallBackData(const char* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSGrabCallBackDataW(const wchar_t* szFileName, LPVOID ArrayOfCallBacks, LPDWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBreakOnCallBackEx(const char* szFileName, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSBreakOnCallBackExW(const wchar_t* szFileName, LPVOID bpxCallBack); +__declspec(dllexport) bool TITCALL TLSRemoveCallback(const char* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveCallbackW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveTable(const char* szFileName); +__declspec(dllexport) bool TITCALL TLSRemoveTableW(const wchar_t* szFileName); +__declspec(dllexport) bool TITCALL TLSBackupData(const char* szFileName); +__declspec(dllexport) bool TITCALL TLSBackupDataW(const wchar_t* szFileName); __declspec(dllexport) bool TITCALL TLSRestoreData(); __declspec(dllexport) bool TITCALL TLSBuildNewTable(ULONG_PTR FileMapVA, ULONG_PTR StorePlace, ULONG_PTR StorePlaceRVA, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(char* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); -__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(wchar_t* szFileName, char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBuildNewTableEx(const char* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); +__declspec(dllexport) bool TITCALL TLSBuildNewTableExW(const wchar_t* szFileName, const char* szSectionName, LPVOID ArrayOfCallBacks, DWORD NumberOfCallBacks); // TitanEngine.TranslateName.functions: -__declspec(dllexport) void* TITCALL TranslateNativeName(char* szNativeName); -__declspec(dllexport) void* TITCALL TranslateNativeNameW(wchar_t* szNativeName); +__declspec(dllexport) void* TITCALL TranslateNativeName(const char* szNativeName); +__declspec(dllexport) void* TITCALL TranslateNativeNameW(const wchar_t* szNativeName); // TitanEngine.Handler.functions: __declspec(dllexport) long TITCALL HandlerGetActiveHandleCount(DWORD ProcessId); __declspec(dllexport) bool TITCALL HandlerIsHandleOpen(DWORD ProcessId, HANDLE hHandle); @@ -959,30 +960,30 @@ __declspec(dllexport) long TITCALL HandlerEnumerateOpenHandles(DWORD ProcessId, __declspec(dllexport) ULONG_PTR TITCALL HandlerGetHandleDetails(HANDLE hProcess, DWORD ProcessId, HANDLE hHandle, DWORD InformationReturn); __declspec(dllexport) bool TITCALL HandlerCloseRemoteHandle(HANDLE hProcess, HANDLE hHandle); __declspec(dllexport) long TITCALL HandlerEnumerateLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); -__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); -__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerIsFileLocked(char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); -__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) long TITCALL HandlerEnumerateLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated, LPVOID HandleDataBuffer, DWORD MaxHandleCount); +__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandles(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerCloseAllLockHandlesW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerIsFileLocked(const char* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); +__declspec(dllexport) bool TITCALL HandlerIsFileLockedW(const wchar_t* szFileOrFolderName, bool NameIsFolder, bool NameIsTranslated); // TitanEngine.Handler[Mutex].functions: __declspec(dllexport) long TITCALL HandlerEnumerateOpenMutexes(HANDLE hProcess, DWORD ProcessId, LPVOID HandleBuffer, DWORD MaxHandleCount); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, char* szMutexString); -__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, wchar_t* szMutexString); -__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(char* szMutexString); -__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(wchar_t* szMutexString); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandle(HANDLE hProcess, DWORD ProcessId, const char* szMutexString); +__declspec(dllexport) ULONG_PTR TITCALL HandlerGetOpenMutexHandleW(HANDLE hProcess, DWORD ProcessId, const wchar_t* szMutexString); +__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutex(const char* szMutexString); +__declspec(dllexport) long TITCALL HandlerGetProcessIdWhichCreatedMutexW(const wchar_t* szMutexString); // TitanEngine.Injector.functions: -__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, char* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, wchar_t* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, char* szLibraryFile, bool WaitForThreadExit); -__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, wchar_t* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteLoadLibrary(HANDLE hProcess, const char* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteLoadLibraryW(HANDLE hProcess, const wchar_t* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteFreeLibrary(HANDLE hProcess, HMODULE hModule, const char* szLibraryFile, bool WaitForThreadExit); +__declspec(dllexport) bool TITCALL RemoteFreeLibraryW(HANDLE hProcess, HMODULE hModule, const wchar_t* szLibraryFile, bool WaitForThreadExit); __declspec(dllexport) bool TITCALL RemoteExitProcess(HANDLE hProcess, DWORD ExitCode); // TitanEngine.StaticUnpacker.functions: -__declspec(dllexport) bool TITCALL StaticFileLoad(char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileLoadW(wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileUnload(char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileUnloadW(wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); -__declspec(dllexport) bool TITCALL StaticFileOpen(char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); -__declspec(dllexport) bool TITCALL StaticFileOpenW(wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); +__declspec(dllexport) bool TITCALL StaticFileLoad(const char* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileLoadW(const wchar_t* szFileName, DWORD DesiredAccess, bool SimulateLoad, LPHANDLE FileHandle, LPDWORD LoadedSize, LPHANDLE FileMap, PULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileUnload(const char* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileUnloadW(const wchar_t* szFileName, bool CommitChanges, HANDLE FileHandle, DWORD LoadedSize, HANDLE FileMap, ULONG_PTR FileMapVA); +__declspec(dllexport) bool TITCALL StaticFileOpen(const char* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); +__declspec(dllexport) bool TITCALL StaticFileOpenW(const wchar_t* szFileName, DWORD DesiredAccess, LPHANDLE FileHandle, LPDWORD FileSizeLow, LPDWORD FileSizeHigh); __declspec(dllexport) bool TITCALL StaticFileGetContent(HANDLE FileHandle, DWORD FilePositionLow, LPDWORD FilePositionHigh, void* Buffer, DWORD Size); __declspec(dllexport) void TITCALL StaticFileClose(HANDLE FileHandle); __declspec(dllexport) void TITCALL StaticMemoryDecrypt(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); @@ -990,40 +991,40 @@ __declspec(dllexport) void TITCALL StaticMemoryDecryptEx(LPVOID MemoryStart, DWO __declspec(dllexport) void TITCALL StaticMemoryDecryptSpecial(LPVOID MemoryStart, DWORD MemorySize, DWORD DecryptionKeySize, DWORD SpecDecryptionType, void* DecryptionCallBack); __declspec(dllexport) void TITCALL StaticSectionDecrypt(ULONG_PTR FileMapVA, DWORD SectionNumber, bool SimulateLoad, DWORD DecryptionType, DWORD DecryptionKeySize, ULONG_PTR DecryptionKey); __declspec(dllexport) bool TITCALL StaticMemoryDecompress(void* Source, DWORD SourceSize, void* Destination, DWORD DestinationSize, int Algorithm); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, wchar_t* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, char* szDumpFileName); -__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopy(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyW(HANDLE hFile, ULONG_PTR FileMapVA, ULONG_PTR VitualAddressToCopy, DWORD Size, bool AddressIsRVA, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyExW(HANDLE hFile, DWORD RawAddressToCopy, DWORD Size, const wchar_t* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const char* szDumpFileName); +__declspec(dllexport) bool TITCALL StaticRawMemoryCopyEx64W(HANDLE hFile, DWORD64 RawAddressToCopy, DWORD64 Size, const wchar_t* szDumpFileName); __declspec(dllexport) bool TITCALL StaticHashMemory(void* MemoryToHash, DWORD SizeOfMemory, void* HashDigest, bool OutputString, int Algorithm); -__declspec(dllexport) bool TITCALL StaticHashFileW(wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm); -__declspec(dllexport) bool TITCALL StaticHashFile(char* szFileName, char* HashDigest, bool OutputString, int Algorithm); +__declspec(dllexport) bool TITCALL StaticHashFileW(const wchar_t* szFileName, char* HashDigest, bool OutputString, int Algorithm); +__declspec(dllexport) bool TITCALL StaticHashFile(const char* szFileName, char* HashDigest, bool OutputString, int Algorithm); // TitanEngine.Engine.functions: -__declspec(dllexport) void TITCALL EngineUnpackerInitialize(char* szFileName, char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); -__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(wchar_t* szFileName, wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); +__declspec(dllexport) void TITCALL EngineUnpackerInitialize(const char* szFileName, const char* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); +__declspec(dllexport) void TITCALL EngineUnpackerInitializeW(const wchar_t* szFileName, const wchar_t* szUnpackedFileName, bool DoLogData, bool DoRealignFile, bool DoMoveOverlay, void* EntryCallBack); __declspec(dllexport) bool TITCALL EngineUnpackerSetBreakCondition(void* SearchStart, DWORD SearchSize, void* SearchPattern, DWORD PatternSize, DWORD PatternDelta, ULONG_PTR BreakType, bool SingleBreak, DWORD Parameter1, DWORD Parameter2); __declspec(dllexport) void TITCALL EngineUnpackerSetEntryPointAddress(ULONG_PTR UnpackedEntryPointAddress); __declspec(dllexport) void TITCALL EngineUnpackerFinalizeUnpacking(); // TitanEngine.Engine.functions: __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool VariableSet); -__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles); -__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(wchar_t* szFileName, wchar_t* szOutputFolder, bool LogCreatedFiles); +__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(const char* szFileName, const char* szOutputFolder, bool LogCreatedFiles); +__declspec(dllexport) bool TITCALL EngineCreateMissingDependenciesW(const wchar_t* szFileName, const wchar_t* szOutputFolder, bool LogCreatedFiles); __declspec(dllexport) bool TITCALL EngineFakeMissingDependencies(HANDLE hProcess); __declspec(dllexport) bool TITCALL EngineDeleteCreatedDependencies(); -__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(char* WindowUnpackerTitle, char* WindowUnpackerLongTitle, char* WindowUnpackerName, char* WindowUnpackerAuthor, void* StartUnpackingCallBack); -__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(char* szLogMessage); +__declspec(dllexport) bool TITCALL EngineCreateUnpackerWindow(const char* WindowUnpackerTitle, const char* WindowUnpackerLongTitle, const char* WindowUnpackerName, const char* WindowUnpackerAuthor, void* StartUnpackingCallBack); +__declspec(dllexport) void TITCALL EngineAddUnpackerWindowLogMessage(const char* szLogMessage); __declspec(dllexport) bool TITCALL EngineCheckStructAlignment(DWORD StructureType, ULONG_PTR StructureSize); // Global.Engine.Extension.Functions: -__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(char* szPluginName); -__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginLoaded(const char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerIsPluginEnabled(const char* szPluginName); __declspec(dllexport) bool TITCALL ExtensionManagerDisableAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerDisablePlugin(const char* szPluginName); __declspec(dllexport) bool TITCALL ExtensionManagerEnableAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerEnablePlugin(const char* szPluginName); __declspec(dllexport) bool TITCALL ExtensionManagerUnloadAllPlugins(); -__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(char* szPluginName); -__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(char* szPluginName); +__declspec(dllexport) bool TITCALL ExtensionManagerUnloadPlugin(const char* szPluginName); +__declspec(dllexport) void* TITCALL ExtensionManagerGetPluginInfo(const char* szPluginName); #ifdef __cplusplus } diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a deleted file mode 100644 index 3b9d6016ac0e191c7a44b4c7b61824c2511940e0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 327286 zcmeIb3w&M2UEn`DQrk3yK0=z%(ua~JZ3wB6Wm%R(2(c|WR*-FBIgSY-@s;kebmOag z)qAgOIU9n>hG0rsLP$%1(k)O*DGOV=(0>;S8=%W;%VWC*x}}tEfl^9=^6El?^8fv2 z&N=fuzdQFtsGq6kd_KSXn3?mKneX|X-^_1j&eb>9I!i0JT>6!x`nGdoY|rG*vE36> zqoZRyO8p!i9iP~_2clp*btz-RcQJO)yBMq8!r0R1gq(gSVzh;7(@Av%Z0r51B{_O_PCJmo@Wf@ z4I@IHd^ck#-`^DSrYjgjdGpT-`QiH*LwV~BLf-ZX#!!CzF(E%W!5GR`NfYihVtHz2>I1FF^2LRr-c0Gjf|oE_9unB|Lu&S{BBRk z2j>_=`2)CClt288kdMBXF_b@ki;#~$z!=J(-y`Hxql}^aH52kTpJEK=ou_2VH zCxm>}J!}Z&mQf+MeuNF79C)XYgFQBcGCMBhYd_0|P>#G;$k%PKA(Z1c2s!Z~HiYu^ zkO!2zr-j_}88(Dcd#jN8Nj8MCe2I_-ToX$3ej)8CHiYu(zY@}WoDHFzJ0#@%zpx>c z2cRrbzIj8)LvTKnhyPy4x4nrCp}YpdP+t2yA>a8F8$x+}Mab(Re<WF60C6VM8dt|AdeaL4HvF@D)P- z=woaM`ZNS%UIKJt5DznI$OC`<#$3c^gYmuDmGZg{N48^5Q8WFMAG4 zP_F*4kZa$<5|mdyDCC9{EJ1nIr9!^)_gI25{$?S&TP#7Dx>CqZ?_mkbSKlS%Yd*yi zl>Hk*X0B%m%5Co#a{I$9K{*WhLpk~ z%`8DV4cCdX@&O@deuyO~Ex1OMSKlb4`!SZFoPCp!^T%0&^1zFQJosUjpnS^(ArHTl zB`A+T7|OT9HKRNVc|m#I?+E#>vn)Y*;tC;e_yv}reD7%?ZyaX{%A5X0$PfM+OHkhO zxR4)(azlChn2?_sVF}8Af#ajR^X)=@2CfU`-A9D{+$&gu^7Ee+@)V>+`Q^6>`IRSG zg7WK71}N`?azOd*%Y*>u3CahctWbWxF62Ykumt79e93SOht`+jRkFf+~c<4zXBX_Z3lxMwI$g|(i zhEXnilaS}Guwj(T$Anz*SvHJv)q8}z=zcbg@{*f{yzF1tFv>OW7INLgY#8PGn}po( zX*P`Vs&@(*dz=lU?7C0L*f7f6 zyM!EtbD|uZ7jnl08%DVkt_|g`-w^VR?_k3yryvg~OGkvHpJBr&D{mKa2Fd`Xb-j?a zkF#Nv?gxdO{WUg>a{i4%9)SFyd^6+)iQHwgKuLu?r3 zr!N)qu3uooC}6K}0b6Alg$<+p`X_|E55iG?`-qVD!*NkQ z@EbyYe~k^Jd}vz8A70LeQGjhOAKPHVD1Qpqit=Y47V^pOW5Xzac|yovf0hlS{4JCn z%0D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%0DB4jDs^Wb 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 kECe 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 STT09}zO^wn5pzvH=l=tEIC{YV diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index b8a422d47a2458a388d55d4976f3e4c41da85b97..cdbace174e9bd4e51ba9ea6de1c01c665685aa36 100644 GIT binary patch literal 105896 zcmeHw3zS_&m39?D9uWZ%0Rb_*A7V&C=fOkBqdTOb(`h@M1Q7{0-6!cwy6@UFplFmj^pb`L{wBnL{xkuBBTGePd!e(Zw~juzy7tz zT06JT-n;f!wd--})Y+%%@Y5@e;n6c@o;1t;H@9oC^ZH{pcb=58ufc(U0yG^l&$>yBY86lk{o)LjNh?6a6o+LHxC!5_G|A z#);TQN%!FQ9>)H7hoGmBC!%lOF6h4f86*16aguJp?+uK<=1@sH@C)kwprEr4U>wB0 z@sOZzE`lA>bB1*$zLs6NCv(cTXT+Gl`q5c?i{NA!dJ1bzP) z#&WtDzc(|!7xDyR-(DaI<@q+~e)uOR_~d^0=A4Tp-H%_;p5GU=*KtS>dOmzZG_zmQ zUHAn(|HFdD<}glFYYG~_lyRc5TLg{ojccMO1TF1iJf{!f7xXUpJ*Ru{3tIUnLH)>A zPWRy#wCqVi-8IIE_)lC%eYiKYdeaTnu6XPzkN66g_a z92B$!ekRHu&51oY%5r-2CbUP;17FICXRt|h9?C^@5%Nm38Fff>9{faB@Mm>P)Ul3G% zm~o>tO#nw0-m;qWiWB`oWdx2SktO#CL<=a=HV*puOQ|qCNJObOnBio)ENb zJK7h~UV=tBs%(j zLC1U+*Ps*c74!<&&*^Ubf=)y^iB3LB(7X>bPBa^SBRc6$L9-X&8gx>Zpf2Q<2;DuW zIj1t76UsgZH1}3Pr~Hg@qEjytv}l@fqWMUd)8+UD%>_Quydwm4?GO8)lW!4p>Z3>x zI&DPK_wfrl9eF1@9=b#)>?Y`VN7{-Z?JzdaouuHT6c_CVeddUfGVIgS2 zZv`#-HS!BOWkS#im%=^~^odTtSI{fbcXRq8enDq+3wrs(jOWzAFX%{M1WM zen8OC8_+&LN5P*tJ&0e>3-*(=9lxM`;jf%Nf?v=fpA>Z6fLY{^|Yp#&=6n;UkI!@AU_yw){te^qphiGk666$6xXdUVY z#D0f+713|d&xs!YxS(HM&R9<9ufGEQ_Un?)!!PL9O-Ya87xWw4?}>hQm!QYd_d&e( z1VJm%#)+0AUqmaq1f7Mvtzo0kWD(KQVjOT>wOF@^x|3t%RLqsEJS46}63c3(= zl+&U31yzm^bOF*5t%p3PS@;E2P$xtiZj^KwenIa9ZcaDj7jy{9O!SUB1zkIv@ti)4 zU(j3N5282kE$B+*jp%I~1?~7U<3w-&s-UZ<87F$%cLZJiOI(9?tQB;{{*32zEq+07 zxkAuYz#w{ix1g*3glo`SpOADpenD4l7xd;Uksr{NGX*tvV>~BdH$anL6x2MOaiYc} zf+o)eAM`q4=LDa;4mAC^peimUV^+69ekdk{dO=;^x}&J9ryt3f)0W_CzRnJ&`Zu2^y)swbGjS9 zpmRqg-G^V$I^+$+{``cbz41$g`!9&kQ1m$drarw}PW&D46No*whoGP19!>N!$aA_1 zzo4Jv8G`7i;OBHTenC&p7W9XYFh=xyMaSW9&=Yq^IuXC1Kh6>KB=|&s0FUSwu$|Kt z_yzqE`Ob;q7xWnN0OGsfm=n9_b|z>q{DQu*JSV>2LGUYR&zhi1_QiY!bo1Gg;Jcea z?}i+3-`JtFA+3mAX@g7xcrR}QQi99rMqvwGQJ@4(Qi!SzGcW~J6s+f=P( zZ2kKFHGO@)61&XM5;{XG*7TpVzI(~g61Kj3YJ6g#Q6J7GCt;#GKC#|r8S-@j1@H`w zo~;2DVp=*OJ3U*arIp!uy|K+Sqc~(k{B0S~tU_*QLnx?RsH=btorl3}Q?*{R{GnNd zA}=fx1<%m1Ga^+~PV{BSj?T-<`pDE6)vm4@#mUQ?ODzLJ3|1kxvmq2zF4R@PMxKX( z%49Pe=vk3fMzV&=hQqWjwIP?=v$ff%3^!M2!%cWsnR2=IwKnFl2eZj~qq)2~mPv!U zx=<#m_O&+Uv6qav*)ciA-`ax3T2`Of z=48ZT85i1s%^O6ooX#8@4%52Sc3ket%I0jz*qExc!F4^VC4?kCPa6)3Q0)F}i_^p$ zrgf>!xm@eI=s+IZVTA4FJqZo1dU4i={^aB@An;h)Zb-5^Ypx!xG%~l1_u%!pPE6s}Xjm0u9bZyx@fPExgX<2``vUIs(|sj*GYy6S|Q7pSxr%ec_#Z64b5SanlvK;NDWhW@iC zhQ%^2v~`=;J4uyGrCSS_k-|(WMjbB3G?fWmfA6kuxmVHvn$Hn?mw z8{WKnYFv3ZAn;hGZQBYYy|rqyJKHd|Nm(=)`cG}acWL($g{W^7@#)KyecZx z?sfVd{Ne*a!^#bBA6yB#vKGV+h(@4X%6o$*S;?N;PVU4@_{vE zGNf#XQ1Sr2%eAiylRm%T7$CB>XedLpY%HrZdbSQ{d0!CoC{-(A*|ModBdaxIX(H0q z%}TR6+?UlhHAksGOipIw=p_m&DvqWI2s~EdsGvxIMss5cJl(=}P-G-7G##dKsr+EE zR#uwBqXU&@Gi%feBQDpxR%UD-Jq;J>)fN3JeepN$fn%ngxFT+$M}H$r!=r_wzRdqn zs`6qmn;5GMXN9)GkbkNa`VxI8AGn66 zP`)r2`p?3L7Hf4go9L}I>ndq+O@GlkfhiH!tE;t5SgnCv%M1?kxuVh-*@DN|;7}bB z2GbNdj*3wcYid)I*@$nH7Ud?<_Ei>lN>$t(d}GQ;T)w2)tPGFluH96Cy4>z8q~&t$ z>%t8_ABB>TBbZz-txRTE#b_8SzzGFIMAO%FVow99>Hdsoz-9xLuN>sD!B{?3%NGg< zDvioGmJG})3CNJ*Y%I-oXOrjzc@H&=dlFx}@K;#YJ4r^)!u)2_P`zhsHayid2AG&M z#8>$W%g|_bPaCR^XRD_48bMH$FYY7Dat*(?wz1wAx5}T=NG6O3l|76zjph`Ffhb}~ z14ct^y?hc9E}3f9bEg!QWU-73Ju$a=;@NO%hT2mtzo>@1mD(b>x~I{=Q!|EdeIs(1 zz2g&DfzBFY1+crgVFd&>3$sOyZW+l1w(hFN2-@>lG>Iu!DSNh3&U%*&xhRIf(=B`( z6a|>t*I}9FqDP`dW+SVy{ORS$7OFI8C2(st0QE5hB*L#Mky4Ewv0`iDY&P>2UjjBdKBt#eEC5oqJ_cB_RxE-34*VK+Ted zf_N4@4I>A#mT0Xp9|W^RRa#0(8;J@wj0Ef2kOvx-tVT=8$O*(&eOh|rcCxeDh8}#> zTN}x?25ZL@2GRt|pi)>ZQB*QSGkZ7#F(||H zZmwOaLZ!R#YCP-@j|T2WjxdxxFxlmAP^S9@XDgtvVV}X|Mi6iN}>UR zj=)3ovyM=)^}?;|5ks(|Uf(=PtF=Ro zN^P=ghNlEY0cJ6HM1(oJcT%>*!EB`3Kp;%9${&~K5_BJA4zu4e#Ckc+Iia9L^xIQw zHn!1XKy^&74#nlUq_;MSH`a)#Q28|icM=M=2<^XRa#ts1!Ev?Dqiut zVg(3D!>P<%8OUCGQ_rxJ$hPJ@ny&Mg;YB1wZfDGN@k zC-{I3(!x+N(6iKif_1s}^@1){IG+#BP|%*mwY4mJh92=(R7dbu5pQ{o6;GSDregXAOEWtFrGf^(DPls!i#YXP>V*7+muKFE?(CcL@b8>akZdM80Fvf}bzf z$jcC-Shg`0qG^j}l2l0u_5C=lqorpxDjVbl@@`E&(mE+=pcnxh($ZEa9&mN7GBG(? z_gjN445snRZ6<HBF~Cnfda129%DMk}>VnOb4@+W#^~Twq&* z0IVz5Db*kHl{-4fW)C)~qnHf}v5^GrWtXHDPN>G^wJ5!67XoRP3cw z)iDWZjR$dgOj3*kDUG;Hw~eHV64JAd_&bQp68Z`{EgFRQdmFvEQH?MvjtF!a6uVmgbVA*V<~-D zCn*%@^-%sP&RVKj;~6|480uRss%TkdY-~fN7)S#GkEJscl4zdQgk7$E?HkM!gAKjB zGh;^N+H?4>W>L){iO)0hV42Qq6#8`kCvPow zQ}JRts^(hjwbJli6UmlYTQn494Lk`c>wbQG4W--gQU~(jCQqV=eCrw@9i0Pu@v1Jo ztlL7R)-c(Ah8<}zRUn&YG7@9O4V}S!yfiuD@4jq08=I@LZSz)CCP!_KT)Xi2LJNy? zSQ88^mPExufcFRI)aqMm(Ud_2oz_UUwpzi$>0mZIFgAt7Yr9yml2RQS#gKxJ1jWkh z;8d+fu`)T+8VFmdDLd3K#oy*cB_>sTT8GFHLWvxqN;6PFFqpW|C6>9gL`om+2|X^H zz?P{LLo#qMlE@RQbU8eNtHrf`%#4baK;$Bx(3h)}IimAHa9F0e!d4`SBUEXYp{dY# zMWJAV=Q=*55l>xo=CqEI_SP;!Pg_DEs(B=r8K#-mNlE=&gmChaMK&)?4b|-*_gV_% zq@YoO(KDSDfiDVnClV;t-bo!U-CJ8(sn&$Rb#zp%up|Cj-9%8X?AE@KkdA9%2?F}2 z^{c6vwBRqPZ4(!M(cKUmo!vOzC~oeFVfffRN{TM1N~u$ZpzJYfJMe|{75o|rVq zFJ2);#SuZu4?SBKbmAz9_)dSqRI-Ak{$U5`(6=w$}ZUDpJ@xDgH2rgP^D|CjK&u6qbd!x=<0JWb0=Y z%9h~i0X?bWnsr};i*GRCG@+=)GF?6>iP?(asQQh|O$p{LJ zFyMfPRTAml41^3oM_Le}(*$n>D+qttqJX}OWF{yO0uFGB7}Rh}NNr*zqVl(9$u^-? zWO`J(PAOOpct|0d)-AE0xF|PdDr$dZ-Dq`qRLprt@*Mh^Na+^&iE9P2mQ)t)o#rfZ z2~}k&An;fkEF=-Ud`Tx?2iJS71Oy(-v20j@L}=3-S{BXDvn8OX{Z%~!=HtD^k{4%X zwX9Jcu8fW8Y=$I0PiHhJLgkAATGxTfYDnVqwDq8fy0kQ$O|GjpN1ZB+%k!^0s6#jo z^!Z}3dpTaauB=W@=3iDI*+^C!t`;gqpA;EVRr`Lal`z?ex}q zrpB7u1eT36y#B0>)VHX5PH6}kUfkJ9`|6ukVs406j<%7cqQuER)^9eZ@YqWm8;lzd zmnjXbKW2!DtK$i>2HXbr9LSf3#A2+@MhmT&6%l=-ABtM4xe79V$zH8$p%fA04lK;* zyT?u_x+Fn4#VGFG@BdnNut|jqsm(Gi=6SiPthJDL(`Mw6|W#*IF&S-i%`8yvx5|3C>rY+TM1>8__ zPly6w|{R2zR9ayqvsCQ^d z|N5T(vwHh`)-PMtKh$&X(E8@$#f#6AxoXSAnW%v_;oGoqCcV^c6TU4IaQ@as3$b;A z`Yu@yP9X_+D_5QyQnlInH`>N`rS!>maXC4>ZEUQvzJU-ugmKVwE4H@^GR0`%i_ndN zOiOy&YHt@Q@Fa~+S08d*4Rp*m~i>=}%m z@fF6levPq@W7qH_e$3d!BaB^(UpiXk<3GfS9S<>f7-$FR0q{KoD%K%kKCiY(aMWHyPXiKE{sw4r4cf z4t))0J3t@o}}57syvs&n?h-kc5W!`a8b$Jl;9 zVCy(jTk!YZ_D~^yD(mYTcYI<(z#IG_5e+T?mC0B6Nz^TXM-D&=OvsynsGMzAY(Vdk6(I#u|06zbsp?qgfebMp78fp z@YX_h%?M{>yK?p&Q2+Bd`z&nC+r-(epf7)mv0c9lnucGHm$f~xGr`&Iprxp{dw}sI ze7OU3+n*R)47v|>(g0nLvYZIo2){lBzkd$44|^eJC+yDI!K0{y8Jv9rdAS7k9|7I= zdd@CJ8NLADKV0SP0_62N=r4l*x1%1fL>)X1nztM37&M0Z*?SMpt^hp&+75s11=<1I zXJ5nFZ(qRK=kfbF)Zwp@{z8=HF8F2|w)>AkeI1Rm;`iPYq5lfb?gm|ezmGZ@{+Wlo z&F1XRlTg?A?ZWSlF3#8j&Q6^Je9*0PIs4fusIOCDa}i|oIlCNm6!=FV{r=Fu1-2fA zeB?B=4bTOrgMU0{yPW`g`2EukaV7$Wf?g(0=gUcF^hja`q9>ClBH5@#~QHHSo&-+R!SbA4Hx(2e0Pr zM$iF6um!pTI!}R)dllLQ=(Es09ch|tQ6A95I+WpesPo^T?_=lj%YTJ>1%3UujGYH+ z;)IUJKo>!N7xWfE=Y(GPdh%6MqF%Q{2Q=?ZXgim2 zw(I3+=b*J74kWk;umx<^sXL;uSPiA7r(b$2)}@is6c)JuGe!m3v?T< zZ`^=344U&!^h3~c_~p)bpl@D_HUrw_EohT(hP^A%?%#&~vxBp*z8&>*HToB>e~I6< z;O&0}>IrlO^mn-mbqSq6;rEHRq78wz z*=_8v+264LV*km$z`n>n$3D;ggME#Co!!U2$^Mqz&OXFG%s$5MV1Lj4j@`-rk$swd zf_;X4lzoK#E4zz*oPCP@3;PH5-|Wlmf7qAUKeMl}ud;t)pJaEle`B9z|IYpoj-&hr zyO*8IUd@KsTDFd@Vdt~IVrQ`x?0xJe*3VY42AgCD@`Lz`_>1`ge1EHkDtSr@MZiAzLatgSGQcr@fa+ZM}=Z z>p$~s8S9eXqB#t_kFYr6nzq8t4;6w;{!IdB8(7*DN^f{+TtGFlKejkqgkIK&b4A2? zA9&A4M~>KR%BvK(XORTiLf<$+DBpxgl!G!9*?c?Czt~<_|4F9wzB}gUtAd$t2rvE& zZKf+E)&V*mt3WXH@(@%{6?vyPKXdzC`#QH}Y^+bg26_u|<099?D+LuwO0NjS-?l_# zLkkI?F604U#oszrE-6x}v%W}EN9Pz9DxH++gz{SA$z#U^xV%s)^`)(gD-mvxSCDuY zjrObFGmEemGd4x2i1Q)bkP|7(KL81a>a!WvN z%#~0hiOZ;v`4$6NLvNp;7|tF7ijCLR$eOb?ff9=Oe)B0DBw1OPbBDnYAWbD$Tj`1t`KZ#1yhpD=H*6=sLWhL-7$@eTrY6W z4Zcux55Ezr_E9sGE$0jyQZx41r>2>ItR% zNOiRd8y-9Ru^S?~i(A{RLslFyfD12BB?sThz0#51*(F_O-VPmsT5&9uaUqqJEWh^{ zV)~leJb@}Ia_k5XlU3Qw`mICPax+U2n=UtNwy)_665@!{O)2tB?~D$%2o+ZQ(1YO| zq33c$R`8jJx9K@FjV-QnOygSSLVe;sY{d-%Kb-FA_J*}KzwiFsuQ=!9F#S( z&@|B1Yy-Q_YDMYegAMTtmhG_h0r`3>&LnJ1z? zGMxo|Dn!09kM9-U-DWgLvY9&9kxl+&nIcjvwRpHt4<;hWN1a%ZZ{uvU@*8DFfPu*39n+J{zsxWEy)#2idM|t#8 zEcs%i4pB5Ix0#q#>Rr=4KvQUW#VUc;0)SsWQ|bZG)W|w8!0=YFcQx9%2y72ZJ)>go zfVv5#bA^uEg%|}9d*2&?mL!$R8cA>mH5^>Hjh>2xarwZgkQ{+gSS*W) zQSaP3>{pjLXXuf+*k);Q3399xp~J|J(!@6*5rG9{r^)>oNoFEZ%bK=M71N2-N=*KJ z2aYlh98T`@VB0?H&b*@hiu>)LJ`q`5=OZuO>FF>#oG~`gBc4i~OIVl3*y%IwU`d@t ztN$b%;{vJl9+~Kt&JMO(wDY@y7D?33xdkV*|7l8UX3n{R>SW^1C@=AlWR%AhiK35* z&3}ENi5A#2)-W89TDHX+l+L2LAFN@;WSiJ3ov8h#$S<}_Rm|{Ks3~b~n)b`FK4KN4 zrtuLhL6DZg(kW@|lYLI987!$bong(WSewU#n&>~W7<9s{VCa=1>oT{JAHPU?`W!~= z1B6evj5T?ZI;=eDBz7sK@l8JO=kP91D&||&=?71k%Qvsf4U28;JejCnxyhX;wakWh zgENhXHEf8mjtN9_yFk`Wwq?>3SazHZ@|4XsHtD0WO3#do7J;2Xv><;WfI*aIuMKtn zZ@v|#lHgY#c??BsvCO`vVip`@v5c7ZQJLWAcS`z@JTS#7da?f|v5aHfa2a~96lBZX z7_A;^`btV8CvQSiErjJoQWr8+afu2vbTN}L*T`ZL$BMAwEM6h4#UUkpC#a6!6q}XM z^S^$d<*{-Yy>(H(q68zFfm?B2m$b7_!KLBEy(Vm(Osr|x*Or1WgEaoDtMC~!T2E~z64 z^EFqFsCrK#`U+5-;i|s}%>Tf8J3;G%%xNc4z3ZviSX5uaxWCb8h)3o0HS-x9vFS_0 zVvkvuqY|51Dyh4bYYyWwMK;BKYFS0?xC-CH2~9B(R;k+AnM~P0FAbR%4?}@18dbW`zIE`d%yCF+mIzB~?#^vGX>3!v zLP7i`)`ShrNx`>wp;M{6eG)B!T%RqBC3bbhY_NA=Xw~5Q zytLw04|)HZzCK?`eS41D@Lr2Odta}MQ%gJW6}cTsBnxLVsRN1+J;n2%^k+U!2KeOK z>iEQZGNNblE~ij(0+ghp8K&g1bmDNxlF*kCM>OL%1D6uQqMS0V8^mO#wS{I{BcMs8 z(5xcsk>DngLeD{!FEyh83QnL^@-g(!e4=bJLQ_;zZaqXr1TMaj#%K^CZ-z{l+YW>( zif4vP85l;8l+2Jhwe(mM9b2^V_mcL4o}fN zm5i*$gSJdS(I|tVTc%nxfXh@;PQXL+&TN=MceS0{W5y|!!ol6f4eSbK2Wo-vE~VLG z=Pns!B?fu1`lZ^9xKi);>H2r>GGlSWKn0cfOLZ%P~O|aa))mCKXlSSXfE)+}6f~UfLFX zW`>f50lk2-v>G|I*zmD+a9P-z9b%?+jKDI(i3ZoGpeC{Ps2)#!y{arL# zS~XKh^tUasgV0PpTVeniL24pPWYw8R87w2E7ok?*c_K5J8^Wew{XjM;F~Zpdhq{&< z)E1LyWF)fI>~sQyTX?h3HrDTS5+mfz<^=-ZJO!E}TH$Y6qX>f2EN{-QoQwmfo$>3OotwNwKXHy&ah>0t^BHoZXJlH?X(WZ)2d!j zo{-3put4~o%2-@O7uQq~{u3O>gnoTt1?yS)2&uR*T8CC<1(3e6$(&d!diz`p3GE;d z#OJCAdpeXaEEeGgahY2HKsyn9j-z~qfC<%#LxFy7UgEm0VezV-DyX=XN~fA4KbcSx zi{%R54FiQzdL2Z#!zDQ`H zZ6JOEvEc}^WCtM%p$f+lk1=?CsBGJUJRmWYLO$Gt66%mc&!mIs z#1NnshB39+v+P7Gy0#s$mt3zqxd~}B&!4c&Lzz@bgO6rfSOhuRRU#g|WT<0QNG&IB(bu7vveuT0c9S%Su>?6YZ$-)pg~YGWLS}^!+Iba9PPAW3l@1Q8vDXZo=uCIGbHqh*D}+<#$l%$EBAnCEB8K4$70hWCUhxV`R+y(W zmIre>!JeiF^`eVp1b!+NKhU$#_GLzn{ZLS4k{&$iVLRWY)F@COib5pu1Oe529LRvH&GhU1vgAJDb{%|lB{ zVI$9 ztU_?&UyIB;0>>8JY2+AVCou$85jNfnm}OqczevLAO?-SeUKONg~*`l}-RC95QR>Rb(ivXEtsX=Ns1aq3KCOh0S_+ zrZ50viUXFN;9SQo)V}DBi&>Jw-}&RVH5!fd`l-*1#uaFV*mzxx_g?e_hIhQ1i;!Zp5;IKLvu??Qc1^3+lDm;Hi(e!# zf`}z>9@=Y#5=R6^R&+S93@bKMP)ERIEpJ7kV?(L4=zMBJ#4U2E+2#tWh^8g;#0@B` z&|^0@Isn-esIX%@D~jt_C$?xZwz@ZSw#6ce8J=wBKucSkg6jI+N~Z&sP0LnXv7IGL z)vZ?}{i)-VYlOotziFL@cU{Dycj&xRTu$Vd< z#HB%WRZYcyn)C^ZSqfM?U7$+ykf5;K2pOtfLo6`9Gz{GMyeiCa& zhr$T`oNFr^!PL^Y3^NXeRJYPFyb%enwk@QBtZhwXn~2gLHdnp;#WSldn} zBCySn?T|cTS0ol$cQI*B(jti4MpAE;bttzKSDTd@T8?^UXa;oK8u2&WesH%;84K|? z#lb*tN5Oc@%GPk&B*TaZ9dX=7%0xS;)MTlq~T^JamY(w9FfMgCVm}=muY2 z7+RvxJ7-a@ii=F74R590232)vIO|j;t8kl~lbyms9d95lB9+L$b!xQ~R;?qHEQ9um zWigRkd6V85M@D0kpx~%xBsoR{k{qLbpy~Kb;7X?3Tol`DC{j>Vd$2-1EvF6*d7@bu zTB!!1)nrpBuEjHnXdsg7R=>+e#TP8A$|c*bY{|5%*=H7xE~@r2nx{nj;}0B&g&oVqKWzMtebDFJE%g>i zHg<4l42Py@J>oBBv+mvnzXxE4clx)FQ>bIvi}u|ee6mUZW`gR|`>m`FH|mr1jm=rd z4IV$Muebl4T%H%Fg z6@4*ddA3ItCod$Wn4vgbqyq-iI`az-@sFba&CiIE4QHlP z^p-7W-uy1317fKN8cvYtIf zId;~C7!;_(_Hi1~`tow_+SYE}PF_lnw5Kdo1F)U9mB<@T@?vf62JU9AbZ<`OZkIfF zc#QBOk$3Xz!?trbe{R@!FN5!9;9g~aJ?K^qEA5T>Cx`K0M|h&-CpKL+RL#(eL;>II()!|DL>9Eh>UB;19$HzZb!zOM2Yt?knL}dpV<=c z8^!HJiBn_33k9Us50&-|~Bqr9GRf&x3=Q9ce|0yV)TT)b>Y%`H`m}T3k3Z zh}r?nNNbt}%$EvGbH4?zLQA)y#C-WMA1_duWf4>J*O%pp#m*6qZMU>7dq`@mo29VS zc4sbF`MwdEh0xR0;SO5Bk)`oco;)JQqn$4Duus=>?sZE~rtZT>+E{_2Ij(Jumhj|J zE}Gxz%6l?0i=*e9qiwuSphZSAdV)JfqlrCB9M5&M-j21gp5b~s&PD5lClmE{yp8t^ zqn)78)Qe@e;!3y4)LPBU9kf8zmB&lmc~123e0MqpZr#Ttb8UJaeuabAK3eKdFk7Li zeR!Orlz$#g)!j)B+B02ub3DBEy_vcj%ysbEM@!A-=MkFtTDT*#`Gt`?54~17SzytY zMfh4l?eF7lrqp)pSrD0%orpYi6?q8m)8v9X*DZVHg2;$E7ufR+Y=p0ccYtyL%lDmy zk#T`ui7wcQ9JJrwQvP4)=D=4Z7A_uX(w%W%} zw7^pfeC2lp**n{KwV#8?osgdBPxEtN>=5QcJJ+piKk~lh0?h3q%_()a&V&wr(l zjn`Ptwq{OYpGMD*_?=$3o)OG}zhj!43Fo?X4Mg%lb$_PFLu4;D2dQ+=Pp#N5&XMI- zX}I@bTV(Mun2X|Gw=QpF4e1pq?-CzXh5<#u%eT3Nx0jme?#6O%Io<2l15&TVp4D-krwoKtE5tlkG9l)sd}E@yhq>)LWtDCZhcbW!tz55`I3*#6>VJI+eY@ zVB6@aIr0h|q*KTV4`|Jd=-;|xKv@COK z#5~7D#=WZ8$jPovKz=E$!K;kz4swx5H@8s;4M ze=wB;8h^0ynVSLUx@G;RTHxvszW8A8S!#hp@f>uh1*W2o)<|??@6@*aotibQ_3`|{ zz4REDD&aZ>;{En8Hogy;Hr9VlT}WcGUi`p~Nh5#Obbx#e)LTb8RUGSfW> zDCa4Z4$Nv(rFo6O!G62#)>5i8=PQ&BlqU7=_q7Vg-U+zvvZdawUl7LZL@SKkOY%@{ z12s5JE#0eA>+lz9G#ocHR@vq`v@}|34qkE4d{;VcwPjCB)!znz=I!R(figz!#1!c_ z96{|sStHL@6niovQJvkX9e0+W^`!b_7Q}47oT+#08*|KJOKrD+&UNed6PeReyvZiQ zqUTg+vu+2&ZBDH*BQsfw&l(M5`c5t1FC%xpSwO8yRAb8!w^Z(R>rzJUffN;fk&oAj z`$xjBn{C8m^Aoo+%lkF*?u6c{j!D#F!*v(Vxo+vz1&P(_aTCqo%H4q~KNh6k(bODl z+TO$5CEf*hu3MHnbq}jcY`y=yW4wGxQ>z>k63zRd#O)#Ob;~lQP+zA}YZ#5{wSfw@ zSVjs zHW_lA_%vE=WId8%;iet5fIG{Ne2F{C77x$Ag*onR*=kZ_-&O~YHoP@iL%b`qw&YZ~Jf8t*;W^1U@N`dub*X>XurCXWem3tApA z;oHk4qP4x5S4bxdt!p#!g!IM`qTgA{moibG+ZCpNR;W|7@*`5Jr@Tqx8fUMx@7qLe zUg6_)qNgNgCT~`VSz{d0DAYyree_+oI@c{*(85SBp%2xsl$b5gr*S}^M%^Y#{uY@F z_vjlJ)VXe1^3?49D#DZpri2dFaj@LB)*3s~Zz&?;t!eBI^x)Ln)T>=|F+>VqxaD-O z+bZ|l3}o81J8K~NkB+br*pn_;`Bs*CpSPn0y6<+U4YXDEw};S+UEexU_C$-jCWfxg zTyl!~G(4X`e}{pt7oS9(i+z~dM~^%wP~5_`HoCx7r~I^yoO;52X9zhza>0dlu3NUW zR4mMOF;u^Sm!27$&w<5JtsTUTUYDUThwThko=`Xshr@Us417{R7Jh2CvrtNr)_ z$9*}d?r_(#))z+l*h1vuhMmoY?~Kwlk$OY%9wQ&-L1b=W%a1Uro_1pd)i1152Q7V` zD(ibKRMF0<*>|9(cTqI2H4CO9I(Ag3T>_>Ass9!T&<%K?GX0aC~{}NE@Sl5kBBx zryTD%p=H}nMfvqFYk;x^>ATEAkXu_Sdb@152EaJ6hvMp1bKQjN5$tRD&qi_qt_mFG!3lceFwe6u)e1OFjGjorN#< zy^U<$P}=MBBTpX`tMf6!727;#4e@0W_Tq6}TYkor!u)$5lg@N?+*uwob+7)ok14-p z3KiGMO3Rj&icIlL>&W~4P!+}E99%xAa_|6>f*f0!%Zh7<8Lp9tf20yQyC z{*#NUkL~rUwsdJz``LXmiW{ij^2mvq{y#^NeOH%l&8ZT9%EWcfIPQS26Em)VNg%gh z=F}MZX%ktW;MIO|Hn3%N8pMMk=e3ezYU8QjEvT)Uo_p7THXB{YS;@( z2hDA6t8L;N2uelg!kJE45vj?C&QZu#?OF6b4KJVCwP zlBZhxe}*vwoy^Ha>-vt<GP{FN9Ie)6N~Z@*_(s^6S5Rd|BiDQ{x)~!I`D&d10iU z7oqfDY=NF~gX5OgwUD@D|F@eD`mP&|F8sQ(lgM8RA>+BGGsvlX%KtdX`lNcNc;(w$ z>aP9e2x_34m2PRN=c%vwxE*;jo7(s0t6|Jkqb^Yttfhjyq>7@ z`yFf%WR@s+>0Xx_X}{e9y%Tqr)H>mJg7`FbuT1)nqow;=Bszd1VZNI}4ivjIcB0N7 zNMmacN%)u@3$$?2Ge*1hVh!(lwnZ^MfYx z%KCJ+s!_#;mX$HQ(sP|#e!iIMSwBo5w_oPem);NM$hB${-8ldH(JN?K52yBb{gI32 z7q0Y(nc4yMVU0&840=T?j}=+-ru_hZY+(fkrP64rdV9n{^Bq~X-cnz4|HMLTA1hU| zM{}%6>{u(}b=uz-BQ<;fsX)s=gUzb7O?e-{H@O{XE0OgOI=AF!1uFVo2e2Y*ZM19p z&n>JD)LjIN-mN_*u;???v+D5XP+guE?iI0Y>r9K)?a7B&{5 zQ-v;%oGA706UZH@>%=p~6G?2}>m=?9Y9Wa{7DO0M6Bg|6%Sy%Zn{nS zY0PpH&oY0su+=8XVc@dfPOXYQMYt;~n=|ZiC%=WB99-Aq6}B{HV*L8wFs5I*rTbHA z?(`>t+8iDos5G(ZgdenDx{Q%lJPTv=pIx*-m+d4T<5Z9NnLUG9WrPC%+ONY%U!lDw zc!8I{6$}EFufNC>DDD2R3n30vCY#wnkJur~D`0uNL=DdH@caf^wg$T*9z77{+g0G9 zeYRh&uE>n#CBS)}#tAgZ(jH7bVeUpqXpLjlO|=1kNGXq%c*5M>!siWnyx)-t53Ti^%<$A`td&h3>n% zbl*)qqwZtjr#Evi?e)lrOW$PdYvbmDTpjIKkx`i5QNA#V-HGul)!z1Nf$mp$X}?FF z)9Kyhi!AiB8kG%&*TakGrO_knFce?4e=GEW^ULC=)_GrS;df?t)Kt910Tv!j_0_22 z4QU=nCg?WTIxODyzt)rqX*Z96fNAKVJvcYWzP zPp$eLBJgPgCfdlbb7vYxMp9aVJG8)D-pDe!KI2t#`Eo`^Fj{GRX%N$QZrPTV^6g;- zCcSffR?7LZAZ7>385y5xoqU$UoTfF2V*RE4IZ$e+_QMNQIaGAwjPKNa;D`coRmb+N zPCU;Z>EX3skE!R(qXgc>SY_B>iYVP1Q_q=48%TkhcWJCtFFZzIP2wYi&Yq8+7;TOX zVzysg&L;?!*6U@$E0(ZsCll{R80PnAflv7ez(rzV^Aaj}zH z2hIUVl=Do9m`Abo)$0>O)$wfAR0rPcr=AxUOVpkk9sjiu80M2;^NlYNoYP zqCI9D(MD44Bn1O~`+N-HG z=fMJ%9>(%b={xWol2}_`Z6hL_HJ{f8f*VWs$jCTE_pc!vl^#C5VwT2>yw|7Lv^73n z2l_|qDPgUR7~B%LlOm}^KC>ifo;1UQ?vBf7KqQlcM_?%q6-RSQO@pc7@<{-PJ9EN`fh4{ z0JpJiq7zS=krh5Vcj>|iYA5buskvSyg1dSm8?ILTN6*szC-F?bp}-!jY!Q`A8@+iA zy8L}R;pyQBYDYXBd9J7R@{uTR;Gm+?B~CpNW(j0}z$#nAsXn|hirhYKYA>iw5!`1M zb+ka0Z(K2C1&5BZKJJRVUp^S^swz;kiQZbX?sc8gNRfLw#hzcJkUFyNmMYU`jfB{W z_RAC*gXnwJF@aQ{2!A48x*w)izsCt{sBiVs%JAl?i4N_sn3xaMJiHFH|42)uxT?Cs zYh;zpt7^+C2mnG++pfPO|j(k6#igUWm z!rht;Pc^euwK06Se^EBv%tk~u+JCc?+KKRTGY?pIEDl1%TZsH^xMH8E!Kqq}_W#J6d$7Be&p~9=q_1t>WaS{Q@+CFw#gR9IWq3Q>evgaX zo#<a<_<@}5uB{gpO$&(`5A4_WE0t*lgQ zkw#xW2Z=bhx7ayI7QOTspJ;Peg>Y9lt7Bub@weaR66+*yHPHtuQRIAy4>|S;Oj&QI)*IjEp?0ioMdl6kc6o=1iYP*y?wfFP>GDSU6|Ho>-A9hOxudmv zjgK2~blK7_jFk2?l=dAaDmDgDPZqduQh)}1XC-pcGo1xq9aP z7>IZ_7f*@pBPM#|UmA!b*pO1*SC)97dyON8&AX? zcLp`l*Z8>o{wKV*0`w8{Se1?pU_ AKmY&$ delta 18609 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 D diff --git a/x64_dbg_dbg/XEDParse/XEDParse_x64.a b/x64_dbg_dbg/XEDParse/XEDParse_x64.a deleted file mode 100644 index c08940befee42657e126a80d2d1c2c16da647a06..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2912 zcmd5;O>fgc5S_#=l&A<)6$Ij9q#`bralYI{LMWAr#04pb9ylNzmn2QpBvf&bD#W1& z#JNAIXVl+BnK$dT*NIKiOJSt!j%S}UvomjJ{rq(>{XBS6dS$1jTy0kBUZt_;*|sZ7 z=4jjHYAt%9QzD`}{QE^@9kTjZ{Wh+MHm-dC!`p*)Fb#YDnOE}ze>e%oJ@N;=pgXrj z8o3{az46hAQT}jz8lz(K!D#e87*3*P{nQQn$1~?kypg;elwH^JcvtmCGu}b>CpJK| zQy_XE+B!M2-q}p_{K2Mn$LR*MARi(tEoxsnM`5@GM(4l{@rOG#jon~njpH((4eB7SKJ!EA&1E<&ZtgGR4MLB zMy{+pjFG1`!5{-^iE=49TIVIJkc*N0fCX0Je)>Q>14+=5V_NCJt`EM6bql z6zP;S6FtrxD#f+`*G#NP7(8qv8jkBpR8>?ai-{U<&IT@Kwz;l#;IuwJZ?eH6j5wo~ z?4!k)Z`n9c$A!wii!j>8JHEVr zfv1a$#Fl7<#rsfd3!kdq_gGVWQQW}05lf7_3vT&@7`K#kT{3ehJ(ePFNw(mD-%>p` z>7Uvn8Avfw_KM1@h*X3`@U9s7h&2dKnzHQ5vl@!D&x*ct;;TOA3m}ur(szZm?rN;9 zH_a~q#oF&2@G{mOVpA-bZj-g248MP4?I0Vsz}jgxE@mzAa8uS2>F+UB<^P|pNxUXo XHGdPfZlUCn6zL^vik$lWY)<|G%@$fn diff --git a/x64_dbg_dbg/XEDParse/XEDParse_x86.a b/x64_dbg_dbg/XEDParse/XEDParse_x86.a deleted file mode 100644 index 286630e1c8c23c34a63a125a4dcc35cdf5a71da3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2940 zcmdT`&2G~`5FW=Z2~qhuR0siwMJgABj2#jul`0gZa4S*|91sT_mn7KA4=7Hh960a@ zeWX4>pMgiA%*=Y7b-ZrEp_N$0v+LO}`}57`*?oQ#&c8-)>#s$=cyA6HEx*xe9}3}e zmu`jdTFvwi{W<{L!RI%C-N)vEd}@~fwaXy*^uBiz&XZxV?D#<##ItZZgdm89;b5%~ zy}ilgLm1DxUITyl9#4M+1+Ngg?osNJp)elD`uU+WI{e?6eI1j{J8@7W{twJa-@EpD;nBf8=qi0 zPn9x^#*tly(fFY~+ZNe;NjYS0cCqUk4D&+Kx2=2mLDDxhI$!iTw9~9^} z+XV&s$Q(t8Vy?5wE`zy21vb=l`@9-}$7xh4GA0Eoyk2X#OwoG3Y7HwYTThcGHEA>nK5~r)8=K#6pf}$C$v`IC6 zQvgrcN>c$38)fNNedoDc%^FTzES?ndrY!0=GY!( z-`mvb7j53_bQ+m)1)a{#xJ;)MuWfY-pmIlcE8`gduUdU1MX71kNj+3mpoccQzGho4 JyNH_e?O%D4V+{ZR diff --git a/x64_dbg_dbg/XEDParse/XEDParse_x86.lib b/x64_dbg_dbg/XEDParse/XEDParse_x86.lib index 53e0a789f41b38171eda776330ccb4b6cd6aa193..5e87ad2ae514518f65ef4a459a6eb533f97133af 100644 GIT binary patch delta 243 zcmeC<@8h2!$!TI}U~X(^Xks&tlXV#Hqlk!4)@I^ospJt0nQX_jktx4y z@<*m<5aq}G8bzVlUB;w5%OE>2>gMnt6m delta 243 zcmeC<@8h2!$!Tn9WNKz)ZfrLB9Glogi>s&tlXV#Hqlk!4)@I^oF}TDKJlT$EBa`&p z$sd`bL6jf!YZQfIlOtFJAPRF>Iw1(=dTmfE8r&waK|G@{{A3 vq$l5JEraNk=5k2R&n?i)OaWUZHF+8vs%|ZaRe#uw(G2xt7lBBnv1flags.d = valflagfromstring(cflags, "df"); regdump->flags.o = valflagfromstring(cflags, "of"); + Getx87FPURegisters(regdump->x87FPURegisters, & (regdump->titcontext)); + GetMMXRegisters(regdump->mmx, & (regdump->titcontext)); + return true; } diff --git a/x64_dbg_dbg/lz4/lz4.h b/x64_dbg_dbg/lz4/lz4.h index 766a6052a..3adcc0db6 100644 --- a/x64_dbg_dbg/lz4/lz4.h +++ b/x64_dbg_dbg/lz4/lz4.h @@ -60,8 +60,8 @@ extern "C" Simple Functions **************************************/ -__declspec(dllimport) int LZ4_compress(const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllexport) int LZ4_compress(const char* source, char* dest, int inputSize); +__declspec(dllexport) int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int maxOutputSize); /* LZ4_compress() : @@ -98,7 +98,7 @@ LZ4_compressBound() : return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ -__declspec(dllimport) int LZ4_compressBound(int isize); +__declspec(dllexport) int LZ4_compressBound(int isize); /* @@ -112,7 +112,7 @@ LZ4_compress_limitedOutput() : return : the number of bytes written in buffer 'dest' or 0 if the compression fails */ -__declspec(dllimport) int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllexport) int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); /* @@ -125,7 +125,7 @@ LZ4_decompress_fast() : Use this function preferably into a trusted environment (data to decode comes from a trusted source). Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. */ -__declspec(dllimport) int LZ4_decompress_fast(const char* source, char* dest, int originalSize); +__declspec(dllexport) int LZ4_decompress_fast(const char* source, char* dest, int originalSize); /* @@ -140,7 +140,7 @@ LZ4_decompress_safe_partial() : If the source stream is detected malformed, the function will stop decoding and return a negative result. This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets */ -__declspec(dllimport) int LZ4_decompress_safe_partial(const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); +__declspec(dllexport) int LZ4_decompress_safe_partial(const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); /* @@ -154,19 +154,19 @@ The allocated memory can be provided to the compressions functions using 'void* LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). */ -__declspec(dllimport) int LZ4_sizeofState(void); -__declspec(dllimport) int LZ4_compress_withState(void* state, const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_compress_limitedOutput_withState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllexport) int LZ4_sizeofState(void); +__declspec(dllexport) int LZ4_compress_withState(void* state, const char* source, char* dest, int inputSize); +__declspec(dllexport) int LZ4_compress_limitedOutput_withState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); /************************************** Streaming Functions **************************************/ -__declspec(dllimport) void* LZ4_create(const char* inputBuffer); -__declspec(dllimport) int LZ4_compress_continue(void* LZ4_Data, const char* source, char* dest, int inputSize); -__declspec(dllimport) int LZ4_compress_limitedOutput_continue(void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllimport) char* LZ4_slideInputBuffer(void* LZ4_Data); -__declspec(dllimport) int LZ4_free(void* LZ4_Data); +__declspec(dllexport) void* LZ4_create(const char* inputBuffer); +__declspec(dllexport) int LZ4_compress_continue(void* LZ4_Data, const char* source, char* dest, int inputSize); +__declspec(dllexport) int LZ4_compress_limitedOutput_continue(void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllexport) char* LZ4_slideInputBuffer(void* LZ4_Data); +__declspec(dllexport) int LZ4_free(void* LZ4_Data); /* These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. @@ -198,8 +198,8 @@ When compression is completed, a call to LZ4_free() will release the memory used */ -__declspec(dllimport) int LZ4_sizeofStreamState(void); -__declspec(dllimport) int LZ4_resetStreamState(void* state, const char* inputBuffer); +__declspec(dllexport) int LZ4_sizeofStreamState(void); +__declspec(dllexport) int LZ4_resetStreamState(void* state, const char* inputBuffer); /* These functions achieve the same result as : @@ -223,8 +223,8 @@ Any other value means there was an error (typically, pointer is not aligned on 4 */ -__declspec(dllimport) int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllimport) int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize); +__declspec(dllexport) int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllexport) int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize); /* *_withPrefix64k() : @@ -241,8 +241,8 @@ __declspec(dllimport) int LZ4_decompress_fast_withPrefix64k(const char* source, These functions are deprecated and should no longer be used. They are provided here for compatibility with existing user programs. */ -__declspec(dllimport) int LZ4_uncompress(const char* source, char* dest, int outputSize); -__declspec(dllimport) int LZ4_uncompress_unknownOutputSize(const char* source, char* dest, int isize, int maxOutputSize); +__declspec(dllexport) int LZ4_uncompress(const char* source, char* dest, int outputSize); +__declspec(dllexport) int LZ4_uncompress_unknownOutputSize(const char* source, char* dest, int isize, int maxOutputSize); #if defined (__cplusplus) diff --git a/x64_dbg_dbg/lz4/lz4_x64.a b/x64_dbg_dbg/lz4/lz4_x64.a deleted file mode 100644 index 6d38e9bb571d95564bcc8072c106e60b30f79d53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33634 zcmeI5-ES4g6~GT`Ac+h4AOr}3V{qBKG=7w*0F1%JuD zZY)|wR#YJrRS}B%P(}SK`q1Yn5B&qGKK8kPLLaIs={Yky-)HyET`87U-jQZ^J#%(u zcjmX}o|!YdKJ!j{(@&y3JSKgNK_q`KN z_46`L?+2hb^A8zkp8!z&@w|*b`40fa`G3lI^)mp9*DlJq@OJ=;KYJ|W2de-Se{oaB zn>7H6xA1(5zy4IlJMREcTzpo>_WuAVcK$8nZ}9#pKG>FVadG)kbFsbHUu~~+VR5P3?#L8)|HJ0u*6RJWmGzD8<|ZCK zTwVKk_2*lI^{v5;{v#A#?60gZ4i$3+*t0}ko6G%9_ou5^`jxF-ue-5u)skg0sa!uf z=L}f~UiVt>#$cn{Ub!)754vt8Os=TKPq(WH^6WFRYLMxkBvUHNiR;E5=nk?jo5`e- z{bZ~7AdBRC8(p_K(gc-foliO9x;kCW$7Z|NUHrH|Sh~K^?e(`?&4<#buUPIwfX{2c@?+2Qh8Z3+4QJQ6i&W$|33d2(<^a zPBQscAu?BT{Gtv zrzNvXAqh3VOL4Xz1>z+^q5yZN!jg`WXV`+99dg%D z)!|S=aCai@OX?4fJ0)-LEji7xov)5bP96LELzplIw52CJk_I7g-kCY+YuC2B?MN@}TnsZC9=pL}`E0mnjE5lMS`k`z1Q5K~^q1ADX=^14~C z*PBxk+F^RK<><+0L?wU1=AxlH$16RJmoR@h<%V`Os7LBa)N7Uwpc=TaWAvZaYt$M| ztn9Z|y zksz-~ULgS0E_oEUj(^c}CR5(WBNY<3jfeDmp4$S(7Rnd1<~2wc3%2W#Y&Yc0RINrf zfMoj*cpJmmzLWMh?RJyxo>gxi+v~hs!1g0vPP0wFcB8U=!RuM-bz-2bEWb=QfWfeQ zK_-Z80@SE3%a(O&$aOTb;&gg0lGA27VQO*uN9?;{oOZ1K-Aztct$On~-R9*2PCw=4 zG^Z!A4@Twm2cp;fSwJ)BK*mJ{gtY^K37co84DaQVqMhDKRI3 zdE9dBS{m0Um)EEF>XpM|5Q)1I}PR}-D zX|=rx)l5PE{?>>)Ik801p zA-GK!GvfJWwhrXF6WcndiRWBy61ap1WF2I!<+MG%+P@I#2b-Cj3g%~jAHn8Li;>-A z^CPQXi@CtZyTr={Y;N#!noU}TFe;m`>)t90mx?YTjv9oXCgp#&xl|r8%1z)6+?pSI zv3%G@aa^(3i1l?{4t-tKdIK}=pTPDWmBrJ7MSmT(yP~_yy7N4th{24kK9C7wo4|*- zC%W@nz)(Cyj`)TGP_n zrBUfV#rCawhoCIlms&4eNmHX_42JA0GC^z;AkI0m)!k<^ttB{`WBp_5MJ{Vy!jlM^ z_ljTl81~MnG{466CzexY{Y+z03Wj36%oI}-co(+}#g<*+X=HW=tP$-K3q1=JwZ_6I zGJ|l^??3q(O{uAkok6hJly}W4-875Swy_?uO52hW@ofxkI~38juX5aC9eYgMig!FR zvE{XGtY@qm&*f5EWIT5wpf-HVw9Et-7|${9+44MxEoDzv=-G-`Z(603bLlRklaF(B z??IiM|6VvtZLAM%DqO9w6ESYvE4~PN7jM*Y+c80{el5S$7Q{>9nYPDk^ed%80(Cs3 z@tVF{qiRhOXX#eHGSP^`X34$_U)d{GkI_Yx**=K%m8GA-@ag33*+^emt6D$9F|0>n zMb^(8m29f7j_403l%3PqcX8CmKFsGTtf?<9lhLhHvHrE$(7*QQh~Iwuox z+IXla$9b%$Z8o%VE6&XrPOiKFIO%X%u> zFBfX;$}eYFE;5()qT8FPSFYR)A5V!j4AXps3JKtcQn|Zk6mqstZYtI%SG}bs8s4+I zwKaVdb4Rr@UI=@y)H;`*TMC9({w*~<(DS@;UOHzj#QNf@w}C}ZWYJn=<-_wXt=g(9 zvz0(|I1~)A`hmt&^ER+1Q{OeCWKAANZmgfJvU5d`WRY9M&OPjq>wRce^mBQ?+BB-2 z>)m~bu`j@}9P53X3&(7K!Hyla2H5`E%x=!WWqiFRn1Lf(or1?`um<=GUQVkRdedc8 zo8gepvNJ3(^Q!btW|=kfTcU++&3q?KpH7c`=ZF`@tJ_;>`_pet!XvyY-|nkW~-3E13YwX4evk3 zI0I>(^X!)6RxHqMZ?K}?P*3BeQLXBOL;70(_+r^*rv8U1;D-9!X$tKU=-@V= zdfgH+$Qxl!%g6c^TOse&DAMp=!#*38_XGL8Tx!P8VtY_9jMMjqRY-u=Fy%7N4kJD7 z&yOQxeUHu1ZmGVdZHT6^)2Kx65BgLqpHkC&ItACzOlvw+NMHdEeVX;1^E%pOb6Ppp z3)u*@a`jDO!*G$WypH)jiG5pUYlBw2P%!MOIc!QbUwO4gkG$^XwQa1AvHH(O)ZD%= zQqS5IAr)6g(mQYIqV@8B-Bo?Z&5)|rK2yt?|7>L4F{fL3PGkLo)%rPV>`YFJte@NG za4P?MYMC|aG0{S{Mpg3|lwrQ|t~kyAKeFsBM67SGdT(0vMV2q5$a~YSC0Fj>{^<9n N)87#0hu_hr{|91>0UQ7T diff --git a/x64_dbg_dbg/lz4/lz4_x86.a b/x64_dbg_dbg/lz4/lz4_x86.a deleted file mode 100644 index b712e2897022de41f9df3b8f11abcc3790e60c2e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 33554 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 diff --git a/x64_dbg_dbg/lz4/lz4_x86.lib b/x64_dbg_dbg/lz4/lz4_x86.lib index aa960265e2a15e38ba4cc777421d7d49a3e5140d..71ab58d03c3aeaaef39b1f4e23238e935d9a14db 100644 GIT binary patch delta 1456 zcmZ`(O>5Lp6n*WqG3`w2v`Lf6WRgk7$$Vtm&N$X~5UWE`5N)M`ZmM7fD^wS?E?g9( ziYuYgj`s&BD7aFTst5%?HtxFU!h)c5p>9PN-6#~_$0T_X3YIABu z-&L*DhH869pspy5+J`QC2O;u0MYxdD1#}9Xho<999R( z=bZYDV<~Vo5%0jv(=QQ1tuUwP@F;PS#grL831_qlAEQ-ADi(XDJI7lhh{SI+pw zHqYX9SWJpuj)%#9E{6(RS&1r)=v59+z=GS$l=2i1FQJie~MDK3-P>$3NL&$IBVkWeR7E<1TGMg6WLm$2O}{=bmTkK2AF7 z-Xl|o25@XIj(yObgFANM5aBE}IfIxZQH}vWTRY)WG1w+j<9?CpwzIr$71j$3Z)ExD z3?^$k%TJaHU?LOISw&E;uS2Z{H2u4zHF*Q-2N2(lASg^Eu1U^Q`33 zQxl&i>FGLmT33SVc0Q=yoF(euay~p0yeb1{l;Eb^25;K_Ri?n@0-N4jg+X5rsp$Fh zwGjA&b<%qwIxXyZOI(4OV$f;RZ_2SS$EF+&?v_M&YDs>6Z}S{C*gSrgmfc{MNKS9| z{*l`d zaBZYk8-}{3HAdfc<@OLFuS?#ISj&laSm^12b;*T-)CDtAb>odR+a`v=cxTZoH6hb_nV6k(EEaFsD6kHSa>FQGjFmAo-lv zzX~i3783Ce%slfPA=C=%Fl#7NKhvhejp;ce80O*<9h z?AokWEG=qadatL)11_omDXr2wsNj4t=uImiI|oCI^A2MSVTMc@tIkNkAewd@h33d& zMi*styM++ro5vK*xkm!Lu5rgdx?#sF8P;VAXN==6T}gqNj1|N-t5WBlW$FP=I_f^4 zQild`Y#)xj-<^kBE_aA%St2?8+57GB zJ0!TjC0EOQORz@j$mep{DSr-5_46F0Pyf%b+0XwBWWMA9RVG{N;XX=uPwz+>I6V;k E3&K)<setFixedWidth(1000); - mGeneralRegs->setFixedHeight(700); + mGeneralRegs->setFixedHeight(1200); QScrollArea* scrollArea = new QScrollArea; scrollArea->setWidget(mGeneralRegs); @@ -41,10 +41,11 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget) scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal{border:1px solid grey;background:#f1f1f1;height:10px}QScrollBar::handle:horizontal{background:#aaa;min-width:20px;margin:1px}QScrollBar::add-line:horizontal,QScrollBar::sub-line:horizontal{width:0;height:0}"); scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical{border:1px solid grey;background:#f1f1f1;width:10px}QScrollBar::handle:vertical{background:#aaa;min-height:20px;margin:1px}QScrollBar::add-line:vertical,QScrollBar::sub-line:vertical{width:0;height:0}"); + /* mRegsTab = new QTabWidget(this); mRegsTab->addTab(scrollArea, "General"); - - ui->mTopRightFrameLayout->addWidget(mRegsTab); + */ + ui->mTopRightFrameLayout->addWidget(scrollArea); mDump = new CPUDump(0); //dump widget ui->mBotLeftFrameLayout->addWidget(mDump); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 17ffddfbb..2fcfa18ba 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -37,43 +37,171 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff // general purposes register (we allow the user to modify the value) mGPR.insert(CAX); + mUINTDISPLAY.insert(CAX); + mLABELDISPLAY.insert(CAX); mGPR.insert(CBX); + mUINTDISPLAY.insert(CBX); + mLABELDISPLAY.insert(CBX); mGPR.insert(CCX); + mUINTDISPLAY.insert(CCX); + mLABELDISPLAY.insert(CCX); mGPR.insert(CDX); + mUINTDISPLAY.insert(CDX); + mLABELDISPLAY.insert(CDX); mGPR.insert(CBP); + mUINTDISPLAY.insert(CBP); + mLABELDISPLAY.insert(CBP); mGPR.insert(CSP); + mUINTDISPLAY.insert(CSP); + mLABELDISPLAY.insert(CSP); mGPR.insert(CSI); + mUINTDISPLAY.insert(CSI); + mLABELDISPLAY.insert(CSI); mGPR.insert(CDI); + mUINTDISPLAY.insert(CDI); + mLABELDISPLAY.insert(CDI); mGPR.insert(R8); + mLABELDISPLAY.insert(R8); + mUINTDISPLAY.insert(R8); mGPR.insert(R9); + mLABELDISPLAY.insert(R9); + mUINTDISPLAY.insert(R9); mGPR.insert(R10); + mUINTDISPLAY.insert(R10); + mLABELDISPLAY.insert(R10); mGPR.insert(R11); + mUINTDISPLAY.insert(R11); + mLABELDISPLAY.insert(R11); mGPR.insert(R12); + mUINTDISPLAY.insert(R12); + mLABELDISPLAY.insert(R12); mGPR.insert(R13); + mUINTDISPLAY.insert(R13); + mLABELDISPLAY.insert(R13); mGPR.insert(R14); + mUINTDISPLAY.insert(R14); + mLABELDISPLAY.insert(R14); mGPR.insert(R15); + mUINTDISPLAY.insert(R15); + mLABELDISPLAY.insert(R15); mGPR.insert(EFLAGS); + mUINTDISPLAY.insert(EFLAGS); // flags (we allow the user to toggle them) mFlags.insert(CF); + mBOOLDISPLAY.insert(CF); mFlags.insert(PF); + mBOOLDISPLAY.insert(PF); mFlags.insert(AF); + mBOOLDISPLAY.insert(AF); mFlags.insert(ZF); + mBOOLDISPLAY.insert(ZF); mFlags.insert(SF); + mBOOLDISPLAY.insert(SF); mFlags.insert(TF); + mBOOLDISPLAY.insert(TF); mFlags.insert(IF); + mBOOLDISPLAY.insert(IF); mFlags.insert(DF); + mBOOLDISPLAY.insert(DF); mFlags.insert(OF); + mBOOLDISPLAY.insert(OF); + + // FPU: XMM, x87 and MMX registers + mDWORDDISPLAY.insert(MxCsr); - // FPU x87 and MMX registers mFPUx87.insert(x87r0); + mFPUx87_80BITSDISPLAY.insert(x87r0); mFPUx87.insert(x87r1); + mFPUx87_80BITSDISPLAY.insert(x87r1); mFPUx87.insert(x87r2); + mFPUx87_80BITSDISPLAY.insert(x87r2); mFPUx87.insert(x87r3); + mFPUx87_80BITSDISPLAY.insert(x87r3); mFPUx87.insert(x87r4); + mFPUx87_80BITSDISPLAY.insert(x87r4); mFPUx87.insert(x87r5); + mFPUx87_80BITSDISPLAY.insert(x87r5); mFPUx87.insert(x87r6); + mFPUx87_80BITSDISPLAY.insert(x87r6); mFPUx87.insert(x87r7); + mFPUx87_80BITSDISPLAY.insert(x87r7); + + mFPUx87.insert(x87TagWord); + mUSHORTDISPLAY.insert(x87TagWord); + mUSHORTDISPLAY.insert(x87StatusWord); + mFPUx87.insert(x87StatusWord); + mFPUx87.insert(x87ControlWord); + mUSHORTDISPLAY.insert(x87ControlWord); + + mFPUx87.insert(x87SW_B); + mBOOLDISPLAY.insert(x87SW_B); + mFPUx87.insert(x87SW_C3); + mBOOLDISPLAY.insert(x87SW_C3); + mFPUx87.insert(x87SW_TOP); + + mFPUx87.insert(x87SW_C2); + mBOOLDISPLAY.insert(x87SW_C2); + mFPUx87.insert(x87SW_C2); + mBOOLDISPLAY.insert(x87SW_C2); + mFPUx87.insert(x87SW_C1); + mBOOLDISPLAY.insert(x87SW_C1); + mFPUx87.insert(x87SW_C0); + mBOOLDISPLAY.insert(x87SW_C0); + mFPUx87.insert(x87SW_IR); + mBOOLDISPLAY.insert(x87SW_IR); + mFPUx87.insert(x87SW_SF); + mBOOLDISPLAY.insert(x87SW_SF); + mFPUx87.insert(x87SW_P); + mBOOLDISPLAY.insert(x87SW_P); + mFPUx87.insert(x87SW_U); + mBOOLDISPLAY.insert(x87SW_U); + mFPUx87.insert(x87SW_O); + mBOOLDISPLAY.insert(x87SW_O); + mFPUx87.insert(x87SW_Z); + mBOOLDISPLAY.insert(x87SW_Z); + mFPUx87.insert(x87SW_D); + mBOOLDISPLAY.insert(x87SW_D); + mFPUx87.insert(x87SW_I); + mBOOLDISPLAY.insert(x87SW_I); + + mFPUx87.insert(x87CW_IC); + mBOOLDISPLAY.insert(x87CW_IC); + mFPUx87.insert(x87CW_RC); + + mFPUx87.insert(x87CW_PC); + + mFPUx87.insert(x87CW_IEM); + mBOOLDISPLAY.insert(x87CW_IEM); + mFPUx87.insert(x87CW_PM); + mBOOLDISPLAY.insert(x87CW_PM); + mFPUx87.insert(x87CW_UM); + mBOOLDISPLAY.insert(x87CW_UM); + mFPUx87.insert(x87CW_OM); + mBOOLDISPLAY.insert(x87CW_OM); + mFPUx87.insert(x87CW_ZM); + mBOOLDISPLAY.insert(x87CW_ZM); + mFPUx87.insert(x87CW_DM); + mBOOLDISPLAY.insert(x87CW_DM); + mFPUx87.insert(x87CW_IM); + mBOOLDISPLAY.insert(x87CW_IM); + + mBOOLDISPLAY.insert(MxCsr_FZ); + mBOOLDISPLAY.insert(MxCsr_PM); + mBOOLDISPLAY.insert(MxCsr_UM); + mBOOLDISPLAY.insert(MxCsr_OM); + mBOOLDISPLAY.insert(MxCsr_ZM); + mBOOLDISPLAY.insert(MxCsr_IM); + mBOOLDISPLAY.insert(MxCsr_DAZ); + mBOOLDISPLAY.insert(MxCsr_PE); + mBOOLDISPLAY.insert(MxCsr_UE); + mBOOLDISPLAY.insert(MxCsr_OE); + mBOOLDISPLAY.insert(MxCsr_ZE); + mBOOLDISPLAY.insert(MxCsr_DE); + mBOOLDISPLAY.insert(MxCsr_IE); + + //MxCsr_RC + mFPUMMX.insert(MM0); mFPUMMX.insert(MM1); mFPUMMX.insert(MM2); @@ -83,20 +211,66 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFPUMMX.insert(MM6); mFPUMMX.insert(MM7); + mFPUXMM.insert(XMM0); + mFPUXMM.insert(XMM1); + mFPUXMM.insert(XMM2); + mFPUXMM.insert(XMM3); + mFPUXMM.insert(XMM4); + mFPUXMM.insert(XMM5); + mFPUXMM.insert(XMM6); + mFPUXMM.insert(XMM7); +#ifdef _WIN64 + mFPUXMM.insert(XMM8); + mFPUXMM.insert(XMM9); + mFPUXMM.insert(XMM10); + mFPUXMM.insert(XMM11); + mFPUXMM.insert(XMM12); + mFPUXMM.insert(XMM13); + mFPUXMM.insert(XMM14); + mFPUXMM.insert(XMM15); +#endif + //registers that should not be changed mNoChange.insert(GS); + mUSHORTDISPLAY.insert(GS); mNoChange.insert(FS); + mUSHORTDISPLAY.insert(FS); mNoChange.insert(ES); + mUSHORTDISPLAY.insert(ES); mNoChange.insert(DS); + mUSHORTDISPLAY.insert(DS); mNoChange.insert(CS); + mUSHORTDISPLAY.insert(CS); mNoChange.insert(SS); + mUSHORTDISPLAY.insert(SS); + mNoChange.insert(DR0); + mUINTDISPLAY.insert(DR0); + mLABELDISPLAY.insert(DR0); + mONLYMODULEANDLABELDISPLAY.insert(DR0); mNoChange.insert(DR1); + mONLYMODULEANDLABELDISPLAY.insert(DR1); + mUINTDISPLAY.insert(DR1); + mLABELDISPLAY.insert(DR2); + mONLYMODULEANDLABELDISPLAY.insert(DR2); mNoChange.insert(DR2); + mUINTDISPLAY.insert(DR2); mNoChange.insert(DR3); + mONLYMODULEANDLABELDISPLAY.insert(DR3); + mLABELDISPLAY.insert(DR3); + mUINTDISPLAY.insert(DR3); mNoChange.insert(DR6); + mLABELDISPLAY.insert(DR6); + mONLYMODULEANDLABELDISPLAY.insert(DR6); + mUINTDISPLAY.insert(DR6); mNoChange.insert(DR7); + mUINTDISPLAY.insert(DR7); + mONLYMODULEANDLABELDISPLAY.insert(DR7); + mLABELDISPLAY.insert(DR7); mNoChange.insert(CIP); + mUINTDISPLAY.insert(CIP); + mLABELDISPLAY.insert(CIP); + mONLYMODULEANDLABELDISPLAY.insert(CIP); // create mapping from internal id to name mRegisterMapping.clear(); @@ -228,39 +402,185 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(x87r7, "x87r7"); mRegisterPlaces.insert(x87r7, Register_Position(offset + 13, 0, 6, 10 * 2)); + offset++; + mRegisterMapping.insert(x87TagWord, "x87TagWord"); + mRegisterPlaces.insert(x87TagWord, Register_Position(offset + 14, 0, 11, sizeof(WORD) * 2)); + + offset++; + mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); + mRegisterPlaces.insert(x87StatusWord, Register_Position(offset + 15, 0, 14, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87SW_B, "x87SW_B"); + mRegisterPlaces.insert(x87SW_B, Register_Position(offset + 16, 0, 9, 1)); + mRegisterMapping.insert(x87SW_C3, "x87SW_C3"); + mRegisterPlaces.insert(x87SW_C3, Register_Position(offset + 16, 12, 10, 1)); + mRegisterMapping.insert(x87SW_C2, "x87SW_C2"); + mRegisterPlaces.insert(x87SW_C2, Register_Position(offset + 16, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_C1, "x87SW_C1"); + mRegisterPlaces.insert(x87SW_C1, Register_Position(offset + 17, 0, 9, 1)); + mRegisterMapping.insert(x87SW_C0, "x87SW_C0"); + mRegisterPlaces.insert(x87SW_C0, Register_Position(offset + 17, 12, 10, 1)); + mRegisterMapping.insert(x87SW_IR, "x87SW_IR"); + mRegisterPlaces.insert(x87SW_IR, Register_Position(offset + 17, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_SF, "x87SW_SF"); + mRegisterPlaces.insert(x87SW_SF, Register_Position(offset + 18, 0, 9, 1)); + mRegisterMapping.insert(x87SW_P, "x87SW_P"); + mRegisterPlaces.insert(x87SW_P, Register_Position(offset + 18, 12, 10, 1)); + mRegisterMapping.insert(x87SW_U, "x87SW_U"); + mRegisterPlaces.insert(x87SW_U, Register_Position(offset + 18, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_O, "x87SW_O"); + mRegisterPlaces.insert(x87SW_O, Register_Position(offset + 19, 0, 9, 1)); + mRegisterMapping.insert(x87SW_Z, "x87SW_Z"); + mRegisterPlaces.insert(x87SW_Z, Register_Position(offset + 19, 12, 10, 1)); + mRegisterMapping.insert(x87SW_D, "x87SW_D"); + mRegisterPlaces.insert(x87SW_D, Register_Position(offset + 19, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_I, "x87SW_I"); + mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); + mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 1)); + + offset++; + + mRegisterMapping.insert(x87ControlWord, "x87ControlWord"); + mRegisterPlaces.insert(x87ControlWord, Register_Position(offset + 21, 0, 15, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87CW_IC, "x87CW_IC"); + mRegisterPlaces.insert(x87CW_IC, Register_Position(offset + 22, 0, 9, 1)); + mRegisterMapping.insert(x87CW_IEM, "x87CW_IEM"); + mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset + 22, 12, 10, 1)); + mRegisterMapping.insert(x87CW_PM, "x87CW_PM"); + mRegisterPlaces.insert(x87CW_PM, Register_Position(offset + 22, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_UM, "x87CW_UM"); + mRegisterPlaces.insert(x87CW_UM, Register_Position(offset + 23, 0, 9, 1)); + mRegisterMapping.insert(x87CW_OM, "x87CW_OM"); + mRegisterPlaces.insert(x87CW_OM, Register_Position(offset + 23, 12, 10, 1)); + mRegisterMapping.insert(x87CW_ZM, "x87CW_ZM"); + mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset + 23, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_DM, "x87CW_DM"); + mRegisterPlaces.insert(x87CW_DM, Register_Position(offset + 24, 0, 9, 1)); + mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); + mRegisterPlaces.insert(x87CW_IM, Register_Position(offset + 24, 12, 10, 1)); + mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); + mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); + mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 1)); + + offset++; + + mRegisterMapping.insert(MxCsr, "MxCsr"); + mRegisterPlaces.insert(MxCsr, Register_Position(offset + 26, 0, 6, sizeof(DWORD) * 2)); + + mRegisterMapping.insert(MxCsr_FZ, "MxCsr_FZ"); + mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset + 27, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_PM, "MxCsr_PM"); + mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset + 27, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_UM, "MxCsr_UM"); + mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset + 27, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_OM, "MxCsr_OM"); + mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset + 28, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_ZM, "MxCsr_ZM"); + mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset + 28, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_IM, "MxCsr_IM"); + mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset + 28, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_UE, "MxCsr_UE"); + mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset + 29, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_PE, "MxCsr_PE"); + mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset + 29, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_DAZ, "MxCsr_DAZ"); + mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset + 29, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_OE, "MxCsr_OE"); + mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset + 30, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_ZE, "MxCsr_ZE"); + mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset + 30, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_DE, "MxCsr_DE"); + mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset + 30, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); + mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset + 31, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 12, 10, 1)); + offset++; mRegisterMapping.insert(MM0, "MM0"); - mRegisterPlaces.insert(MM0, Register_Position(offset + 14, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM0, Register_Position(offset + 32, 0, 4, 8 * 2)); mRegisterMapping.insert(MM1, "MM1"); - mRegisterPlaces.insert(MM1, Register_Position(offset + 15, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM1, Register_Position(offset + 33, 0, 4, 8 * 2)); mRegisterMapping.insert(MM2, "MM2"); - mRegisterPlaces.insert(MM2, Register_Position(offset + 16, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM2, Register_Position(offset + 34, 0, 4, 8 * 2)); mRegisterMapping.insert(MM3, "MM3"); - mRegisterPlaces.insert(MM3, Register_Position(offset + 17, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM3, Register_Position(offset + 35, 0, 4, 8 * 2)); mRegisterMapping.insert(MM4, "MM4"); - mRegisterPlaces.insert(MM4, Register_Position(offset + 18, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM4, Register_Position(offset + 36, 0, 4, 8 * 2)); mRegisterMapping.insert(MM5, "MM5"); - mRegisterPlaces.insert(MM5, Register_Position(offset + 19, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM5, Register_Position(offset + 37, 0, 4, 8 * 2)); mRegisterMapping.insert(MM6, "MM6"); - mRegisterPlaces.insert(MM6, Register_Position(offset + 20, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM6, Register_Position(offset + 38, 0, 4, 8 * 2)); mRegisterMapping.insert(MM7, "MM7"); - mRegisterPlaces.insert(MM7, Register_Position(offset + 21, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM7, Register_Position(offset + 39, 0, 4, 8 * 2)); offset++; mRegisterMapping.insert(DR0, "DR0"); - mRegisterPlaces.insert(DR0, Register_Position(offset + 22, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR0, Register_Position(offset + 40, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR1, "DR1"); - mRegisterPlaces.insert(DR1, Register_Position(offset + 23, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR1, Register_Position(offset + 41, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR2, "DR2"); - mRegisterPlaces.insert(DR2, Register_Position(offset + 24, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR2, Register_Position(offset + 42, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR3, "DR3"); - mRegisterPlaces.insert(DR3, Register_Position(offset + 25, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR3, Register_Position(offset + 43, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR6, "DR6"); - mRegisterPlaces.insert(DR6, Register_Position(offset + 26, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR6, Register_Position(offset + 44, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR7, "DR7"); - mRegisterPlaces.insert(DR7, Register_Position(offset + 27, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR7, Register_Position(offset + 45, 0, 4, sizeof(uint_t) * 2)); + + offset++; + + mRegisterMapping.insert(XMM0, "XMM0"); + mRegisterPlaces.insert(XMM0, Register_Position(offset + 46, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM1, "XMM1"); + mRegisterPlaces.insert(XMM1, Register_Position(offset + 47, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM2, "XMM2"); + mRegisterPlaces.insert(XMM2, Register_Position(offset + 48, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM3, "XMM3"); + mRegisterPlaces.insert(XMM3, Register_Position(offset + 49, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM4, "XMM4"); + mRegisterPlaces.insert(XMM4, Register_Position(offset + 50, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM5, "XMM5"); + mRegisterPlaces.insert(XMM5, Register_Position(offset + 51, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM6, "XMM6"); + mRegisterPlaces.insert(XMM6, Register_Position(offset + 52, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM7, "XMM7"); + mRegisterPlaces.insert(XMM7, Register_Position(offset + 53, 0, 6, 16 * 2)); + +#ifdef _WIN64 + mRegisterMapping.insert(XMM8, "XMM8"); + mRegisterPlaces.insert(XMM8, Register_Position(offset + 54, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM9, "XMM9"); + mRegisterPlaces.insert(XMM9, Register_Position(offset + 55, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM10, "XMM10"); + mRegisterPlaces.insert(XMM10, Register_Position(offset + 56, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM11, "XMM11"); + mRegisterPlaces.insert(XMM11, Register_Position(offset + 57, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM12, "XMM12"); + mRegisterPlaces.insert(XMM12, Register_Position(offset + 58, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM13, "XMM13"); + mRegisterPlaces.insert(XMM13, Register_Position(offset + 59, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM14, "XMM14"); + mRegisterPlaces.insert(XMM14, Register_Position(offset + 60, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM15, "XMM15"); + mRegisterPlaces.insert(XMM15, Register_Position(offset + 61, 0, 6, 16 * 2)); +#endif fontsUpdatedSlot(); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); @@ -445,11 +765,11 @@ QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) bool hasLabel = DbgGetLabelAt(register_value, SEG_DEFAULT, label_text); bool hasModule = DbgGetModuleAt(register_value, module_text); - if(hasString && register_selected != CIP) + if(hasString && !mONLYMODULEANDLABELDISPLAY.contains(register_selected)) { newText = string_text; } - else if(hasLabel && hasModule && register_selected != CIP) + else if(hasLabel && hasModule) { newText = "<" + QString(module_text) + "." + QString(label_text) + ">"; } @@ -457,11 +777,11 @@ QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) { newText = QString(module_text) + "." + valueText; } - else if(hasLabel && register_selected != CIP) + else if(hasLabel) { newText = "<" + QString(label_text) + ">"; } - else if(register_selected != CIP) + else if(!mONLYMODULEANDLABELDISPLAY.contains(register_selected)) { bool isCharacter = false; if(register_value == (register_value & 0xFF)) @@ -558,60 +878,6 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) // is the register-id known? if(mRegisterMapping.contains(reg)) { - uint_t nouint_value; - bool enable_label_detection = false; - switch(reg) - { - case CAX: - case CCX: - case CDX: - case CBX: - case CDI: - case CBP: - case CSI: - case CSP: - case R8: - case R9: - case R10: - case R11: - case R12: - case R13: - case R14: - case R15: - case CIP: - case DR0: - case DR1: - case DR2: - case DR3: - case DR6: - case DR7: - enable_label_detection = true; - break; - - case CF: - case PF: - case AF: - case ZF: - case SF: - case TF: - case IF: - case DF: - case OF: - nouint_value = * ((bool*) value); - value = (char*) & nouint_value; - break; - - case GS: - case FS: - case ES: - case DS: - case CS: - case SS: - nouint_value = * ((unsigned short*) value); - value = (char*) & nouint_value; - break; - } - // padding to the left is at least one character (looks better) int x = mCharWidth * (1 + mRegisterPlaces[reg].start); int ySpace = yTopSpacing; @@ -649,44 +915,70 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) QString valueText; // draw value - if(mFPUx87.contains(reg) || mFPUMMX.contains(reg)) - { - SIZE_T size; - if(mFPUx87.contains(reg)) - size = 10; - else - size = 8; - valueText = QString(QByteArray(value, size).toHex()).toUpper(); - } - else + if(mUINTDISPLAY.contains(reg)) valueText = QString("%1").arg((* ((uint_t*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - + else if(mUSHORTDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((unsigned short*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mDWORDDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((DWORD*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mBOOLDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((bool*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else + { + SIZE_T size = GetSizeRegister(reg); + if(size != 0) + valueText = QString(QByteArray(value, size).toHex()).toUpper(); + else + valueText = QString("???"); + } width = mCharWidth * valueText.length(); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText); //p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper()); x += valueText.length() * mCharWidth; - if((mFPUx87.contains(reg) || mFPUMMX.contains(reg)) && DbgIsDebugging()) + if(mFPUx87_80BITSDISPLAY.contains(reg) && DbgIsDebugging()) { x += 1 * mCharWidth; //1 space QString newText; - if(mFPUx87.contains(reg)) + newText = QString("ST%1 ").arg(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->st_value); + +#define X87FPU_TAGWORD_NONZERO 0 +#define X87FPU_TAGWORD_ZERO 1 +#define X87FPU_TAGWORD_SPECIAL 2 +#define X87FPU_TAGWORD_EMPTY 3 + + switch(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->tag) { - newText = QString("ST%1 ").arg(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->st_value); - newText += QString::number(readFloat80(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); - } - else - { - newText = QString::number(* (double*)(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); + case X87FPU_TAGWORD_NONZERO: + newText += QString("nonzero "); + break; + + case X87FPU_TAGWORD_ZERO: + newText += QString("zero "); + break; + + case X87FPU_TAGWORD_SPECIAL: + newText += QString("special "); + break; + + case X87FPU_TAGWORD_EMPTY: + newText += QString("empty "); + break; + + default: + newText += QString("unkown "); + break; } + + newText += QString::number(readFloat80(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); width = newText.length() * mCharWidth; p->setPen(ConfigColor("RegistersExtraInfoColor")); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); } // do we have a label ? - if(enable_label_detection) + if(mLABELDISPLAY.contains(reg)) { x += 5 * mCharWidth; //5 spaces @@ -819,7 +1111,7 @@ void RegistersView::onCopyToClipboardAction() void RegistersView::onCopySymbolToClipboardAction() { - if(mGPR.contains(mSelected)) + if(mLABELDISPLAY.contains(mSelected)) { QClipboard* clipboard = QApplication::clipboard(); QString symbol = getRegisterLabel(mSelected); @@ -952,41 +1244,47 @@ void RegistersView::repaint() this->viewport()->repaint(); } - -uint_t RegistersView::GetUintValue(REGISTER_NAME reg, char* value) +SIZE_T RegistersView::GetSizeRegister(const REGISTER_NAME reg_name) { - switch(reg) - { - case CF: - case PF: - case AF: - case ZF: - case SF: - case TF: - case IF: - case DF: - case OF: - return (uint_t) * ((bool*) value); - break; + SIZE_T size; - case GS: - case FS: - case ES: - case DS: - case CS: - case SS: - return (uint_t) * ((unsigned short*) value); - break; - } + if(mUINTDISPLAY.contains(reg_name)) + size = sizeof(uint_t); + else if(mUSHORTDISPLAY.contains(reg_name)) + size = sizeof(unsigned short); + else if(mDWORDDISPLAY.contains(reg_name)) + size = sizeof(DWORD); + else if(mBOOLDISPLAY.contains(reg_name)) + size = sizeof(bool); + else if(mFPUx87_80BITSDISPLAY.contains(reg_name)) + size = 10; + else if(mFPUMMX.contains(reg_name)) + size = 8; + else if(mFPUXMM.contains(reg_name)) + size = 16; + else + size = 0; - return * ((uint_t*) value); + return size; +} + +int RegistersView::CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2) +{ + SIZE_T size = GetSizeRegister(reg_name); + char* reg1_data = registerValue(regdump1, reg_name); + char* reg2_data = registerValue(regdump2, reg_name); + + if(size != 0) + return memcmp(reg1_data, reg2_data, size); + + return -1; } char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) { static int null_value = 0; // this is probably the most efficient general method to access the values of the struct - + // TODO: or maybe we can add an array with something like: return array[reg].data, this is more fast :-) if(reg == CAX) return (char*) & (regd->titcontext.cax); if(reg == CBX) return (char*) & (regd->titcontext.cbx); if(reg == CCX) return (char*) & (regd->titcontext.ccx); @@ -1034,23 +1332,46 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == DR6) return (char*) & (regd->titcontext.dr6); if(reg == DR7) return (char*) & (regd->titcontext.dr7); - if(reg == MM0) return (char*) & (regd->titcontext.mmx[0]); - if(reg == MM1) return (char*) & (regd->titcontext.mmx[1]); - if(reg == MM2) return (char*) & (regd->titcontext.mmx[2]); - if(reg == MM3) return (char*) & (regd->titcontext.mmx[3]); - if(reg == MM4) return (char*) & (regd->titcontext.mmx[4]); - if(reg == MM5) return (char*) & (regd->titcontext.mmx[5]); - if(reg == MM6) return (char*) & (regd->titcontext.mmx[6]); - if(reg == MM7) return (char*) & (regd->titcontext.mmx[7]); + if(reg == MM0) return (char*) & (regd->mmx[0]); + if(reg == MM1) return (char*) & (regd->mmx[1]); + if(reg == MM2) return (char*) & (regd->mmx[2]); + if(reg == MM3) return (char*) & (regd->mmx[3]); + if(reg == MM4) return (char*) & (regd->mmx[4]); + if(reg == MM5) return (char*) & (regd->mmx[5]); + if(reg == MM6) return (char*) & (regd->mmx[6]); + if(reg == MM7) return (char*) & (regd->mmx[7]); - if(reg == x87r0) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[0]); - if(reg == x87r1) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[1]); - if(reg == x87r2) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[2]); - if(reg == x87r3) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[3]); - if(reg == x87r4) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[4]); - if(reg == x87r5) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[5]); - if(reg == x87r6) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[6]); - if(reg == x87r7) return (char*) & (regd->titcontext.x87fpu.x87FPURegister[7]); + if(reg == x87r0) return (char*) & (regd->x87FPURegisters[0]); + if(reg == x87r1) return (char*) & (regd->x87FPURegisters[1]); + if(reg == x87r2) return (char*) & (regd->x87FPURegisters[2]); + if(reg == x87r3) return (char*) & (regd->x87FPURegisters[3]); + if(reg == x87r4) return (char*) & (regd->x87FPURegisters[4]); + if(reg == x87r5) return (char*) & (regd->x87FPURegisters[5]); + if(reg == x87r6) return (char*) & (regd->x87FPURegisters[6]); + if(reg == x87r7) return (char*) & (regd->x87FPURegisters[7]); + + if(reg == x87ControlWord) return (char*) & (regd->titcontext.x87fpu.ControlWord); + if(reg == x87StatusWord) return (char*) & (regd->titcontext.x87fpu.StatusWord); + if(reg == x87TagWord) return (char*) & (regd->titcontext.x87fpu.TagWord); + + if(reg == MxCsr) return (char*) & (regd->titcontext.MxCsr); + + if(reg == XMM0) return (char*) & (regd->titcontext.XmmRegisters[0]); + if(reg == XMM1) return (char*) & (regd->titcontext.XmmRegisters[1]); + if(reg == XMM2) return (char*) & (regd->titcontext.XmmRegisters[2]); + if(reg == XMM3) return (char*) & (regd->titcontext.XmmRegisters[3]); + if(reg == XMM4) return (char*) & (regd->titcontext.XmmRegisters[4]); + if(reg == XMM5) return (char*) & (regd->titcontext.XmmRegisters[5]); + if(reg == XMM6) return (char*) & (regd->titcontext.XmmRegisters[6]); + if(reg == XMM7) return (char*) & (regd->titcontext.XmmRegisters[7]); + if(reg == XMM8) return (char*) & (regd->titcontext.XmmRegisters[8]); + if(reg == XMM9) return (char*) & (regd->titcontext.XmmRegisters[9]); + if(reg == XMM10) return (char*) & (regd->titcontext.XmmRegisters[10]); + if(reg == XMM11) return (char*) & (regd->titcontext.XmmRegisters[11]); + if(reg == XMM12) return (char*) & (regd->titcontext.XmmRegisters[12]); + if(reg == XMM13) return (char*) & (regd->titcontext.XmmRegisters[13]); + if(reg == XMM14) return (char*) & (regd->titcontext.XmmRegisters[14]); + if(reg == XMM15) return (char*) & (regd->titcontext.XmmRegisters[15]); return (char*) & null_value; } @@ -1069,9 +1390,7 @@ void RegistersView::setRegisters(REGDUMP* reg) // iterate all ids (CAX, CBX, ...) while(it != mRegisterMapping.end()) { - uint_t old_value = GetUintValue((REGISTER_NAME) it.key(), registerValue(reg, it.key())); - uint_t new_value = GetUintValue((REGISTER_NAME) it.key(), registerValue(&wCipRegDumpStruct, it.key())); - if(old_value != new_value) + if(CompareRegisters(it.key(), reg, &wCipRegDumpStruct) != 0) mRegisterUpdates.insert(it.key()); else if(mRegisterUpdates.contains(it.key())) //registers are equal mRegisterUpdates.remove(it.key()); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 469b07714..77bfce265 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -27,8 +27,24 @@ public: EFLAGS, CF, PF, AF, ZF, SF, TF, IF, DF, OF, GS, FS, ES, DS, CS, SS, DR0, DR1, DR2, DR3, DR6, DR7, + // x87 stuff x87r0, x87r1, x87r2, x87r3, x87r4, x87r5, x87r6, x87r7, + x87TagWord, x87ControlWord, x87StatusWord, + // x87 Status Word fields + x87SW_B, x87SW_C3, x87SW_TOP, x87SW_C2, x87SW_C1, x87SW_O, + x87SW_IR, x87SW_SF, x87SW_P, x87SW_U, x87SW_Z, + x87SW_D, x87SW_I, x87SW_C0, + // x87 Control Word fields + x87CW_IC, x87CW_RC, x87CW_PC, x87CW_IEM, x87CW_PM, + x87CW_UM, x87CW_OM, x87CW_ZM, x87CW_DM, x87CW_IM, + //MxCsr + MxCsr, MxCsr_FZ, MxCsr_PM, MxCsr_UM, MxCsr_OM, MxCsr_ZM, + MxCsr_IM, MxCsr_DAZ, MxCsr_PE, MxCsr_UE, MxCsr_OE, + MxCsr_ZE, MxCsr_DE, MxCsr_IE, MxCsr_RC, + // MMX and XMM MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, + XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, + XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, UNKNOWN }; @@ -101,21 +117,29 @@ protected slots: void onFollowInDump(); void onFollowInStack(); QString getRegisterLabel(REGISTER_NAME); - uint_t GetUintValue(REGISTER_NAME, char*); - + int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2); + SIZE_T GetSizeRegister(const REGISTER_NAME reg_name); private: int mVScrollOffset; int mRowsNeeded; int yTopSpacing; + QSet mUINTDISPLAY; + QSet mUSHORTDISPLAY; + QSet mDWORDDISPLAY; + QSet mBOOLDISPLAY; + QSet mLABELDISPLAY; + QSet mONLYMODULEANDLABELDISPLAY; + QSet mFPUx87_80BITSDISPLAY; // holds current selected register REGISTER_NAME mSelected; // general purposes register id s (cax, ..., r8, ....) QSet mGPR; // all flags QSet mFlags; - // FPU x87 and MMX registers + // FPU x87, XMM and MMX registers QSet mFPUx87; QSet mFPUMMX; + QSet mFPUXMM; // contains all id's of registers if there occurs a change QSet mRegisterUpdates; // registers that do not allow changes From c7719cd8e172e2fa324f6e3524501b0f06a77096 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 25 Oct 2014 12:12:51 +0200 Subject: [PATCH 05/58] fix in memory leaks text --- x64_dbg_dbg/x64_dbg.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 196425944..36132121d 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -300,7 +300,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal() if(memleaks()) { char msg[256] = ""; - sprintf(msg, "%d memory leak(s) found!\n\nPlease send contact the authors of x64_dbg.", memleaks()); + sprintf(msg, "%d memory leak(s) found!\n\nPlease contact the authors of x64_dbg.", memleaks()); MessageBoxA(0, msg, "error", MB_ICONERROR | MB_SYSTEMMODAL); } else From 7a283696d34760b0bc910f83c5c46ebaca798661 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 25 Oct 2014 12:43:55 +0200 Subject: [PATCH 06/58] DBG: updated debugger version --- x64_dbg_bridge/bridgemain.h | 2 +- x64_dbg_exe/resource.rc | 13 ++++++------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 283d64f53..e42f5cfac 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -37,7 +37,7 @@ extern "C" //Bridge defines #define MAX_SETTING_SIZE 65536 -#define DBG_VERSION 22 +#define DBG_VERSION 23 //Bridge functions BRIDGE_IMPEXP const char* BridgeInit(); diff --git a/x64_dbg_exe/resource.rc b/x64_dbg_exe/resource.rc index 19ad3428b..f95d41395 100644 --- a/x64_dbg_exe/resource.rc +++ b/x64_dbg_exe/resource.rc @@ -17,6 +17,7 @@ #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU) LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US +#pragma code_page(1252) #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// @@ -55,12 +56,10 @@ IDI_ICON1 ICON "..\\bug.ico" ///////////////////////////////////////////////////////////////////////////// // -// Manifest +// RT_MANIFEST // -// Icon with lowest ID value placed first to ensure application icon -// remains consistent on all systems. -1 RT_MANIFEST ".\\manifest.xml" +1 RT_MANIFEST ".\\manifest.xml" ///////////////////////////////////////////////////////////////////////////// // @@ -68,8 +67,8 @@ IDI_ICON1 ICON "..\\bug.ico" // VS_VERSION_INFO VERSIONINFO - FILEVERSION 0,0,2,2 - PRODUCTVERSION 0,0,2,2 + FILEVERSION 0,0,2,3 + PRODUCTVERSION 0,0,2,3 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L @@ -85,7 +84,7 @@ BEGIN BLOCK "040904b0" BEGIN VALUE "FileDescription", "x64_dbg" - VALUE "FileVersion", "0.0.2.2" + VALUE "FileVersion", "0.0.2.3" VALUE "LegalCopyright", "x64dbg.com" VALUE "ProductName", "x64_dbg" VALUE "ProductVersion", "V2.2ALPHA" From 0705384dbecbd76724525dc834268b288682c594 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 26 Oct 2014 02:24:57 +0200 Subject: [PATCH 07/58] last fpu changes --- x64_dbg_bridge/bridgemain.h | 59 +++ x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 105896 bytes x64_dbg_dbg/_exports.cpp | 35 ++ x64_dbg_dbg/value.cpp | 54 +++ x64_dbg_dbg/value.h | 1 + x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 389 +++++++++++++++--- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 7 +- 7 files changed, 483 insertions(+), 62 deletions(-) diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 9ffafc22c..b08916d95 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -368,12 +368,71 @@ typedef struct bool o; } FLAGS; +typedef struct +{ + bool FZ; + bool PM; + bool UM; + bool OM; + bool ZM; + bool IM; + bool DM; + bool DAZ; + bool PE; + bool UE; + bool OE; + bool ZE; + bool DE; + bool IE; + + unsigned short RC; +} MxCsr_FIELDS_t; + +typedef struct +{ + bool B; + bool C3; + bool C2; + bool C1; + bool C0; + bool IR; + bool SF; + bool P; + bool U; + bool O; + bool Z; + bool D; + bool I; + + unsigned short TOP; + +} x87StatusWord_FIELDS_t; + +typedef struct +{ + bool IC; + bool IEM; + bool PM; + bool UM; + bool OM; + bool ZM; + bool DM; + bool IM; + + unsigned short RC; + unsigned short PC; + +} x87ControlWord_FIELDS_t; + typedef struct { TITAN_ENGINE_CONTEXT_t titcontext; FLAGS flags; x87FPURegister_t x87FPURegisters[8]; uint64_t mmx[8]; + MxCsr_FIELDS_t MxCsrFields; + x87StatusWord_FIELDS_t x87StatusWordFields; + x87ControlWord_FIELDS_t x87ControlWordFields; } REGDUMP; typedef struct diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index cdbace174e9bd4e51ba9ea6de1c01c665685aa36..fefa7bf57a494e50c677d2d07c9ef01be5679094 100644 GIT binary patch delta 10781 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 delta 10781 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 diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index a0d864dab..3d45cb339 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -332,6 +332,37 @@ extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr) return cacheResult; } +void GetMxCsrFields(MxCsr_FIELDS_t* MxCsrFields, DWORD MxCsr) +{ + MxCsrFields->DAZ = valmxcsrflagfromstring(MxCsr, "DAZ"); + MxCsrFields->DE = valmxcsrflagfromstring(MxCsr, "DE"); + MxCsrFields->FZ = valmxcsrflagfromstring(MxCsr, "FZ"); + MxCsrFields->IE = valmxcsrflagfromstring(MxCsr, "IE"); + MxCsrFields->IM = valmxcsrflagfromstring(MxCsr, "IM"); + MxCsrFields->DM = valmxcsrflagfromstring(MxCsr, "DM"); + MxCsrFields->OE = valmxcsrflagfromstring(MxCsr, "OE"); + MxCsrFields->OM = valmxcsrflagfromstring(MxCsr, "OM"); + MxCsrFields->PE = valmxcsrflagfromstring(MxCsr, "PE"); + MxCsrFields->PM = valmxcsrflagfromstring(MxCsr, "PM"); + MxCsrFields->UE = valmxcsrflagfromstring(MxCsr, "UE"); + MxCsrFields->UM = valmxcsrflagfromstring(MxCsr, "UM"); + MxCsrFields->ZE = valmxcsrflagfromstring(MxCsr, "ZE"); + MxCsrFields->ZM = valmxcsrflagfromstring(MxCsr, "ZM"); + + //MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC") +} + +void Getx87ControlWordFields(x87ControlWord_FIELDS_t* x87ControlWordFields, WORD ControlWord) +{ + +} + +void Getx87StatusWordFields(x87StatusWord_FIELDS_t* x87StatusWordFields, WORD StatusWord) +{ + + +} + extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) { if(!DbgIsDebugging()) @@ -356,6 +387,10 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) Getx87FPURegisters(regdump->x87FPURegisters, & (regdump->titcontext)); GetMMXRegisters(regdump->mmx, & (regdump->titcontext)); + GetMxCsrFields(& (regdump->MxCsrFields), regdump->titcontext.MxCsr); + Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->titcontext.x87fpu.ControlWord); + Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->titcontext.x87fpu.StatusWord); + return true; } diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index 89e2e9bda..8292eaf21 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -257,6 +257,60 @@ static bool isregister(const char* string) return false; } +#define MXCSRFLAG_IE 0x1 +#define MXCSRFLAG_DE 0x4 +#define MXCSRFLAG_ZE 0x8 +#define MXCSRFLAG_OE 0x10 +#define MXCSRFLAG_UE 0x20 +#define MXCSRFLAG_PE 0x40 +#define MXCSRFLAG_DAZ 0x80 +#define MXCSRFLAG_IM 0x100 +#define MXCSRFLAG_DM 0x200 +#define MXCSRFLAG_ZM 0x400 +#define MXCSRFLAG_OM 0x800 +#define MXCSRFLAG_UM 0x1000 +#define MXCSRFLAG_PM 0x2000 +#define MXCSRFLAG_FZ 0x4000 + +typedef struct +{ + char* name; + uint flag; + +} FLAG_NAME_VALUE_TABLE_t; + +#define MXCSR_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, MXCSRFLAG_##flag_name } + +bool valmxcsrflagfromstring(uint mxcsrflags, const char* string) +{ + static FLAG_NAME_VALUE_TABLE_t mxcsrnameflagtable[] = + { + MXCSR_NAME_FLAG_TABLE_ENTRY(IE), + MXCSR_NAME_FLAG_TABLE_ENTRY(DE), + MXCSR_NAME_FLAG_TABLE_ENTRY(ZE), + MXCSR_NAME_FLAG_TABLE_ENTRY(OE), + MXCSR_NAME_FLAG_TABLE_ENTRY(UE), + MXCSR_NAME_FLAG_TABLE_ENTRY(PE), + MXCSR_NAME_FLAG_TABLE_ENTRY(DAZ), + MXCSR_NAME_FLAG_TABLE_ENTRY(IM), + MXCSR_NAME_FLAG_TABLE_ENTRY(DM), + MXCSR_NAME_FLAG_TABLE_ENTRY(ZM), + MXCSR_NAME_FLAG_TABLE_ENTRY(OM), + MXCSR_NAME_FLAG_TABLE_ENTRY(UM), + MXCSR_NAME_FLAG_TABLE_ENTRY(PM), + MXCSR_NAME_FLAG_TABLE_ENTRY(FZ) + }; + int i; + + for(i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++) + { + if(scmp(string, mxcsrnameflagtable[i].name)) + return (bool)((int)(mxcsrflags & mxcsrnameflagtable[i].flag) != 0); + } + + return false; +} + bool valflagfromstring(uint eflags, const char* string) { if(scmp(string, "cf")) diff --git a/x64_dbg_dbg/value.h b/x64_dbg_dbg/value.h index 1dc282df7..9dceafeb4 100644 --- a/x64_dbg_dbg/value.h +++ b/x64_dbg_dbg/value.h @@ -13,5 +13,6 @@ bool valfromstring(const char* string, uint* value, bool silent); bool valfromstring(const char* string, uint* value); bool valflagfromstring(uint eflags, const char* string); bool valtostring(const char* string, uint* value, bool silent); +bool valmxcsrflagfromstring(uint mxcsrflags, const char* string); #endif // _VALUE_H diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 2fcfa18ba..d8ad18017 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -37,167 +37,349 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff // general purposes register (we allow the user to modify the value) mGPR.insert(CAX); + mCANSTOREADDRESS.insert(CAX); mUINTDISPLAY.insert(CAX); mLABELDISPLAY.insert(CAX); + mMODIFYDISPLAY.insert(CAX); + mINCREMENTDECREMET.insert(CAX); + mSETONEZEROTOGGLE.insert(CAX); + + mSETONEZEROTOGGLE.insert(CBX); + mINCREMENTDECREMET.insert(CBX); mGPR.insert(CBX); mUINTDISPLAY.insert(CBX); mLABELDISPLAY.insert(CBX); + mMODIFYDISPLAY.insert(CBX); + mCANSTOREADDRESS.insert(CBX); + + mSETONEZEROTOGGLE.insert(CCX); + mINCREMENTDECREMET.insert(CCX); mGPR.insert(CCX); mUINTDISPLAY.insert(CCX); mLABELDISPLAY.insert(CCX); + mMODIFYDISPLAY.insert(CCX); + mCANSTOREADDRESS.insert(CCX); + + mSETONEZEROTOGGLE.insert(CDX); + mINCREMENTDECREMET.insert(CDX); mGPR.insert(CDX); mUINTDISPLAY.insert(CDX); mLABELDISPLAY.insert(CDX); + mMODIFYDISPLAY.insert(CDX); + mCANSTOREADDRESS.insert(CCX); + + mSETONEZEROTOGGLE.insert(CBP); + mINCREMENTDECREMET.insert(CBP); + mCANSTOREADDRESS.insert(CBP); mGPR.insert(CBP); mUINTDISPLAY.insert(CBP); mLABELDISPLAY.insert(CBP); + mMODIFYDISPLAY.insert(CBP); + + mSETONEZEROTOGGLE.insert(CSP); + mINCREMENTDECREMET.insert(CSP); + mCANSTOREADDRESS.insert(CSP); mGPR.insert(CSP); mUINTDISPLAY.insert(CSP); mLABELDISPLAY.insert(CSP); + mMODIFYDISPLAY.insert(CSP); + + mSETONEZEROTOGGLE.insert(CSI); + mINCREMENTDECREMET.insert(CSI); + mCANSTOREADDRESS.insert(CSI); mGPR.insert(CSI); mUINTDISPLAY.insert(CSI); mLABELDISPLAY.insert(CSI); + mMODIFYDISPLAY.insert(CSI); + + mSETONEZEROTOGGLE.insert(CDI); + mINCREMENTDECREMET.insert(CDI); + mCANSTOREADDRESS.insert(CDI); mGPR.insert(CDI); mUINTDISPLAY.insert(CDI); mLABELDISPLAY.insert(CDI); + mMODIFYDISPLAY.insert(CDI); + + mSETONEZEROTOGGLE.insert(R8); + mINCREMENTDECREMET.insert(R8); + mCANSTOREADDRESS.insert(R8); mGPR.insert(R8); mLABELDISPLAY.insert(R8); mUINTDISPLAY.insert(R8); + mMODIFYDISPLAY.insert(R8); + + mSETONEZEROTOGGLE.insert(R9); + mINCREMENTDECREMET.insert(R9); + mCANSTOREADDRESS.insert(R9); mGPR.insert(R9); mLABELDISPLAY.insert(R9); mUINTDISPLAY.insert(R9); + mMODIFYDISPLAY.insert(R9); + + mSETONEZEROTOGGLE.insert(R10); + mINCREMENTDECREMET.insert(R10); + mCANSTOREADDRESS.insert(R10); mGPR.insert(R10); + mMODIFYDISPLAY.insert(R10); mUINTDISPLAY.insert(R10); mLABELDISPLAY.insert(R10); + + mSETONEZEROTOGGLE.insert(R11); + mINCREMENTDECREMET.insert(R11); + mCANSTOREADDRESS.insert(R11); mGPR.insert(R11); + mMODIFYDISPLAY.insert(R11); mUINTDISPLAY.insert(R11); mLABELDISPLAY.insert(R11); + + mSETONEZEROTOGGLE.insert(R12); + mINCREMENTDECREMET.insert(R12); + mCANSTOREADDRESS.insert(R12); mGPR.insert(R12); + mMODIFYDISPLAY.insert(R12); mUINTDISPLAY.insert(R12); mLABELDISPLAY.insert(R12); + + mSETONEZEROTOGGLE.insert(R13); + mINCREMENTDECREMET.insert(R13); + mCANSTOREADDRESS.insert(R13); mGPR.insert(R13); + mMODIFYDISPLAY.insert(R13); mUINTDISPLAY.insert(R13); mLABELDISPLAY.insert(R13); + + mSETONEZEROTOGGLE.insert(R14); + mINCREMENTDECREMET.insert(R14); + mCANSTOREADDRESS.insert(R14); mGPR.insert(R14); + mMODIFYDISPLAY.insert(R14); mUINTDISPLAY.insert(R14); mLABELDISPLAY.insert(R14); + + mSETONEZEROTOGGLE.insert(R15); + mINCREMENTDECREMET.insert(R15); + mCANSTOREADDRESS.insert(R15); mGPR.insert(R15); + mMODIFYDISPLAY.insert(R15); mUINTDISPLAY.insert(R15); mLABELDISPLAY.insert(R15); + + mSETONEZEROTOGGLE.insert(EFLAGS); + mINCREMENTDECREMET.insert(EFLAGS); mGPR.insert(EFLAGS); + mMODIFYDISPLAY.insert(EFLAGS); mUINTDISPLAY.insert(EFLAGS); // flags (we allow the user to toggle them) mFlags.insert(CF); mBOOLDISPLAY.insert(CF); + mSETONEZEROTOGGLE.insert(CF); + + mSETONEZEROTOGGLE.insert(PF); mFlags.insert(PF); mBOOLDISPLAY.insert(PF); + + mSETONEZEROTOGGLE.insert(AF); mFlags.insert(AF); mBOOLDISPLAY.insert(AF); + + mSETONEZEROTOGGLE.insert(ZF); mFlags.insert(ZF); mBOOLDISPLAY.insert(ZF); + + mSETONEZEROTOGGLE.insert(SF); mFlags.insert(SF); mBOOLDISPLAY.insert(SF); + + mSETONEZEROTOGGLE.insert(TF); mFlags.insert(TF); mBOOLDISPLAY.insert(TF); + mFlags.insert(IF); mBOOLDISPLAY.insert(IF); + + mSETONEZEROTOGGLE.insert(DF); mFlags.insert(DF); mBOOLDISPLAY.insert(DF); + + mSETONEZEROTOGGLE.insert(OF); mFlags.insert(OF); mBOOLDISPLAY.insert(OF); // FPU: XMM, x87 and MMX registers + mSETONEZEROTOGGLE.insert(MxCsr); mDWORDDISPLAY.insert(MxCsr); + mMODIFYDISPLAY.insert(MxCsr); mFPUx87.insert(x87r0); mFPUx87_80BITSDISPLAY.insert(x87r0); + mFPUx87.insert(x87r1); mFPUx87_80BITSDISPLAY.insert(x87r1); + mFPUx87.insert(x87r2); mFPUx87_80BITSDISPLAY.insert(x87r2); + mFPUx87.insert(x87r3); mFPUx87_80BITSDISPLAY.insert(x87r3); + mFPUx87.insert(x87r4); mFPUx87_80BITSDISPLAY.insert(x87r4); + mFPUx87.insert(x87r5); mFPUx87_80BITSDISPLAY.insert(x87r5); + mFPUx87.insert(x87r6); mFPUx87_80BITSDISPLAY.insert(x87r6); + mFPUx87.insert(x87r7); mFPUx87_80BITSDISPLAY.insert(x87r7); + mSETONEZEROTOGGLE.insert(x87TagWord); mFPUx87.insert(x87TagWord); + mMODIFYDISPLAY.insert(x87TagWord); mUSHORTDISPLAY.insert(x87TagWord); + + mSETONEZEROTOGGLE.insert(x87StatusWord); mUSHORTDISPLAY.insert(x87StatusWord); + mMODIFYDISPLAY.insert(x87StatusWord); mFPUx87.insert(x87StatusWord); + + mSETONEZEROTOGGLE.insert(x87ControlWord); mFPUx87.insert(x87ControlWord); + mMODIFYDISPLAY.insert(x87ControlWord); mUSHORTDISPLAY.insert(x87ControlWord); + mSETONEZEROTOGGLE.insert(x87SW_B); mFPUx87.insert(x87SW_B); mBOOLDISPLAY.insert(x87SW_B); + + mSETONEZEROTOGGLE.insert(x87SW_C3); mFPUx87.insert(x87SW_C3); mBOOLDISPLAY.insert(x87SW_C3); + mFPUx87.insert(x87SW_TOP); mFPUx87.insert(x87SW_C2); mBOOLDISPLAY.insert(x87SW_C2); - mFPUx87.insert(x87SW_C2); - mBOOLDISPLAY.insert(x87SW_C2); + mSETONEZEROTOGGLE.insert(x87SW_C2); + + mSETONEZEROTOGGLE.insert(x87SW_C1); mFPUx87.insert(x87SW_C1); mBOOLDISPLAY.insert(x87SW_C1); + + mSETONEZEROTOGGLE.insert(x87SW_C0); mFPUx87.insert(x87SW_C0); mBOOLDISPLAY.insert(x87SW_C0); + + mSETONEZEROTOGGLE.insert(x87SW_IR); mFPUx87.insert(x87SW_IR); mBOOLDISPLAY.insert(x87SW_IR); + + mSETONEZEROTOGGLE.insert(x87SW_SF); mFPUx87.insert(x87SW_SF); mBOOLDISPLAY.insert(x87SW_SF); + + mSETONEZEROTOGGLE.insert(x87SW_P); mFPUx87.insert(x87SW_P); mBOOLDISPLAY.insert(x87SW_P); + + mSETONEZEROTOGGLE.insert(x87SW_U); mFPUx87.insert(x87SW_U); mBOOLDISPLAY.insert(x87SW_U); + + mSETONEZEROTOGGLE.insert(x87SW_O); mFPUx87.insert(x87SW_O); mBOOLDISPLAY.insert(x87SW_O); + + mSETONEZEROTOGGLE.insert(x87SW_Z); mFPUx87.insert(x87SW_Z); mBOOLDISPLAY.insert(x87SW_Z); + + mSETONEZEROTOGGLE.insert(x87SW_D); mFPUx87.insert(x87SW_D); mBOOLDISPLAY.insert(x87SW_D); + + mSETONEZEROTOGGLE.insert(x87SW_I); mFPUx87.insert(x87SW_I); mBOOLDISPLAY.insert(x87SW_I); + mSETONEZEROTOGGLE.insert(x87CW_IC); mFPUx87.insert(x87CW_IC); mBOOLDISPLAY.insert(x87CW_IC); + mFPUx87.insert(x87CW_RC); mFPUx87.insert(x87CW_PC); + mSETONEZEROTOGGLE.insert(x87CW_IEM); mFPUx87.insert(x87CW_IEM); mBOOLDISPLAY.insert(x87CW_IEM); + + mSETONEZEROTOGGLE.insert(x87CW_PM); mFPUx87.insert(x87CW_PM); mBOOLDISPLAY.insert(x87CW_PM); + + mSETONEZEROTOGGLE.insert(x87CW_UM); mFPUx87.insert(x87CW_UM); mBOOLDISPLAY.insert(x87CW_UM); + + mSETONEZEROTOGGLE.insert(x87CW_OM); mFPUx87.insert(x87CW_OM); mBOOLDISPLAY.insert(x87CW_OM); + + mSETONEZEROTOGGLE.insert(x87CW_ZM); mFPUx87.insert(x87CW_ZM); mBOOLDISPLAY.insert(x87CW_ZM); + + mSETONEZEROTOGGLE.insert(x87CW_DM); mFPUx87.insert(x87CW_DM); mBOOLDISPLAY.insert(x87CW_DM); + + mSETONEZEROTOGGLE.insert(x87CW_IM); mFPUx87.insert(x87CW_IM); mBOOLDISPLAY.insert(x87CW_IM); + mSETONEZEROTOGGLE.insert(MxCsr_FZ); mBOOLDISPLAY.insert(MxCsr_FZ); + + mSETONEZEROTOGGLE.insert(MxCsr_PM); mBOOLDISPLAY.insert(MxCsr_PM); + + mSETONEZEROTOGGLE.insert(MxCsr_UM); mBOOLDISPLAY.insert(MxCsr_UM); + + mSETONEZEROTOGGLE.insert(MxCsr_OM); mBOOLDISPLAY.insert(MxCsr_OM); + + mSETONEZEROTOGGLE.insert(MxCsr_ZM); mBOOLDISPLAY.insert(MxCsr_ZM); + + mSETONEZEROTOGGLE.insert(MxCsr_IM); mBOOLDISPLAY.insert(MxCsr_IM); + + mSETONEZEROTOGGLE.insert(MxCsr_DM); + mBOOLDISPLAY.insert(MxCsr_DM); + + mSETONEZEROTOGGLE.insert(MxCsr_DAZ); mBOOLDISPLAY.insert(MxCsr_DAZ); + + mSETONEZEROTOGGLE.insert(MxCsr_PE); mBOOLDISPLAY.insert(MxCsr_PE); + + mSETONEZEROTOGGLE.insert(MxCsr_UE); mBOOLDISPLAY.insert(MxCsr_UE); + + mSETONEZEROTOGGLE.insert(MxCsr_OE); mBOOLDISPLAY.insert(MxCsr_OE); + + mSETONEZEROTOGGLE.insert(MxCsr_ZE); mBOOLDISPLAY.insert(MxCsr_ZE); + + mSETONEZEROTOGGLE.insert(MxCsr_DE); mBOOLDISPLAY.insert(MxCsr_DE); + + mSETONEZEROTOGGLE.insert(MxCsr_IE); mBOOLDISPLAY.insert(MxCsr_IE); //MxCsr_RC @@ -233,14 +415,19 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff //registers that should not be changed mNoChange.insert(GS); mUSHORTDISPLAY.insert(GS); + mNoChange.insert(FS); mUSHORTDISPLAY.insert(FS); + mNoChange.insert(ES); mUSHORTDISPLAY.insert(ES); + mNoChange.insert(DS); mUSHORTDISPLAY.insert(DS); + mNoChange.insert(CS); mUSHORTDISPLAY.insert(CS); + mNoChange.insert(SS); mUSHORTDISPLAY.insert(SS); @@ -248,29 +435,42 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mUINTDISPLAY.insert(DR0); mLABELDISPLAY.insert(DR0); mONLYMODULEANDLABELDISPLAY.insert(DR0); + mCANSTOREADDRESS.insert(DR0); + mNoChange.insert(DR1); mONLYMODULEANDLABELDISPLAY.insert(DR1); mUINTDISPLAY.insert(DR1); + mCANSTOREADDRESS.insert(DR1); + mLABELDISPLAY.insert(DR2); mONLYMODULEANDLABELDISPLAY.insert(DR2); mNoChange.insert(DR2); mUINTDISPLAY.insert(DR2); + mCANSTOREADDRESS.insert(DR2); + mNoChange.insert(DR3); mONLYMODULEANDLABELDISPLAY.insert(DR3); mLABELDISPLAY.insert(DR3); mUINTDISPLAY.insert(DR3); + mCANSTOREADDRESS.insert(DR3); + mNoChange.insert(DR6); mLABELDISPLAY.insert(DR6); mONLYMODULEANDLABELDISPLAY.insert(DR6); mUINTDISPLAY.insert(DR6); + mCANSTOREADDRESS.insert(DR6); + mNoChange.insert(DR7); mUINTDISPLAY.insert(DR7); mONLYMODULEANDLABELDISPLAY.insert(DR7); + mCANSTOREADDRESS.insert(DR7); mLABELDISPLAY.insert(DR7); + mNoChange.insert(CIP); mUINTDISPLAY.insert(CIP); mLABELDISPLAY.insert(CIP); mONLYMODULEANDLABELDISPLAY.insert(CIP); + mCANSTOREADDRESS.insert(CIP); // create mapping from internal id to name mRegisterMapping.clear(); @@ -507,8 +707,10 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset + 31, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); + mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 12, 10, 1)); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 1)); offset++; @@ -711,11 +913,11 @@ void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) if(!identifyRegister(y, x, 0)) return; // is current register general purposes register or FPU register? - if(mGPR.contains(mSelected) || mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) + if(mMODIFYDISPLAY.contains(mSelected)) { wCM_Modify->trigger(); } - else if(mFlags.contains(mSelected)) // is flag ? + else if(mBOOLDISPLAY.contains(mSelected)) // is flag ? wCM_ToggleValue->trigger(); else if(mSelected == CIP) //double clicked on CIP register DbgCmdExec("disasm cip"); @@ -873,6 +1075,30 @@ double readFloat80(const uint8_t buffer[10]) return sign * ldexp(significand, exponent - EXP_BIAS); } +QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value) +{ + QString valueText; + + if(mUINTDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((uint_t*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mUSHORTDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((unsigned short*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mDWORDDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((DWORD*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mBOOLDISPLAY.contains(reg)) + valueText = QString("%1").arg((* ((bool*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else + { + SIZE_T size = GetSizeRegister(reg); + if(size != 0) + valueText = QString(QByteArray(value, size).toHex()).toUpper(); + else + valueText = QString("???"); + } + + return valueText; +} + void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) { // is the register-id known? @@ -915,22 +1141,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) QString valueText; // draw value - if(mUINTDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((uint_t*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mUSHORTDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((unsigned short*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mDWORDDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((DWORD*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else if(mBOOLDISPLAY.contains(reg)) - valueText = QString("%1").arg((* ((bool*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); - else - { - SIZE_T size = GetSizeRegister(reg); - if(size != 0) - valueText = QString(QByteArray(value, size).toHex()).toUpper(); - else - valueText = QString("???"); - } + valueText = GetRegStringValueFromValue(reg, value); width = mCharWidth * valueText.length(); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, valueText); //p->drawText(x + (mRegisterPlaces[reg].labelwidth)*mCharWidth ,mRowHeight*(mRegisterPlaces[reg].line+1),QString("%1").arg(value, mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper()); @@ -1008,7 +1219,7 @@ void RegistersView::updateRegistersSlot() void RegistersView::displayEditDialog() { - if(!mFPUx87.contains(mSelected) && !mFPUMMX.contains(mSelected)) + if(1) { WordEditDialog wEditDial(this); wEditDial.setup(QString("Edit"), (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), sizeof(int_t)); @@ -1040,47 +1251,50 @@ void RegistersView::displayEditDialog() void RegistersView::onIncrementAction() { - if(mGPR.contains(mSelected)) + if(mINCREMENTDECREMET.contains(mSelected)) setRegister(mSelected, (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) + 1); } void RegistersView::onDecrementAction() { - if(mGPR.contains(mSelected)) + if(mINCREMENTDECREMET.contains(mSelected)) setRegister(mSelected, (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) - 1); } void RegistersView::onZeroAction() { - if(!mNoChange.contains(mSelected)) + if(mSETONEZEROTOGGLE.contains(mSelected)) setRegister(mSelected, 0); } void RegistersView::onSetToOneAction() { - if(!mNoChange.contains(mSelected)) + if(mSETONEZEROTOGGLE.contains(mSelected)) setRegister(mSelected, 1); } void RegistersView::onModifyAction() { - if(mGPR.contains(mSelected) || mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) + if(mMODIFYDISPLAY.contains(mSelected)) displayEditDialog(); } void RegistersView::onToggleValueAction() { - if(mFlags.contains(mSelected)) + if(mSETONEZEROTOGGLE.contains(mSelected)) { - int value = (int)(* (bool*) registerValue(&wRegDumpStruct, mSelected)); - setRegister(mSelected, value ^ 1); - } - else - { - int_t val = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); - val++; - val *= -1; - setRegister(mSelected, val); + if(mBOOLDISPLAY.contains(mSelected)) + { + int value = (int)(* (bool*) registerValue(&wRegDumpStruct, mSelected)); + setRegister(mSelected, value ^ 1); + } + else + { + int_t val = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); + val++; + val *= -1; + setRegister(mSelected, val); + } } } @@ -1122,7 +1336,7 @@ void RegistersView::onCopySymbolToClipboardAction() void RegistersView::onFollowInDisassembly() { - if(mGPR.contains(mSelected)) + if(mCANSTOREADDRESS.contains(mSelected)) { QString addr = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); if(DbgMemIsValidReadPtr((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))))) @@ -1132,7 +1346,7 @@ void RegistersView::onFollowInDisassembly() void RegistersView::onFollowInDump() { - if(mGPR.contains(mSelected)) + if(mCANSTOREADDRESS.contains(mSelected)) { QString addr = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); if(DbgMemIsValidReadPtr((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))))) @@ -1142,7 +1356,7 @@ void RegistersView::onFollowInDump() void RegistersView::onFollowInStack() { - if(mGPR.contains(mSelected)) + if(mCANSTOREADDRESS.contains(mSelected)) { QString addr = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); if(DbgMemIsValidReadPtr((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))))) @@ -1158,7 +1372,7 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) if(mSelected != UNKNOWN) { - if(!mNoChange.contains(mSelected) && !mFPUx87.contains(mSelected) && !mFPUMMX.contains(mSelected)) + if(mSETONEZEROTOGGLE.contains(mSelected)) { if((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))) >= 1) wMenu.addAction(wCM_Zero); @@ -1167,31 +1381,40 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) wMenu.addAction(wCM_ToggleValue); } - if(mGPR.contains(mSelected) || mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) + if(mINCREMENTDECREMET.contains(mSelected)) + { + wMenu.addAction(wCM_Increment); + wMenu.addAction(wCM_Decrement); + } + + if(mMODIFYDISPLAY.contains(mSelected)) { wMenu.addAction(wCM_Modify); + } - if(mGPR.contains(mSelected)) + if(mCANSTOREADDRESS.contains(mSelected)) + { + uint_t addr = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); + if(DbgMemIsValidReadPtr(addr)) { - wMenu.addAction(wCM_Increment); - wMenu.addAction(wCM_Decrement); - - uint_t addr = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); - if(DbgMemIsValidReadPtr(addr)) - { - wMenu.addAction(wCM_FollowInDump); - wMenu.addAction(wCM_FollowInDisassembly); - duint size = 0; - duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); - if(addr >= base && addr < base + size) - wMenu.addAction(wCM_FollowInStack); - } + wMenu.addAction(wCM_FollowInDump); + wMenu.addAction(wCM_FollowInDisassembly); + duint size = 0; + duint base = DbgMemFindBaseAddr(DbgValFromString("csp"), &size); + if(addr >= base && addr < base + size) + wMenu.addAction(wCM_FollowInStack); } } + + if(mLABELDISPLAY.contains(mSelected)) + { + QString symbol = getRegisterLabel(mSelected); + if(symbol != "") + wMenu.addAction(wCM_CopySymbolToClipboard); + } + wMenu.addAction(wCM_CopyToClipboard); - QString symbol = getRegisterLabel(mSelected); - if(symbol != "") - wMenu.addAction(wCM_CopySymbolToClipboard); + wMenu.exec(this->mapToGlobal(pos)); } else @@ -1350,12 +1573,56 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == x87r6) return (char*) & (regd->x87FPURegisters[6]); if(reg == x87r7) return (char*) & (regd->x87FPURegisters[7]); - if(reg == x87ControlWord) return (char*) & (regd->titcontext.x87fpu.ControlWord); - if(reg == x87StatusWord) return (char*) & (regd->titcontext.x87fpu.StatusWord); if(reg == x87TagWord) return (char*) & (regd->titcontext.x87fpu.TagWord); + if(reg == x87ControlWord) return (char*) & (regd->titcontext.x87fpu.ControlWord); + + if(reg == x87CW_IC) return (char*) & (regd->x87ControlWordFields.IC); + if(reg == x87CW_IEM) return (char*) & (regd->x87ControlWordFields.IEM); + if(reg == x87CW_PM) return (char*) & (regd->x87ControlWordFields.PM); + if(reg == x87CW_UM) return (char*) & (regd->x87ControlWordFields.UM); + if(reg == x87CW_OM) return (char*) & (regd->x87ControlWordFields.OM); + if(reg == x87CW_ZM) return (char*) & (regd->x87ControlWordFields.ZM); + if(reg == x87CW_DM) return (char*) & (regd->x87ControlWordFields.DM); + if(reg == x87CW_IM) return (char*) & (regd->x87ControlWordFields.IM); + if(reg == x87CW_RC) return (char*) & (regd->x87ControlWordFields.RC); + if(reg == x87CW_PC) return (char*) & (regd->x87ControlWordFields.PC); + + if(reg == x87StatusWord) return (char*) & (regd->titcontext.x87fpu.StatusWord); + + if(reg == x87SW_B) return (char*) & (regd->x87StatusWordFields.B); + if(reg == x87SW_C3) return (char*) & (regd->x87StatusWordFields.C3); + if(reg == x87SW_C2) return (char*) & (regd->x87StatusWordFields.C2); + if(reg == x87SW_C1) return (char*) & (regd->x87StatusWordFields.C1); + if(reg == x87SW_O) return (char*) & (regd->x87StatusWordFields.O); + if(reg == x87SW_IR) return (char*) & (regd->x87StatusWordFields.IR); + if(reg == x87SW_SF) return (char*) & (regd->x87StatusWordFields.SF); + if(reg == x87SW_P) return (char*) & (regd->x87StatusWordFields.P); + if(reg == x87SW_U) return (char*) & (regd->x87StatusWordFields.U); + if(reg == x87SW_Z) return (char*) & (regd->x87StatusWordFields.Z); + if(reg == x87SW_D) return (char*) & (regd->x87StatusWordFields.D); + if(reg == x87SW_I) return (char*) & (regd->x87StatusWordFields.I); + if(reg == x87SW_C0) return (char*) & (regd->x87StatusWordFields.C0); + if(reg == x87SW_TOP) return (char*) & (regd->x87StatusWordFields.TOP); + if(reg == MxCsr) return (char*) & (regd->titcontext.MxCsr); + if(reg == MxCsr_FZ) return (char*) & (regd->MxCsrFields.FZ); + if(reg == MxCsr_PM) return (char*) & (regd->MxCsrFields.PM); + if(reg == MxCsr_UM) return (char*) & (regd->MxCsrFields.UM); + if(reg == MxCsr_OM) return (char*) & (regd->MxCsrFields.OM); + if(reg == MxCsr_ZM) return (char*) & (regd->MxCsrFields.ZM); + if(reg == MxCsr_IM) return (char*) & (regd->MxCsrFields.IM); + if(reg == MxCsr_DM) return (char*) & (regd->MxCsrFields.DM); + if(reg == MxCsr_DAZ) return (char*) & (regd->MxCsrFields.DAZ); + if(reg == MxCsr_PE) return (char*) & (regd->MxCsrFields.PE); + if(reg == MxCsr_UE) return (char*) & (regd->MxCsrFields.UE); + if(reg == MxCsr_OE) return (char*) & (regd->MxCsrFields.OE); + if(reg == MxCsr_ZE) return (char*) & (regd->MxCsrFields.ZE); + if(reg == MxCsr_DE) return (char*) & (regd->MxCsrFields.DE); + if(reg == MxCsr_IE) return (char*) & (regd->MxCsrFields.IE); + if(reg == MxCsr_RC) return (char*) & (regd->MxCsrFields.RC); + if(reg == XMM0) return (char*) & (regd->titcontext.XmmRegisters[0]); if(reg == XMM1) return (char*) & (regd->titcontext.XmmRegisters[1]); if(reg == XMM2) return (char*) & (regd->titcontext.XmmRegisters[2]); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 77bfce265..63c5782ce 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -39,7 +39,7 @@ public: x87CW_UM, x87CW_OM, x87CW_ZM, x87CW_DM, x87CW_IM, //MxCsr MxCsr, MxCsr_FZ, MxCsr_PM, MxCsr_UM, MxCsr_OM, MxCsr_ZM, - MxCsr_IM, MxCsr_DAZ, MxCsr_PE, MxCsr_UE, MxCsr_OE, + MxCsr_IM, MxCsr_DM, MxCsr_DAZ, MxCsr_PE, MxCsr_UE, MxCsr_OE, MxCsr_ZE, MxCsr_DE, MxCsr_IE, MxCsr_RC, // MMX and XMM MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, @@ -119,6 +119,7 @@ protected slots: QString getRegisterLabel(REGISTER_NAME); int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2); SIZE_T GetSizeRegister(const REGISTER_NAME reg_name); + QString GetRegStringValueFromValue(REGISTER_NAME reg , char* value); private: int mVScrollOffset; int mRowsNeeded; @@ -129,6 +130,10 @@ private: QSet mBOOLDISPLAY; QSet mLABELDISPLAY; QSet mONLYMODULEANDLABELDISPLAY; + QSet mSETONEZEROTOGGLE; + QSet mMODIFYDISPLAY; + QSet mCANSTOREADDRESS; + QSet mINCREMENTDECREMET; QSet mFPUx87_80BITSDISPLAY; // holds current selected register REGISTER_NAME mSelected; From c874ee04d63ddecc737e7f6055f3ae0eb91d06e7 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 26 Oct 2014 19:19:33 +0100 Subject: [PATCH 08/58] all fpu read done. --- x64_dbg_dbg/_exports.cpp | 27 +- x64_dbg_dbg/value.cpp | 132 +++++++++- x64_dbg_dbg/value.h | 5 + x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 241 +++++++++++++++--- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 7 + 5 files changed, 364 insertions(+), 48 deletions(-) diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 3d45cb339..0160c1978 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -349,18 +349,41 @@ void GetMxCsrFields(MxCsr_FIELDS_t* MxCsrFields, DWORD MxCsr) MxCsrFields->ZE = valmxcsrflagfromstring(MxCsr, "ZE"); MxCsrFields->ZM = valmxcsrflagfromstring(MxCsr, "ZM"); - //MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC") + MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC"); } void Getx87ControlWordFields(x87ControlWord_FIELDS_t* x87ControlWordFields, WORD ControlWord) { + x87ControlWordFields->DM = valx87controlwordflagfromstring(ControlWord, "DM"); + x87ControlWordFields->IC = valx87controlwordflagfromstring(ControlWord, "IC"); + x87ControlWordFields->IEM = valx87controlwordflagfromstring(ControlWord, "IEM"); + x87ControlWordFields->IM = valx87controlwordflagfromstring(ControlWord, "IM"); + x87ControlWordFields->OM = valx87controlwordflagfromstring(ControlWord, "OM"); + x87ControlWordFields->PM = valx87controlwordflagfromstring(ControlWord, "PM"); + x87ControlWordFields->UM = valx87controlwordflagfromstring(ControlWord, "UM"); + x87ControlWordFields->ZM = valx87controlwordflagfromstring(ControlWord, "ZM"); + x87ControlWordFields->RC = valx87controlwordfieldfromstring(ControlWord, "RC"); + x87ControlWordFields->PC = valx87controlwordfieldfromstring(ControlWord, "PC"); } void Getx87StatusWordFields(x87StatusWord_FIELDS_t* x87StatusWordFields, WORD StatusWord) { + x87StatusWordFields->B = valx87statuswordflagfromstring(StatusWord, "B"); + x87StatusWordFields->C0 = valx87statuswordflagfromstring(StatusWord, "C0"); + x87StatusWordFields->C1 = valx87statuswordflagfromstring(StatusWord, "C1"); + x87StatusWordFields->C2 = valx87statuswordflagfromstring(StatusWord, "C2"); + x87StatusWordFields->C3 = valx87statuswordflagfromstring(StatusWord, "C3"); + x87StatusWordFields->D = valx87statuswordflagfromstring(StatusWord, "D"); + x87StatusWordFields->I = valx87statuswordflagfromstring(StatusWord, "I"); + x87StatusWordFields->IR = valx87statuswordflagfromstring(StatusWord, "IR"); + x87StatusWordFields->O = valx87statuswordflagfromstring(StatusWord, "O"); + x87StatusWordFields->P = valx87statuswordflagfromstring(StatusWord, "P"); + x87StatusWordFields->SF = valx87statuswordflagfromstring(StatusWord, "SF"); + x87StatusWordFields->U = valx87statuswordflagfromstring(StatusWord, "U"); + x87StatusWordFields->Z = valx87statuswordflagfromstring(StatusWord, "Z"); - + x87StatusWordFields->TOP = valx87statuswordfieldfromstring(StatusWord, "TOP"); } extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index 8292eaf21..83420b9ba 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -258,19 +258,19 @@ static bool isregister(const char* string) } #define MXCSRFLAG_IE 0x1 -#define MXCSRFLAG_DE 0x4 -#define MXCSRFLAG_ZE 0x8 -#define MXCSRFLAG_OE 0x10 -#define MXCSRFLAG_UE 0x20 -#define MXCSRFLAG_PE 0x40 -#define MXCSRFLAG_DAZ 0x80 -#define MXCSRFLAG_IM 0x100 -#define MXCSRFLAG_DM 0x200 -#define MXCSRFLAG_ZM 0x400 -#define MXCSRFLAG_OM 0x800 -#define MXCSRFLAG_UM 0x1000 -#define MXCSRFLAG_PM 0x2000 -#define MXCSRFLAG_FZ 0x4000 +#define MXCSRFLAG_DE 0x2 +#define MXCSRFLAG_ZE 0x4 +#define MXCSRFLAG_OE 0x8 +#define MXCSRFLAG_UE 0x10 +#define MXCSRFLAG_PE 0x20 +#define MXCSRFLAG_DAZ 0x40 +#define MXCSRFLAG_IM 0x80 +#define MXCSRFLAG_DM 0x100 +#define MXCSRFLAG_ZM 0x200 +#define MXCSRFLAG_OM 0x400 +#define MXCSRFLAG_UM 0x800 +#define MXCSRFLAG_PM 0x1000 +#define MXCSRFLAG_FZ 0x8000 typedef struct { @@ -311,6 +311,112 @@ bool valmxcsrflagfromstring(uint mxcsrflags, const char* string) return false; } +#define x87STATUSWORD_FLAG_I 0x1 +#define x87STATUSWORD_FLAG_D 0x2 +#define x87STATUSWORD_FLAG_Z 0x4 +#define x87STATUSWORD_FLAG_O 0x8 +#define x87STATUSWORD_FLAG_U 0x10 +#define x87STATUSWORD_FLAG_P 0x20 +#define x87STATUSWORD_FLAG_SF 0x40 +#define x87STATUSWORD_FLAG_IR 0x80 +#define x87STATUSWORD_FLAG_C0 0x100 +#define x87STATUSWORD_FLAG_C1 0x200 +#define x87STATUSWORD_FLAG_C2 0x400 +#define x87STATUSWORD_FLAG_C3 0x4000 +#define x87STATUSWORD_FLAG_B 0x8000 + +#define X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87STATUSWORD_FLAG_##flag_name } + +bool valx87statuswordflagfromstring(uint statusword, const char* string) +{ + static FLAG_NAME_VALUE_TABLE_t statuswordflagtable[] = + { + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(I), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(D), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(Z), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(O), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(U), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(P), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(SF), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(IR), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C0), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C1), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C2), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(C3), + X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(B) + }; + int i; + + for(i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++) + { + if(scmp(string, statuswordflagtable[i].name)) + return (bool)((int)(statusword & statuswordflagtable[i].flag) != 0); + } + + return false; +} + +#define x87CONTROLWORD_FLAG_IM 0x1 +#define x87CONTROLWORD_FLAG_DM 0x2 +#define x87CONTROLWORD_FLAG_ZM 0x4 +#define x87CONTROLWORD_FLAG_OM 0x8 +#define x87CONTROLWORD_FLAG_UM 0x10 +#define x87CONTROLWORD_FLAG_PM 0x20 +#define x87CONTROLWORD_FLAG_IEM 0x80 +#define x87CONTROLWORD_FLAG_IC 0x1000 + +#define X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87CONTROLWORD_FLAG_##flag_name } + +bool valx87controlwordflagfromstring(uint controlword, const char* string) +{ + static FLAG_NAME_VALUE_TABLE_t controlwordflagtable[] = + { + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(DM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(ZM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(OM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(UM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(PM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IEM), + X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(IC) + }; + int i; + + for(i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++) + { + if(scmp(string, controlwordflagtable[i].name)) + return (bool)((int)(controlword & controlwordflagtable[i].flag) != 0); + } + + return false; +} + +unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string) +{ + if(scmp(string, "RC")) + return ((mxcsrflags & 0x6000) >> 13); + + return 0; +} + +unsigned short valx87statuswordfieldfromstring(uint statusword, const char* string) +{ + if(scmp(string, "TOP")) + return ((statusword & 0x3800) >> 11); + + return 0; +} + +unsigned short valx87controlwordfieldfromstring(uint controlword, const char* string) +{ + if(scmp(string, "PC")) + return ((controlword & 0x300) >> 8); + if(scmp(string, "RC")) + return ((controlword & 0xC00) >> 10); + + return 0; +} + bool valflagfromstring(uint eflags, const char* string) { if(scmp(string, "cf")) diff --git a/x64_dbg_dbg/value.h b/x64_dbg_dbg/value.h index 9dceafeb4..62a67c7ba 100644 --- a/x64_dbg_dbg/value.h +++ b/x64_dbg_dbg/value.h @@ -14,5 +14,10 @@ bool valfromstring(const char* string, uint* value); bool valflagfromstring(uint eflags, const char* string); bool valtostring(const char* string, uint* value, bool silent); bool valmxcsrflagfromstring(uint mxcsrflags, const char* string); +bool valx87statuswordflagfromstring(uint statusword, const char* string); +bool valx87controlwordflagfromstring(uint controlword, const char* string); +unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string); +unsigned short valx87statuswordfieldfromstring(uint statusword, const char* string); +unsigned short valx87controlwordfieldfromstring(uint controlword, const char* string); #endif // _VALUE_H diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index d8ad18017..2f780978a 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -259,6 +259,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mBOOLDISPLAY.insert(x87SW_C3); mFPUx87.insert(x87SW_TOP); + mFIELDVALUE.insert(x87SW_TOP); mFPUx87.insert(x87SW_C2); mBOOLDISPLAY.insert(x87SW_C2); @@ -309,8 +310,42 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mBOOLDISPLAY.insert(x87CW_IC); mFPUx87.insert(x87CW_RC); + mFIELDVALUE.insert(x87CW_RC); + + mFPUx87.insert(x87TW_0); + mFIELDVALUE.insert(x87TW_0); + mTAGWORD.insert(x87TW_0); + + mFPUx87.insert(x87TW_1); + mFIELDVALUE.insert(x87TW_1); + mTAGWORD.insert(x87TW_1); + + mFPUx87.insert(x87TW_2); + mFIELDVALUE.insert(x87TW_2); + mTAGWORD.insert(x87TW_2); + + mFPUx87.insert(x87TW_3); + mFIELDVALUE.insert(x87TW_3); + mTAGWORD.insert(x87TW_3); + + mFPUx87.insert(x87TW_4); + mFIELDVALUE.insert(x87TW_4); + mTAGWORD.insert(x87TW_4); + + mFPUx87.insert(x87TW_5); + mFIELDVALUE.insert(x87TW_5); + mTAGWORD.insert(x87TW_5); + + mFPUx87.insert(x87TW_6); + mFIELDVALUE.insert(x87TW_6); + mTAGWORD.insert(x87TW_6); + + mFPUx87.insert(x87TW_7); + mFIELDVALUE.insert(x87TW_7); + mTAGWORD.insert(x87TW_7); mFPUx87.insert(x87CW_PC); + mFIELDVALUE.insert(x87CW_PC); mSETONEZEROTOGGLE.insert(x87CW_IEM); mFPUx87.insert(x87CW_IEM); @@ -382,7 +417,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mSETONEZEROTOGGLE.insert(MxCsr_IE); mBOOLDISPLAY.insert(MxCsr_IE); - //MxCsr_RC + mFIELDVALUE.insert(MxCsr_RC); mFPUMMX.insert(MM0); mFPUMMX.insert(MM1); @@ -606,6 +641,28 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(x87TagWord, "x87TagWord"); mRegisterPlaces.insert(x87TagWord, Register_Position(offset + 14, 0, 11, sizeof(WORD) * 2)); + mRegisterMapping.insert(x87TW_0, "x87TW_0"); + mRegisterPlaces.insert(x87TW_0, Register_Position(offset + 15, 0, 8, 10)); + mRegisterMapping.insert(x87TW_1, "x87TW_1"); + mRegisterPlaces.insert(x87TW_1, Register_Position(offset + 15, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_2, "x87TW_2"); + mRegisterPlaces.insert(x87TW_2, Register_Position(offset + 16, 0, 8, 10)); + mRegisterMapping.insert(x87TW_3, "x87TW_3"); + mRegisterPlaces.insert(x87TW_3, Register_Position(offset + 16, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_4, "x87TW_4"); + mRegisterPlaces.insert(x87TW_4, Register_Position(offset + 17, 0, 8, 10)); + mRegisterMapping.insert(x87TW_5, "x87TW_5"); + mRegisterPlaces.insert(x87TW_5, Register_Position(offset + 17, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_6, "x87TW_6"); + mRegisterPlaces.insert(x87TW_6, Register_Position(offset + 18, 0, 8, 10)); + mRegisterMapping.insert(x87TW_7, "x87TW_7"); + mRegisterPlaces.insert(x87TW_7, Register_Position(offset + 18, 20, 8, 10)); + + offset += 4; + offset++; mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); mRegisterPlaces.insert(x87StatusWord, Register_Position(offset + 15, 0, 14, sizeof(WORD) * 2)); @@ -641,7 +698,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(x87SW_I, "x87SW_I"); mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); - mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 1)); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 6)); offset++; @@ -667,10 +724,10 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); mRegisterPlaces.insert(x87CW_IM, Register_Position(offset + 24, 12, 10, 1)); mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); - mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 1)); + mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 13)); mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); - mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 1)); + mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 13)); offset++; @@ -710,7 +767,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 1)); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 13)); offset++; @@ -1087,6 +1144,108 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value valueText = QString("%1").arg((* ((DWORD*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); else if(mBOOLDISPLAY.contains(reg)) valueText = QString("%1").arg((* ((bool*) value)), mRegisterPlaces[reg].valuesize, 16, QChar('0')).toUpper(); + else if(mFIELDVALUE.contains(reg)) + { + if(mTAGWORD.contains(reg)) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString("("); + valueText += GetTagWordStateString((* ((unsigned short*) value))); + valueText += QString(")"); + } + if(reg == MxCsr_RC) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString("("); +#define MxCsr_RC_NEAR 0 +#define MxCsr_RC_NEGATIVE 1 +#define MxCsr_RC_POSITIVE 2 +#define MxCsr_RC_TOZERO 3 + switch((* ((unsigned short*) value))) + { + case MxCsr_RC_NEAR: + valueText += "round near"; + break; + + case MxCsr_RC_NEGATIVE: + valueText += "toward negative"; + break; + + case MxCsr_RC_POSITIVE: + valueText += "toward positive"; + break; + + case MxCsr_RC_TOZERO: + valueText += "toward zero"; + break; + } + + valueText += QString(")"); + } + else if(reg == x87CW_RC) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString("("); +#define x87CW_RC_NEAR 0 +#define x87CW_RC_DOWN 1 +#define x87CW_RC_UP 2 +#define x87CW_RC_TRUNCATE 3 + switch((* ((unsigned short*) value))) + { + case x87CW_RC_NEAR: + valueText += "round near"; + break; + + case x87CW_RC_DOWN: + valueText += "round down"; + break; + + case x87CW_RC_UP: + valueText += "round up"; + break; + + case x87CW_RC_TRUNCATE: + valueText += "truncate"; + break; + } + + valueText += QString(")"); + } + else if(reg == x87CW_PC) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString("("); +#define x87CW_PC_REAL4 0 +#define x87CW_PC_NOTUSED 1 +#define x87CW_PC_REAL8 2 +#define x87CW_PC_REAL10 3 + switch((* ((unsigned short*) value))) + { + case x87CW_PC_REAL4: + valueText += "real4"; + break; + + case x87CW_PC_NOTUSED: + valueText += "not used"; + break; + + case x87CW_PC_REAL8: + valueText += "real8"; + break; + + case x87CW_PC_REAL10: + valueText += "real10"; + break; + } + + valueText += QString(")"); + } + else if(reg == x87SW_TOP) + { + valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); + valueText += QString("(ST") + valueText + QString(")"); + } + } else { SIZE_T size = GetSizeRegister(reg); @@ -1099,6 +1258,39 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value return valueText; } +QString RegistersView::GetTagWordStateString(unsigned short state) +{ +#define X87FPU_TAGWORD_NONZERO 0 +#define X87FPU_TAGWORD_ZERO 1 +#define X87FPU_TAGWORD_SPECIAL 2 +#define X87FPU_TAGWORD_EMPTY 3 + QString string_state = ""; + switch(state) + { + case X87FPU_TAGWORD_NONZERO: + string_state += QString("nonzero"); + break; + + case X87FPU_TAGWORD_ZERO: + string_state += QString("zero"); + break; + + case X87FPU_TAGWORD_SPECIAL: + string_state += QString("special"); + break; + + case X87FPU_TAGWORD_EMPTY: + string_state += QString("empty"); + break; + + default: + string_state += QString("unkown"); + break; + } + + return string_state; +} + void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) { // is the register-id known? @@ -1154,33 +1346,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) QString newText; newText = QString("ST%1 ").arg(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->st_value); -#define X87FPU_TAGWORD_NONZERO 0 -#define X87FPU_TAGWORD_ZERO 1 -#define X87FPU_TAGWORD_SPECIAL 2 -#define X87FPU_TAGWORD_EMPTY 3 - - switch(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->tag) - { - case X87FPU_TAGWORD_NONZERO: - newText += QString("nonzero "); - break; - - case X87FPU_TAGWORD_ZERO: - newText += QString("zero "); - break; - - case X87FPU_TAGWORD_SPECIAL: - newText += QString("special "); - break; - - case X87FPU_TAGWORD_EMPTY: - newText += QString("empty "); - break; - - default: - newText += QString("unkown "); - break; - } + newText += GetTagWordStateString(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->tag) + QString(" "); newText += QString::number(readFloat80(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); width = newText.length() * mCharWidth; @@ -1473,7 +1639,7 @@ SIZE_T RegistersView::GetSizeRegister(const REGISTER_NAME reg_name) if(mUINTDISPLAY.contains(reg_name)) size = sizeof(uint_t); - else if(mUSHORTDISPLAY.contains(reg_name)) + else if(mUSHORTDISPLAY.contains(reg_name) || mFIELDVALUE.contains(reg_name)) size = sizeof(unsigned short); else if(mDWORDDISPLAY.contains(reg_name)) size = sizeof(DWORD); @@ -1577,6 +1743,15 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == x87ControlWord) return (char*) & (regd->titcontext.x87fpu.ControlWord); + if(reg == x87TW_0) return (char*) & (regd->x87FPURegisters[0].tag); + if(reg == x87TW_1) return (char*) & (regd->x87FPURegisters[1].tag); + if(reg == x87TW_2) return (char*) & (regd->x87FPURegisters[2].tag); + if(reg == x87TW_3) return (char*) & (regd->x87FPURegisters[3].tag); + if(reg == x87TW_4) return (char*) & (regd->x87FPURegisters[4].tag); + if(reg == x87TW_5) return (char*) & (regd->x87FPURegisters[5].tag); + if(reg == x87TW_6) return (char*) & (regd->x87FPURegisters[6].tag); + if(reg == x87TW_7) return (char*) & (regd->x87FPURegisters[7].tag); + if(reg == x87CW_IC) return (char*) & (regd->x87ControlWordFields.IC); if(reg == x87CW_IEM) return (char*) & (regd->x87ControlWordFields.IEM); if(reg == x87CW_PM) return (char*) & (regd->x87ControlWordFields.PM); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 63c5782ce..5293989d2 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -30,6 +30,9 @@ public: // x87 stuff x87r0, x87r1, x87r2, x87r3, x87r4, x87r5, x87r6, x87r7, x87TagWord, x87ControlWord, x87StatusWord, + // x87 Tag Word fields + x87TW_0, x87TW_1, x87TW_2, x87TW_3, x87TW_4, x87TW_5, + x87TW_6, x87TW_7, // x87 Status Word fields x87SW_B, x87SW_C3, x87SW_TOP, x87SW_C2, x87SW_C1, x87SW_O, x87SW_IR, x87SW_SF, x87SW_P, x87SW_U, x87SW_Z, @@ -120,6 +123,8 @@ protected slots: int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2); SIZE_T GetSizeRegister(const REGISTER_NAME reg_name); QString GetRegStringValueFromValue(REGISTER_NAME reg , char* value); + QString GetTagWordStateString(unsigned short); + private: int mVScrollOffset; int mRowsNeeded; @@ -132,6 +137,8 @@ private: QSet mONLYMODULEANDLABELDISPLAY; QSet mSETONEZEROTOGGLE; QSet mMODIFYDISPLAY; + QSet mFIELDVALUE; + QSet mTAGWORD; QSet mCANSTOREADDRESS; QSet mINCREMENTDECREMET; QSet mFPUx87_80BITSDISPLAY; From 5bf857b6e4b3e0ffd42533fdd04c70071c90af98 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Mon, 27 Oct 2014 08:02:42 +0100 Subject: [PATCH 09/58] more fpu changes --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 45 ++++ x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 105896 bytes x64_dbg_dbg/value.cpp | 58 ++++- x64_dbg_dbg/value.h | 1 + x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 232 ++++++++++++++---- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 1 + 6 files changed, 289 insertions(+), 48 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index f111e4ec2..3c5bf4245 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -253,6 +253,51 @@ #define UE_SEG_DS 40 #define UE_SEG_CS 41 #define UE_SEG_SS 42 +#define UE_x87_r0 43 +#define UE_x87_r1 44 +#define UE_x87_r2 45 +#define UE_x87_r3 46 +#define UE_x87_r4 47 +#define UE_x87_r5 48 +#define UE_x87_r6 49 +#define UE_x87_r7 50 +#define UE_X87_STATUSWORD 51 +#define UE_X87_CONTROLWORD 52 +#define UE_X87_TAGWORD 53 +#define UE_MXCSR 54 +#define UE_MMX0 55 +#define UE_MMX1 56 +#define UE_MMX2 57 +#define UE_MMX3 58 +#define UE_MMX4 59 +#define UE_MMX5 60 +#define UE_MMX6 61 +#define UE_MMX7 62 +#define UE_XMM0 63 +#define UE_XMM1 64 +#define UE_XMM2 65 +#define UE_XMM3 66 +#define UE_XMM4 67 +#define UE_XMM5 68 +#define UE_XMM6 69 +#define UE_XMM7 70 +#define UE_XMM8 71 +#define UE_XMM9 72 +#define UE_XMM10 73 +#define UE_XMM11 74 +#define UE_XMM12 75 +#define UE_XMM13 76 +#define UE_XMM14 77 +#define UE_XMM15 78 +#define UE_x87_ST0 79 +#define UE_x87_ST1 80 +#define UE_x87_ST2 81 +#define UE_x87_ST3 82 +#define UE_x87_ST4 83 +#define UE_x87_ST5 84 +#define UE_x87_ST6 85 +#define UE_x87_ST7 86 + #ifndef CONTEXT_EXTENDED_REGISTERS #define CONTEXT_EXTENDED_REGISTERS 0 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index fefa7bf57a494e50c677d2d07c9ef01be5679094..e7467ff4f4dfea2b1c9ebee0c3fe6cfe9f4747c1 100644 GIT binary patch delta 10342 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 delta 10342 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 z zR?2?oc^6zp#Vgf*m$OQ2!|mztDmbLIn-JZr{>~a#jN>rp66}uJM(Mp=e7a z-CE`C)G#OYH8BTsy6`pB7nhRJsGpHuQyO~?h|pW6U(eW^i~Q?a#lTpj2S(|?qNvXr z5n||WTO*NkgDETz%6t#rv-6xgPHvtxlJ7XMIbtnrmWH%`E#fA`y6Zqh=UlxG(2~ws zu})MX6|?gp?K2B6a^?B17a!-3nP|>>bOTJnE9+$v@-mXK0p4=RO;`KEMQ6;X*eDK+ z`n|U3>01z$yUR(ju7dXux8KhEI$ zsmDaL|7L51Yw0nx;?0PtC;C0Nh{ufA54VU*SXA0>MU&IM8#nc|+-ud`FrfjR+5#^z jV59#ex;et@y)>gn_uhTVtNg5R+LSGNIHL= RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) @@ -210,241 +211,356 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mSETONEZEROTOGGLE.insert(MxCsr); mDWORDDISPLAY.insert(MxCsr); mMODIFYDISPLAY.insert(MxCsr); + mFPU.insert(MxCsr); + mMODIFYDISPLAY.insert(x87r0); mFPUx87.insert(x87r0); mFPUx87_80BITSDISPLAY.insert(x87r0); + mFPU.insert(x87r0); + mMODIFYDISPLAY.insert(x87r1); mFPUx87.insert(x87r1); mFPUx87_80BITSDISPLAY.insert(x87r1); + mFPU.insert(x87r1); + mMODIFYDISPLAY.insert(x87r2); mFPUx87.insert(x87r2); mFPUx87_80BITSDISPLAY.insert(x87r2); + mFPU.insert(x87r2); + mMODIFYDISPLAY.insert(x87r3); mFPUx87.insert(x87r3); mFPUx87_80BITSDISPLAY.insert(x87r3); + mFPU.insert(x87r3); + mMODIFYDISPLAY.insert(x87r4); mFPUx87.insert(x87r4); mFPUx87_80BITSDISPLAY.insert(x87r4); + mFPU.insert(x87r4); + mMODIFYDISPLAY.insert(x87r5); mFPUx87.insert(x87r5); + mFPU.insert(x87r5); mFPUx87_80BITSDISPLAY.insert(x87r5); + mMODIFYDISPLAY.insert(x87r6); mFPUx87.insert(x87r6); + mFPU.insert(x87r6); mFPUx87_80BITSDISPLAY.insert(x87r6); + mMODIFYDISPLAY.insert(x87r7); mFPUx87.insert(x87r7); + mFPU.insert(x87r7); mFPUx87_80BITSDISPLAY.insert(x87r7); mSETONEZEROTOGGLE.insert(x87TagWord); mFPUx87.insert(x87TagWord); mMODIFYDISPLAY.insert(x87TagWord); mUSHORTDISPLAY.insert(x87TagWord); + mFPU.insert(x87TagWord); mSETONEZEROTOGGLE.insert(x87StatusWord); mUSHORTDISPLAY.insert(x87StatusWord); mMODIFYDISPLAY.insert(x87StatusWord); mFPUx87.insert(x87StatusWord); + mFPU.insert(x87StatusWord); mSETONEZEROTOGGLE.insert(x87ControlWord); mFPUx87.insert(x87ControlWord); mMODIFYDISPLAY.insert(x87ControlWord); mUSHORTDISPLAY.insert(x87ControlWord); + mFPU.insert(x87ControlWord); mSETONEZEROTOGGLE.insert(x87SW_B); mFPUx87.insert(x87SW_B); mBOOLDISPLAY.insert(x87SW_B); + mFPU.insert(x87SW_B); mSETONEZEROTOGGLE.insert(x87SW_C3); mFPUx87.insert(x87SW_C3); mBOOLDISPLAY.insert(x87SW_C3); + mFPU.insert(x87SW_C3); mFPUx87.insert(x87SW_TOP); mFIELDVALUE.insert(x87SW_TOP); + mFPU.insert(x87SW_TOP); mFPUx87.insert(x87SW_C2); mBOOLDISPLAY.insert(x87SW_C2); mSETONEZEROTOGGLE.insert(x87SW_C2); + mFPU.insert(x87SW_C2); mSETONEZEROTOGGLE.insert(x87SW_C1); mFPUx87.insert(x87SW_C1); mBOOLDISPLAY.insert(x87SW_C1); + mFPU.insert(x87SW_C1); mSETONEZEROTOGGLE.insert(x87SW_C0); mFPUx87.insert(x87SW_C0); mBOOLDISPLAY.insert(x87SW_C0); + mFPU.insert(x87SW_C0); mSETONEZEROTOGGLE.insert(x87SW_IR); mFPUx87.insert(x87SW_IR); mBOOLDISPLAY.insert(x87SW_IR); + mFPU.insert(x87SW_IR); mSETONEZEROTOGGLE.insert(x87SW_SF); mFPUx87.insert(x87SW_SF); mBOOLDISPLAY.insert(x87SW_SF); + mFPU.insert(x87SW_SF); mSETONEZEROTOGGLE.insert(x87SW_P); mFPUx87.insert(x87SW_P); mBOOLDISPLAY.insert(x87SW_P); + mFPU.insert(x87SW_P); mSETONEZEROTOGGLE.insert(x87SW_U); mFPUx87.insert(x87SW_U); mBOOLDISPLAY.insert(x87SW_U); + mFPU.insert(x87SW_U); mSETONEZEROTOGGLE.insert(x87SW_O); mFPUx87.insert(x87SW_O); mBOOLDISPLAY.insert(x87SW_O); + mFPU.insert(x87SW_O); mSETONEZEROTOGGLE.insert(x87SW_Z); mFPUx87.insert(x87SW_Z); mBOOLDISPLAY.insert(x87SW_Z); + mFPU.insert(x87SW_Z); mSETONEZEROTOGGLE.insert(x87SW_D); mFPUx87.insert(x87SW_D); mBOOLDISPLAY.insert(x87SW_D); + mFPU.insert(x87SW_D); mSETONEZEROTOGGLE.insert(x87SW_I); mFPUx87.insert(x87SW_I); mBOOLDISPLAY.insert(x87SW_I); + mFPU.insert(x87SW_I); mSETONEZEROTOGGLE.insert(x87CW_IC); mFPUx87.insert(x87CW_IC); mBOOLDISPLAY.insert(x87CW_IC); + mFPU.insert(x87CW_IC); mFPUx87.insert(x87CW_RC); mFIELDVALUE.insert(x87CW_RC); + mFPU.insert(x87CW_RC); mFPUx87.insert(x87TW_0); mFIELDVALUE.insert(x87TW_0); mTAGWORD.insert(x87TW_0); + mFPU.insert(x87TW_0); mFPUx87.insert(x87TW_1); mFIELDVALUE.insert(x87TW_1); mTAGWORD.insert(x87TW_1); + mFPU.insert(x87TW_1); mFPUx87.insert(x87TW_2); mFIELDVALUE.insert(x87TW_2); mTAGWORD.insert(x87TW_2); + mFPU.insert(x87TW_2); mFPUx87.insert(x87TW_3); mFIELDVALUE.insert(x87TW_3); mTAGWORD.insert(x87TW_3); + mFPU.insert(x87TW_3); mFPUx87.insert(x87TW_4); mFIELDVALUE.insert(x87TW_4); mTAGWORD.insert(x87TW_4); + mFPU.insert(x87TW_4); mFPUx87.insert(x87TW_5); mFIELDVALUE.insert(x87TW_5); mTAGWORD.insert(x87TW_5); + mFPU.insert(x87TW_5); mFPUx87.insert(x87TW_6); mFIELDVALUE.insert(x87TW_6); mTAGWORD.insert(x87TW_6); + mFPU.insert(x87TW_6); mFPUx87.insert(x87TW_7); mFIELDVALUE.insert(x87TW_7); mTAGWORD.insert(x87TW_7); + mFPU.insert(x87TW_7); mFPUx87.insert(x87CW_PC); mFIELDVALUE.insert(x87CW_PC); + mFPU.insert(x87CW_PC); mSETONEZEROTOGGLE.insert(x87CW_IEM); mFPUx87.insert(x87CW_IEM); mBOOLDISPLAY.insert(x87CW_IEM); + mFPU.insert(x87CW_IEM); mSETONEZEROTOGGLE.insert(x87CW_PM); mFPUx87.insert(x87CW_PM); mBOOLDISPLAY.insert(x87CW_PM); + mFPU.insert(x87CW_PM); mSETONEZEROTOGGLE.insert(x87CW_UM); mFPUx87.insert(x87CW_UM); mBOOLDISPLAY.insert(x87CW_UM); + mFPU.insert(x87CW_UM); mSETONEZEROTOGGLE.insert(x87CW_OM); mFPUx87.insert(x87CW_OM); mBOOLDISPLAY.insert(x87CW_OM); + mFPU.insert(x87CW_OM); mSETONEZEROTOGGLE.insert(x87CW_ZM); mFPUx87.insert(x87CW_ZM); mBOOLDISPLAY.insert(x87CW_ZM); + mFPU.insert(x87CW_ZM); mSETONEZEROTOGGLE.insert(x87CW_DM); mFPUx87.insert(x87CW_DM); mBOOLDISPLAY.insert(x87CW_DM); + mFPU.insert(x87CW_DM); mSETONEZEROTOGGLE.insert(x87CW_IM); mFPUx87.insert(x87CW_IM); mBOOLDISPLAY.insert(x87CW_IM); + mFPU.insert(x87CW_IM); mSETONEZEROTOGGLE.insert(MxCsr_FZ); mBOOLDISPLAY.insert(MxCsr_FZ); + mFPU.insert(MxCsr_FZ); mSETONEZEROTOGGLE.insert(MxCsr_PM); mBOOLDISPLAY.insert(MxCsr_PM); + mFPU.insert(MxCsr_PM); mSETONEZEROTOGGLE.insert(MxCsr_UM); mBOOLDISPLAY.insert(MxCsr_UM); + mFPU.insert(MxCsr_UM); mSETONEZEROTOGGLE.insert(MxCsr_OM); mBOOLDISPLAY.insert(MxCsr_OM); + mFPU.insert(MxCsr_OM); mSETONEZEROTOGGLE.insert(MxCsr_ZM); mBOOLDISPLAY.insert(MxCsr_ZM); + mFPU.insert(MxCsr_ZM); mSETONEZEROTOGGLE.insert(MxCsr_IM); mBOOLDISPLAY.insert(MxCsr_IM); + mFPU.insert(MxCsr_IM); mSETONEZEROTOGGLE.insert(MxCsr_DM); mBOOLDISPLAY.insert(MxCsr_DM); + mFPU.insert(MxCsr_DM); mSETONEZEROTOGGLE.insert(MxCsr_DAZ); mBOOLDISPLAY.insert(MxCsr_DAZ); + mFPU.insert(MxCsr_DAZ); mSETONEZEROTOGGLE.insert(MxCsr_PE); mBOOLDISPLAY.insert(MxCsr_PE); + mFPU.insert(MxCsr_PE); mSETONEZEROTOGGLE.insert(MxCsr_UE); mBOOLDISPLAY.insert(MxCsr_UE); + mFPU.insert(MxCsr_UE); mSETONEZEROTOGGLE.insert(MxCsr_OE); mBOOLDISPLAY.insert(MxCsr_OE); + mFPU.insert(MxCsr_OE); mSETONEZEROTOGGLE.insert(MxCsr_ZE); mBOOLDISPLAY.insert(MxCsr_ZE); + mFPU.insert(MxCsr_ZE); mSETONEZEROTOGGLE.insert(MxCsr_DE); mBOOLDISPLAY.insert(MxCsr_DE); + mFPU.insert(MxCsr_DE); mSETONEZEROTOGGLE.insert(MxCsr_IE); mBOOLDISPLAY.insert(MxCsr_IE); + mFPU.insert(MxCsr_IE); mFIELDVALUE.insert(MxCsr_RC); + mFPU.insert(MxCsr_RC); + mMODIFYDISPLAY.insert(MM0); mFPUMMX.insert(MM0); + mFPU.insert(MM0); + mMODIFYDISPLAY.insert(MM1); mFPUMMX.insert(MM1); + mFPU.insert(MM1); mFPUMMX.insert(MM2); + mMODIFYDISPLAY.insert(MM2); + mFPU.insert(MM2); mFPUMMX.insert(MM3); + mMODIFYDISPLAY.insert(MM3); + mFPU.insert(MM3); mFPUMMX.insert(MM4); + mMODIFYDISPLAY.insert(MM4); + mFPU.insert(MM4); mFPUMMX.insert(MM5); + mMODIFYDISPLAY.insert(MM5); + mFPU.insert(MM5); mFPUMMX.insert(MM6); + mMODIFYDISPLAY.insert(MM6); + mFPU.insert(MM6); mFPUMMX.insert(MM7); + mMODIFYDISPLAY.insert(MM7); + mFPU.insert(MM7); mFPUXMM.insert(XMM0); + mMODIFYDISPLAY.insert(XMM0); + mFPU.insert(XMM0); mFPUXMM.insert(XMM1); + mMODIFYDISPLAY.insert(XMM1); + mFPU.insert(XMM1); mFPUXMM.insert(XMM2); + mMODIFYDISPLAY.insert(XMM2); + mFPU.insert(XMM2); mFPUXMM.insert(XMM3); + mMODIFYDISPLAY.insert(XMM3); + mFPU.insert(XMM3); mFPUXMM.insert(XMM4); + mMODIFYDISPLAY.insert(XMM4); + mFPU.insert(XMM4); mFPUXMM.insert(XMM5); + mMODIFYDISPLAY.insert(XMM5); + mFPU.insert(XMM5); mFPUXMM.insert(XMM6); + mMODIFYDISPLAY.insert(XMM6); + mFPU.insert(XMM6); mFPUXMM.insert(XMM7); + mMODIFYDISPLAY.insert(XMM7); + mFPU.insert(XMM7); #ifdef _WIN64 mFPUXMM.insert(XMM8); + mMODIFYDISPLAY.insert(XMM8); + mFPU.insert(XMM8); mFPUXMM.insert(XMM9); + mMODIFYDISPLAY.insert(XMM9); + mFPU.insert(XMM9); mFPUXMM.insert(XMM10); + mMODIFYDISPLAY.insert(XMM10); + mFPU.insert(XMM10); mFPUXMM.insert(XMM11); + mMODIFYDISPLAY.insert(XMM11); + mFPU.insert(XMM11); mFPUXMM.insert(XMM12); + mMODIFYDISPLAY.insert(XMM12); + mFPU.insert(XMM12); mFPUXMM.insert(XMM13); + mMODIFYDISPLAY.insert(XMM13); + mFPU.insert(XMM13); mFPUXMM.insert(XMM14); + mMODIFYDISPLAY.insert(XMM14); + mFPU.insert(XMM14); mFPUXMM.insert(XMM15); + mMODIFYDISPLAY.insert(XMM15); + mFPU.insert(XMM15); #endif //registers that should not be changed @@ -1385,34 +1501,67 @@ void RegistersView::updateRegistersSlot() void RegistersView::displayEditDialog() { - if(1) + if(mFPU.contains(mSelected)) + { + bool errorinput = false; + LineEditDialog mLineEdit(this); + + mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); + mLineEdit.setWindowTitle("Edit FPU register"); + mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); + mLineEdit.setCursorPosition(0); + + do + { + errorinput = false; + if(mLineEdit.exec() != QDialog::Accepted) + return; //pressed cancel + + if(mLineEdit.editText.size() != GetSizeRegister(mSelected) * 2) + { + mLineEdit.setCursorPosition(GetSizeRegister(mSelected) * 2); + errorinput = true; + + QMessageBox msg(QMessageBox::Warning, "ERROR SIZE INPUT", "ERROR SIZE INPUT MUST BE: " + QString::number(GetSizeRegister(mSelected) * 2)); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + else + { + bool ok = false; + uint_t fpuvalue; + + if(mUSHORTDISPLAY.contains(mSelected)) + fpuvalue = (uint_t) mLineEdit.editText.toUShort(&ok, 16); + else if(mDWORDDISPLAY.contains(mSelected)) + fpuvalue = mLineEdit.editText.toUInt(&ok, 16); + + if(!ok) + { + errorinput = true; + + QMessageBox msg(QMessageBox::Warning, "ERROR CONVERTING TO HEX", "ERROR CONVERTING TO HEXADECIMAL"); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + else + setRegister(mSelected, fpuvalue); + } + + } + while(errorinput); + } + else { WordEditDialog wEditDial(this); wEditDial.setup(QString("Edit"), (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), sizeof(int_t)); if(wEditDial.exec() == QDialog::Accepted) //OK button clicked setRegister(mSelected, wEditDial.getVal()); } - else - { - /* - LineEditDialog mLineEdit(this); - SIZE_T size; - if (mFPUx87.contains(mSelected)) - size = 10 * 2; - else if (mFPUMMX.contains(mSelected)) - size = 8 * 2; - else - size = sizeof(int_t) * 2; - - mLineEdit.setText(QString("%1").arg((uint_t)registerValue(&wRegDumpStruct, mSelected), size, 16, QChar('0')).toUpper()); - mLineEdit.setWindowTitle("Edit FPU register"); - mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); - mLineEdit.setCursorPosition(0); - - if(mLineEdit.exec() != QDialog::Accepted) - return; //pressed cancel - */ - } } void RegistersView::onIncrementAction() @@ -1456,10 +1605,14 @@ void RegistersView::onToggleValueAction() } else { - int_t val = (* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))); - val++; - val *= -1; - setRegister(mSelected, val); + bool ok = false; + int_t val = GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected)).toInt(&ok, 16); + if(ok) + { + val++; + val *= -1; + setRegister(mSelected, val); + } } } } @@ -1467,26 +1620,7 @@ void RegistersView::onToggleValueAction() void RegistersView::onCopyToClipboardAction() { QClipboard* clipboard = QApplication::clipboard(); - QString valueText; - if(mFPUx87.contains(mSelected) || mFPUMMX.contains(mSelected)) - { - SIZE_T size; - char* value; - if(mFPUx87.contains(mSelected)) - { - value = (char*)((x87FPURegister_t*) registerValue(&wRegDumpStruct, mSelected))->data; - size = 10; - } - else - { - value = (char*) registerValue(&wRegDumpStruct, mSelected); - size = 8; - } - valueText = QString(QByteArray(value, size).toHex()).toUpper(); - } - else - valueText = QString("%1").arg((* ((uint_t*) registerValue(&wRegDumpStruct, mSelected))), mRegisterPlaces[mSelected].valuesize, 16, QChar('0')).toUpper(); - clipboard->setText(valueText); + clipboard->setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); } void RegistersView::onCopySymbolToClipboardAction() @@ -1614,7 +1748,11 @@ void RegistersView::setRegister(REGISTER_NAME reg, uint_t value) // we change the value (so highlight it) mRegisterUpdates.insert(reg); // tell everything the compiler + if(mFPU.contains(reg)) + wRegName = "_" + wRegName; + DbgValToString(wRegName.toUtf8().constData(), value); + // force repaint emit refresh(); } @@ -1673,7 +1811,7 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) { static int null_value = 0; // this is probably the most efficient general method to access the values of the struct - // TODO: or maybe we can add an array with something like: return array[reg].data, this is more fast :-) + // TODO: add an array with something like: return array[reg].data, this is more fast :-) if(reg == CAX) return (char*) & (regd->titcontext.cax); if(reg == CBX) return (char*) & (regd->titcontext.cbx); if(reg == CCX) return (char*) & (regd->titcontext.ccx); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 5293989d2..c94c20c9f 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -142,6 +142,7 @@ private: QSet mCANSTOREADDRESS; QSet mINCREMENTDECREMET; QSet mFPUx87_80BITSDISPLAY; + QSet mFPU; // holds current selected register REGISTER_NAME mSelected; // general purposes register id s (cax, ..., r8, ....) From 0d65cf39fabc40bdeac2fbae5360d0a15334401c Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sat, 1 Nov 2014 02:05:16 +0100 Subject: [PATCH 10/58] more fpu stuff --- x64_dbg_bridge/x64_dbg_bridge.vcxproj | 1 + x64_dbg_dbg/value.cpp | 138 +++++++++++-- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 190 ++++++++++++------ x64_dbg_gui/Project/Src/Gui/RegistersView.h | 1 + x64_dbg_gui/Project/Src/Gui/SelectFields.cpp | 23 +++ x64_dbg_gui/Project/Src/Gui/SelectFields.h | 25 +++ x64_dbg_gui/Project/Src/Gui/SelectFields.ui | 79 ++++++++ x64_dbg_gui/Project/x64_dbg.pro | 9 +- 8 files changed, 386 insertions(+), 80 deletions(-) create mode 100644 x64_dbg_gui/Project/Src/Gui/SelectFields.cpp create mode 100644 x64_dbg_gui/Project/Src/Gui/SelectFields.h create mode 100644 x64_dbg_gui/Project/Src/Gui/SelectFields.ui diff --git a/x64_dbg_bridge/x64_dbg_bridge.vcxproj b/x64_dbg_bridge/x64_dbg_bridge.vcxproj index 2d15f6a53..a68af05da 100644 --- a/x64_dbg_bridge/x64_dbg_bridge.vcxproj +++ b/x64_dbg_bridge/x64_dbg_bridge.vcxproj @@ -59,6 +59,7 @@ MultiThreadedDLL Level3 ProgramDatabase + MaxSpeed MachineX86 diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index d225690c4..3f74cdab1 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -281,7 +281,7 @@ typedef struct #define MXCSR_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, MXCSRFLAG_##flag_name } -bool valmxcsrflagfromstring(uint mxcsrflags, const char* string) +unsigned int getmxcsrflagfromstring(const char* string) { static FLAG_NAME_VALUE_TABLE_t mxcsrnameflagtable[] = { @@ -305,10 +305,19 @@ bool valmxcsrflagfromstring(uint mxcsrflags, const char* string) for(i = 0; i < (sizeof(mxcsrnameflagtable) / sizeof(*mxcsrnameflagtable)); i++) { if(scmp(string, mxcsrnameflagtable[i].name)) - return (bool)((int)(mxcsrflags & mxcsrnameflagtable[i].flag) != 0); + return mxcsrnameflagtable[i].flag; } - return false; + return 0; +} + +bool valmxcsrflagfromstring(uint mxcsrflags, const char* string) +{ + unsigned int flag = getmxcsrflagfromstring(string); + if(flag == 0) + return false; + + return (bool)((int)(mxcsrflags & flag) != 0); } #define x87STATUSWORD_FLAG_I 0x1 @@ -327,7 +336,7 @@ bool valmxcsrflagfromstring(uint mxcsrflags, const char* string) #define X87STATUSWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87STATUSWORD_FLAG_##flag_name } -bool valx87statuswordflagfromstring(uint statusword, const char* string) +unsigned int getx87statuswordflagfromstring(const char* string) { static FLAG_NAME_VALUE_TABLE_t statuswordflagtable[] = { @@ -350,10 +359,19 @@ bool valx87statuswordflagfromstring(uint statusword, const char* string) for(i = 0; i < (sizeof(statuswordflagtable) / sizeof(*statuswordflagtable)); i++) { if(scmp(string, statuswordflagtable[i].name)) - return (bool)((int)(statusword & statuswordflagtable[i].flag) != 0); + return statuswordflagtable[i].flag; } - return false; + return 0; +} + +bool valx87statuswordflagfromstring(uint statusword, const char* string) +{ + unsigned int flag = getx87statuswordflagfromstring(string); + if(flag == 0) + return false; + + return (bool)((int)(statusword & flag) != 0); } #define x87CONTROLWORD_FLAG_IM 0x1 @@ -367,7 +385,7 @@ bool valx87statuswordflagfromstring(uint statusword, const char* string) #define X87CONTROLWORD_NAME_FLAG_TABLE_ENTRY(flag_name) { #flag_name, x87CONTROLWORD_FLAG_##flag_name } -bool valx87controlwordflagfromstring(uint controlword, const char* string) +unsigned int getx87controlwordflagfromstring(const char* string) { static FLAG_NAME_VALUE_TABLE_t controlwordflagtable[] = { @@ -385,10 +403,20 @@ bool valx87controlwordflagfromstring(uint controlword, const char* string) for(i = 0; i < (sizeof(controlwordflagtable) / sizeof(*controlwordflagtable)); i++) { if(scmp(string, controlwordflagtable[i].name)) - return (bool)((int)(controlword & controlwordflagtable[i].flag) != 0); + return controlwordflagtable[i].flag; } - return false; + return 0; +} + +bool valx87controlwordflagfromstring(uint controlword, const char* string) +{ + unsigned int flag = getx87controlwordflagfromstring(string); + + if(flag == 0) + return false; + + return (bool)((int)(controlword & flag) != 0); } unsigned short valmxcsrfieldfromstring(uint mxcsrflags, const char* string) @@ -1538,22 +1566,90 @@ bool startsWith(const char* pre, const char* str) return longEnough(str, lenpre) ? StrNCmpI(str, pre, lenpre) == 0 : false; } +#define MxCsr_PRE_FIELD_STRING "MxCsr_" +#define x87SW_PRE_FIELD_STRING "x87SW_" +#define x87CW_PRE_FIELD_STRING "x87CW_" +#define x87TW_PRE_FIELD_STRING "x87TW_" +#define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1) + + void fpustuff(const char* string, uint value) { - if(startsWith("MxCsr_", string)) + uint xorval = 0; + uint flags = 0; + uint flag = 0; + bool set = false; + + if(value) + set = true; + + if(startsWith(MxCsr_PRE_FIELD_STRING, string)) { + uint flags = GetContextDataEx(hActiveThread, UE_MXCSR); + flag = getmxcsrflagfromstring(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING)); + if(flags & flag and !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_MXCSR, flags ^ xorval); + } + else if(startsWith(x87TW_PRE_FIELD_STRING, string)) + { + unsigned int i; + + string += STRLEN_USING_SIZEOF(x87TW_PRE_FIELD_STRING); + i = atoi(string); + + if(i > 7) + return; + + flags = GetContextDataEx(hActiveThread, UE_X87_TAGWORD); + + flag = 7; + flag <<= i * 2; + + flags &= ~flag; + + flag = value; + flag <<= i * 2; + + flags |= flag; + + SetContextDataEx(hActiveThread, UE_X87_TAGWORD, (unsigned short) flags); } - else if(startsWith("x87TW_", string)) + else if(startsWith(x87SW_PRE_FIELD_STRING, string)) { + if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING), "TOP", strlen("TOP")) == 0) + { + uint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD); + int i = 7; + i <<= 11; + flags &= ~i; + value <<= 11; + flags |= value; + SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags); + } + else + { + uint flags = GetContextDataEx(hActiveThread, UE_X87_STATUSWORD); + flag = getx87statuswordflagfromstring(string + STRLEN_USING_SIZEOF(x87SW_PRE_FIELD_STRING)); + if(flags & flag and !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_X87_STATUSWORD, flags ^ xorval); + } } - else if(startsWith("x87SW_", string)) + else if(startsWith(x87CW_PRE_FIELD_STRING, string)) { - - } - else if(startsWith("x87CW_", string)) - { - + uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + flag = getx87controlwordflagfromstring(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING)); + if(flags & flag and !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags ^ xorval); } else if(StrNCmpI(string, "x87TagWord", strlen(string)) == 0) { @@ -1655,8 +1751,16 @@ bool valtostring(const char* string, uint* value, bool silent) } else if((*string == '_')) { + if(!DbgIsDebugging()) + { + if(!silent) + dputs("not debugging!"); + return false; + } fpustuff(string + 1, * value); GuiUpdateAllViews(); //repaint gui + + return true; } else if(*string == '!' and isflag(string + 1)) //flag { diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 1ada68b55..711f0878f 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -3,6 +3,7 @@ #include "Configuration.h" #include "WordEditDialog.h" #include "LineEditDialog.h" +#include "SelectFields.h" #include @@ -284,6 +285,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFPUx87.insert(x87SW_TOP); mFIELDVALUE.insert(x87SW_TOP); mFPU.insert(x87SW_TOP); + mMODIFYDISPLAY.insert(x87SW_TOP); mFPUx87.insert(x87SW_C2); mBOOLDISPLAY.insert(x87SW_C2); @@ -353,41 +355,49 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFIELDVALUE.insert(x87TW_0); mTAGWORD.insert(x87TW_0); mFPU.insert(x87TW_0); + mMODIFYDISPLAY.insert(x87TW_0); mFPUx87.insert(x87TW_1); mFIELDVALUE.insert(x87TW_1); mTAGWORD.insert(x87TW_1); mFPU.insert(x87TW_1); + mMODIFYDISPLAY.insert(x87TW_1); mFPUx87.insert(x87TW_2); mFIELDVALUE.insert(x87TW_2); mTAGWORD.insert(x87TW_2); mFPU.insert(x87TW_2); + mMODIFYDISPLAY.insert(x87TW_2); mFPUx87.insert(x87TW_3); mFIELDVALUE.insert(x87TW_3); mTAGWORD.insert(x87TW_3); mFPU.insert(x87TW_3); + mMODIFYDISPLAY.insert(x87TW_3); mFPUx87.insert(x87TW_4); mFIELDVALUE.insert(x87TW_4); mTAGWORD.insert(x87TW_4); mFPU.insert(x87TW_4); + mMODIFYDISPLAY.insert(x87TW_4); mFPUx87.insert(x87TW_5); mFIELDVALUE.insert(x87TW_5); mTAGWORD.insert(x87TW_5); mFPU.insert(x87TW_5); + mMODIFYDISPLAY.insert(x87TW_5); mFPUx87.insert(x87TW_6); mFIELDVALUE.insert(x87TW_6); mTAGWORD.insert(x87TW_6); mFPU.insert(x87TW_6); + mMODIFYDISPLAY.insert(x87TW_6); mFPUx87.insert(x87TW_7); mFIELDVALUE.insert(x87TW_7); mTAGWORD.insert(x87TW_7); mFPU.insert(x87TW_7); + mMODIFYDISPLAY.insert(x87TW_7); mFPUx87.insert(x87CW_PC); mFIELDVALUE.insert(x87CW_PC); @@ -1374,37 +1384,50 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value return valueText; } -QString RegistersView::GetTagWordStateString(unsigned short state) -{ #define X87FPU_TAGWORD_NONZERO 0 #define X87FPU_TAGWORD_ZERO 1 #define X87FPU_TAGWORD_SPECIAL 2 #define X87FPU_TAGWORD_EMPTY 3 - QString string_state = ""; - switch(state) + +typedef struct +{ + QString string; + unsigned int value; +} STRING_VALUE_TABLE_t; + +STRING_VALUE_TABLE_t TagWordValueStringTable[] = +{ + {"nonzero", X87FPU_TAGWORD_NONZERO}, + {"zero", X87FPU_TAGWORD_ZERO}, + {"special", X87FPU_TAGWORD_SPECIAL}, + {"empty", X87FPU_TAGWORD_EMPTY} +}; + +unsigned int RegistersView::GetTagWordValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(TagWordValueStringTable) / sizeof(*TagWordValueStringTable)); i++) { - case X87FPU_TAGWORD_NONZERO: - string_state += QString("nonzero"); - break; - - case X87FPU_TAGWORD_ZERO: - string_state += QString("zero"); - break; - - case X87FPU_TAGWORD_SPECIAL: - string_state += QString("special"); - break; - - case X87FPU_TAGWORD_EMPTY: - string_state += QString("empty"); - break; - - default: - string_state += QString("unkown"); - break; + if(TagWordValueStringTable[i].string == string) + return TagWordValueStringTable[i].value; } - return string_state; + return i; +} + + +QString RegistersView::GetTagWordStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(TagWordValueStringTable) / sizeof(*TagWordValueStringTable)); i++) + { + if(TagWordValueStringTable[i].value == state) + return TagWordValueStringTable[i].string; + } + + return "unknown"; } void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) @@ -1503,57 +1526,104 @@ void RegistersView::displayEditDialog() { if(mFPU.contains(mSelected)) { - bool errorinput = false; - LineEditDialog mLineEdit(this); - - mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); - mLineEdit.setWindowTitle("Edit FPU register"); - mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); - mLineEdit.setCursorPosition(0); - - do + if(mTAGWORD.contains(mSelected)) { - errorinput = false; - if(mLineEdit.exec() != QDialog::Accepted) - return; //pressed cancel + SelectFields mSelectFields(this); + QListWidget* mQListWidget = mSelectFields.GetList(); - if(mLineEdit.editText.size() != GetSizeRegister(mSelected) * 2) + QStringList items; + items << GetTagWordStateString(X87FPU_TAGWORD_EMPTY) << GetTagWordStateString(X87FPU_TAGWORD_NONZERO) + << GetTagWordStateString(X87FPU_TAGWORD_SPECIAL) << GetTagWordStateString(X87FPU_TAGWORD_ZERO); + + mQListWidget->addItems(items); + + mSelectFields.setWindowTitle("Edit TAG"); + if(mSelectFields.exec() != QDialog::Accepted) + return; + + if(mQListWidget->selectedItems().count() != 1) + return; + + QListWidgetItem* item = mQListWidget->takeItem(mQListWidget->currentRow()); + + uint_t value = GetTagWordValueFromString(item->text()); + setRegister(mSelected, (uint_t)value); + } + else if(mSelected == x87SW_TOP) + { + SelectFields mSelectFields(this); + QListWidget* mQListWidget = mSelectFields.GetList(); + + QStringList items; + items << "ST0" << "ST1" << "ST2" << "ST3" << "ST4" + << "ST5" << "ST6" << "ST7"; + + mQListWidget->addItems(items); + + mSelectFields.setWindowTitle("Edit x87SW_TOP"); + if(mSelectFields.exec() != QDialog::Accepted) + return; + + if(mQListWidget->selectedItems().count() != 1) + return; + + uint_t value = mQListWidget->currentRow(); + setRegister(mSelected, (uint_t)value); + } + else + { + bool errorinput = false; + LineEditDialog mLineEdit(this); + + mLineEdit.setText(GetRegStringValueFromValue(mSelected, registerValue(&wRegDumpStruct, mSelected))); + mLineEdit.setWindowTitle("Edit FPU register"); + mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); + mLineEdit.setCursorPosition(0); + + do { - mLineEdit.setCursorPosition(GetSizeRegister(mSelected) * 2); - errorinput = true; + errorinput = false; + if(mLineEdit.exec() != QDialog::Accepted) + return; //pressed cancel - QMessageBox msg(QMessageBox::Warning, "ERROR SIZE INPUT", "ERROR SIZE INPUT MUST BE: " + QString::number(GetSizeRegister(mSelected) * 2)); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - } - else - { - bool ok = false; - uint_t fpuvalue; - - if(mUSHORTDISPLAY.contains(mSelected)) - fpuvalue = (uint_t) mLineEdit.editText.toUShort(&ok, 16); - else if(mDWORDDISPLAY.contains(mSelected)) - fpuvalue = mLineEdit.editText.toUInt(&ok, 16); - - if(!ok) + if(mLineEdit.editText.size() != GetSizeRegister(mSelected) * 2) { + mLineEdit.setCursorPosition(GetSizeRegister(mSelected) * 2); errorinput = true; - QMessageBox msg(QMessageBox::Warning, "ERROR CONVERTING TO HEX", "ERROR CONVERTING TO HEXADECIMAL"); + QMessageBox msg(QMessageBox::Warning, "ERROR SIZE INPUT", "ERROR SIZE INPUT MUST BE: " + QString::number(GetSizeRegister(mSelected) * 2)); msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); msg.setParent(this, Qt::Dialog); msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); msg.exec(); } else - setRegister(mSelected, fpuvalue); - } + { + bool ok = false; + uint_t fpuvalue; + if(mUSHORTDISPLAY.contains(mSelected)) + fpuvalue = (uint_t) mLineEdit.editText.toUShort(&ok, 16); + else if(mDWORDDISPLAY.contains(mSelected)) + fpuvalue = mLineEdit.editText.toUInt(&ok, 16); + + if(!ok) + { + errorinput = true; + + QMessageBox msg(QMessageBox::Warning, "ERROR CONVERTING TO HEX", "ERROR CONVERTING TO HEXADECIMAL"); + msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); + msg.setParent(this, Qt::Dialog); + msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); + msg.exec(); + } + else + setRegister(mSelected, fpuvalue); + } + + } + while(errorinput); } - while(errorinput); } else { diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index c94c20c9f..0a5ac980e 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -124,6 +124,7 @@ protected slots: SIZE_T GetSizeRegister(const REGISTER_NAME reg_name); QString GetRegStringValueFromValue(REGISTER_NAME reg , char* value); QString GetTagWordStateString(unsigned short); + unsigned int GetTagWordValueFromString(QString string); private: int mVScrollOffset; diff --git a/x64_dbg_gui/Project/Src/Gui/SelectFields.cpp b/x64_dbg_gui/Project/Src/Gui/SelectFields.cpp new file mode 100644 index 000000000..98093885e --- /dev/null +++ b/x64_dbg_gui/Project/Src/Gui/SelectFields.cpp @@ -0,0 +1,23 @@ +#include "selectfields.h" +#include "ui_selectfields.h" + +SelectFields::SelectFields(QWidget* parent) : + QDialog(parent), + ui(new Ui::SelectFields) +{ + ui->setupUi(this); +#if QT_VERSION < QT_VERSION_CHECK(5,0,0) + setWindowFlags(Qt::Dialog | Qt::WindowSystemMenuHint | Qt::WindowTitleHint | Qt::MSWindowsFixedSizeDialogHint); +#endif + setModal(true); +} + +QListWidget* SelectFields::GetList(void) +{ + return ui->listWidget; +} + +SelectFields::~SelectFields() +{ + delete ui; +} diff --git a/x64_dbg_gui/Project/Src/Gui/SelectFields.h b/x64_dbg_gui/Project/Src/Gui/SelectFields.h new file mode 100644 index 000000000..e365ff93e --- /dev/null +++ b/x64_dbg_gui/Project/Src/Gui/SelectFields.h @@ -0,0 +1,25 @@ +#ifndef SELECTFIELDS_H +#define SELECTFIELDS_H + +#include +#include + +namespace Ui +{ +class SelectFields; +} + +class SelectFields : public QDialog +{ + Q_OBJECT + +public: + explicit SelectFields(QWidget* parent = 0); + QListWidget* GetList(void); + ~SelectFields(); + +private: + Ui::SelectFields* ui; +}; + +#endif // SELECTFIELDS_H diff --git a/x64_dbg_gui/Project/Src/Gui/SelectFields.ui b/x64_dbg_gui/Project/Src/Gui/SelectFields.ui new file mode 100644 index 000000000..f3fa7f6c8 --- /dev/null +++ b/x64_dbg_gui/Project/Src/Gui/SelectFields.ui @@ -0,0 +1,79 @@ + + + SelectFields + + + Qt::NonModal + + + + 0 + 0 + 213 + 181 + + + + Dialog + + + + :/icons/images/log.png:/icons/images/log.png + + + true + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + + + + + + + + + buttonBox + accepted() + SelectFields + accept() + + + 248 + 254 + + + 157 + 274 + + + + + buttonBox + rejected() + SelectFields + reject() + + + 316 + 260 + + + 286 + 274 + + + + + diff --git a/x64_dbg_gui/Project/x64_dbg.pro b/x64_dbg_gui/Project/x64_dbg.pro index 9eae84fe6..44dc257aa 100644 --- a/x64_dbg_gui/Project/x64_dbg.pro +++ b/x64_dbg_gui/Project/x64_dbg.pro @@ -83,7 +83,8 @@ SOURCES += \ Src/BasicView/ShortcutEdit.cpp \ Src/Gui/CalculatorDialog.cpp \ Src/Gui/AttachDialog.cpp \ - Src/Gui/PageMemoryRights.cpp + Src/Gui/PageMemoryRights.cpp \ + Src/Gui/SelectFields.cpp HEADERS += \ @@ -145,7 +146,8 @@ HEADERS += \ Src/BasicView/ShortcutEdit.h \ Src/Gui/CalculatorDialog.h \ Src/Gui/AttachDialog.h \ - Src/Gui/PageMemoryRights.h + Src/Gui/PageMemoryRights.h \ + Src/Gui/SelectFields.h INCLUDEPATH += \ @@ -179,7 +181,8 @@ FORMS += \ Src/Gui/ShortcutsDialog.ui \ Src/Gui/CalculatorDialog.ui \ Src/Gui/AttachDialog.ui \ - Src/Gui/PageMemoryRights.ui + Src/Gui/PageMemoryRights.ui \ + Src/Gui/SelectFields.ui INCLUDEPATH += $$PWD/Src/Bridge From acce7800fbeb00758e012202dae2604b262d0389 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 2 Nov 2014 00:31:21 +0100 Subject: [PATCH 11/58] last fpu changes - ended basic first version --- x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 105896 bytes x64_dbg_dbg/value.cpp | 239 ++++++++- .../Project/Src/Gui/LineEditDialog.cpp | 24 + x64_dbg_gui/Project/Src/Gui/LineEditDialog.h | 2 + x64_dbg_gui/Project/Src/Gui/LineEditDialog.ui | 108 ++-- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 472 +++++++++++++----- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 21 + 7 files changed, 660 insertions(+), 206 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index e7467ff4f4dfea2b1c9ebee0c3fe6cfe9f4747c1..107449a221c864828f600a3dab7a9e0e36150549 100644 GIT binary patch delta 10342 zcmai4d309Q5$B04AuLI=k%W+hH4q?#MS_7wr0j$c79+AHEK)=aiR+SMacncl}5?Y)>00|6l8~hD2OacP*99O@4erf-@M0{bIO0ro0&VyZC8blx6#L?d@WPbA6I}n@w{yaKFYy2Oo@;1NJ6gZ`m0`p8Ejb$a7}J%Q z{Z2`cp&uv-v|RMC4k=H>`Tk|s8E93nreuemwu?$)_k|y;()qdl6GnYF1)bUV#j9qqoN>$|iub4~)ldaZ||F*a^qr$H1bp`D`Uw+r&tnPT~C8+?>V3Tw}o`^M1=kDbciuH z>`YJAH~6fNGw)04Nf)4P+6A8%TQ9I<1j&$6mbBw4oUoVn zVQ0(RI0xJ-?ZGaxwy76co5HP$o(W3}6_#lGVQHBC;3B(7*`pmjBQ8M?=jzBM&Xv;R zv!MIej0HmC-~XBoMZlsjvx|bZRhL-`uXaW{NPOuv!AY+Bwf{lzDKROk@T zyy+)?X=@oncBj5CmFDg(FLAMUOzCMC z-)>}Q{m_yHSV!RxtV8-|(vMsqHn*tlKXO~JSu*ktO9JExMXl9ZF_>X^7ik?Tj+vK!s=#G4^v;?Y5| z4zeqMj@D}2a~u^O&G|atnd)=#q9%6C zFZ`JXw{z@kuf7j4-=l2$C6R%^hM5+w4I8Rkc=oO)c3h>uU9&6MF4XRwN-j6a-^5>$ zKd#D?zxuQFxevC34+`$Jvpv6AuEF|Gv@xYJsCOA!3Hlb;z+#0Q1 zUy>DSUpmF1vANS9ddO+!Rf|xYeCu*n9^Euk~3&c()6I6u99}N zS%lr`44?>)57!otUF!{{1wbDFNgo8jMHtkw4h+IPp^bGUJ{+?efuI?`jd_X6ygACe zbrI3@Mj&#>&50@kEtCoeFt@Ip$g_dY*F^xirf5VxoQNzPss|UiDN<^Ei@T!uy05-4 zIvWQyZvdJ>pUDz6kO(?$mI8yI5!SpKU-&s#xyw$3Xt&PFfoLU zOA80hEY>FMMd4zd8@OE}09+(^PXyB8g`TY}NnRFBeH#LLQhwVT0#Z8mriD^Wq=a2J zeaertLX2l!l;^K2eGi8x(DA1{djfh%Vw4!?HhQ~@&b=cd+Rf`bJwF-%MEiUgT}3%e zZ6vnq5pF_utr0>dli1kaQQ7{cvc05pr2U`w0%>gwG9x|eYK-XA_YBi}6O`mOy42W; zqDBQCY?&i?pQE#ltw&cd8XYV4=uT)%(H&ujGNpKVBdUxQGxSh5(^VsEr=G5H?>DBH z0u^Y%vzgPz*OEAkw?OeAGaerB(n3e#y+#=6K25-Au2gXKUFy;F|GAplR9xj`7B!V* zswQDPZK)jji}G}8$A+|GsMk|t#qMT;d%b`dEA#^L9u+pT;wYoJg*}iv&%4b9>U=Mw z_!iO@K-?%q1S6oOD;VlFX6)2+f1k25IVqIhY6&}e{1_fRX7(GN2ntV-vS+iVCcrFR z3`VB8lKHDouf6?>pC=<*LBxBV{u|}AvLY!Y!3uG0p}6`|dTXzsIZWTfKURl*njA@2 zTBF+Gd0L`)ju3s6h`6Dbv~2_Jnr0xWGx>>zWMM)Ctr_B}eHj!nZABa7VqIIo#iL`p zSecun6t-xGcnZE3v=e;uzDxJpc>!ZkG(Sl=O~=9rsZ5eyhJ|2Bd$H27$ly+A_zRkz zY=zs&NS0Zv%_&ooaSD3*^<*)}oIJFH6=Ia7C}sbqiexL6)^xDi^EBegQ_%s*K!T=p z6q<^jQKJ!bgmOBmHhi^ibpoV~JBCAFL%wu4 z>_K^TDYvt5=~^^gx)w{A>y!QUsJt^$rD1NEw2}YyF@@2U^&W5_R7FpCLgnk%sa+&L z$Z>HOa6&pQ1vD97MJdw5Alja?O8PmA$*IVgShYJ9R%!Ebzy*CkV;ay6EzK0Psa-u|N>wqGua2aD zc0+_^7l`SOlQdq8P-`W0Nq3hH(e!cmDujZ6>k%?2&U4Xt-K-(E7+G*0K}DEUQ(=06QZqW!86{rdJT z-DjGIyY6(-OAqyw@sWuuE?<&*3;?chaVQj;TuO=6dyA+f_Y8Za19_7rWPRojm5 z7EQYbqiAt^yFXaGMo-Jll%B?qfOInx4N1~9b%-ln?u9c*ompNGO$qG*AvD*Vp`spV zmR3a^Jxn@YEepM7cMa7hZUNQZ}uah~-$f=Y&~);#VR*oGG_I`E7f3FEqE z2~h{cG+8~-q9`p(?TzQNq{-@1HDgLYqC{J2CdOxl&@*|SF(o_9?q`8*DgD?HLPY7? zE+R^!)^p(GHssq;oyS^SC|4a3B* z{Hlo77;t(v*;Wcd6+xk{O;(29^)Z5foh6eHeUC|`iZN>H<&8x`JVUXK?{h#lKI2kl zROpAswv?M=HKY7&83p=P+I;V%zPIyzZ;<2FfromUoMZ7bEVibbIf6x9um&M|g-+H8 zDd`bevbr!+ZVhMHrjP!dMfS3O(N*?7mydM5wTOy zlQC5Cr-*W1*zQk3Y|-OqzX(}lS$+LmK&(2juR_Aup|q`z)qxjA6+QDgPJQm@`y3P~ zpVcu2M|v~suW@v#IEpp}dN1%8%xN#7X5h$ymtc$zx52o6LQALZxmGBpHIN!WXt(4_ zX!+MUYA~&e9x#6zII*mhO+$jEF-@E<8Fs(ooSY73#5sKi;w%b^W{3iYT++-c7~h&H zjEuwJmq9cA%RoSP?-2?DC9kVH`pXCd%=qc$Dzs0U1x-NjX`#t}J>U-jh8dHd=i(sjcn#)xT{5j|)jTNjj3;ZpIO0zDY@yS^`Od(< zIUhquH6GVA%K9Td2zRlIh-E8rfxr`!j}{<>NNcTypqa5{JlD6|T&h@Tg_FHdpx`$A z`a*GtTT9L&xARh5GbnSh6>7J*>wY+vAvs{Nf7N`tSk$W|8mn{*oJEC8RN|{I_1@Lp zmhD~wQJK#1uiy-Guz|dGbB;nq{H74v`--4~3o77Mi4Ffr3C(>~AkU1~U5scyBbNe) zX4^78=#jmEa+a!*UAa`|DdyksWe6ehPs4O%8Rn}z-()VwRtOlEEQhr1{5($mR>+{l zes_3qLt48Dq5iRRxeDR7%}pqG6`*2j+%V`GU!fR^ zH%HRVmEKMbbJAWDb1IA; zdao8ChVItY5;-@R!t$Za_uxG%-?`)D712oMI}-(s{qnIv+yEUQQ&&rEr;B6wJ%(B#(Z}h z#eq@3#}=J@or~TeG#)^!Ho#FhUs(lh>PF#X8%sBejqdjTX9bD!>~MR>6<&@|7KdL) za!p(fjC6P3sbv0sB#QpgMv#l&X^Kc9>3Of)rGZp>IF4=*fTXkFtB5C*-nW(B8uB l;Uxxa^q)jGM|ho=X4L53yH|NtkR47Nb3_kkbir0D@qfDiwSxcv delta 10342 zcmai4d326v7WYz1#F9)lNkkGmvBj>KG&Ob+5t=F?vDBz)EH$>Vwbn)mFTKTR8IHEc zXywr9v?i^bcBW$-qZw)^R7*9ML`$nF=6Rm)y}$duzMM1ubKiUKbC=&;p6AOu2Wz}@ zutt8v8lAdy?bx}Ced%O)LHA)3UH{#`YvOw^@c;LnZ(vV9RWGIN94_rTm!=ZR^P-5%;mxJq6PC z%RbWLQ;_UX&5^u)s)r-FX^BG`eYz(rW68s(SrS}5&VXy*d7u8bg>>m;g#GADh%q?q zY#-J)?3|A?_iSH>MET)X>i`|6Rw_#M?Dc0O?Z)R?J}$8EoJXJz3j|fERmCm}3%5hh zvkWZEIqzrT1&}DNwd3yK3sAjej6?hEf?rhHUxc>l7kyrAyU30aBtuGA(vB;4!d}v! zoh@tQ9B{uRnO$UU(=M?#gC3carG95jmE<+FJ>gZ+8mD1z0 zp!e5|1w!KA|C$X&z@o3Pi-NY*S6G{f-oL`4Hm82lH~yl>zhP0F(C1sQ!H|M){j|kg z1sh?Q2%`xi#9Z2lKhu^Uzlr_7~B#DQ89g?i9+V>!_vRU6l z63DpxJ^M*z4Xg-CiLre3ky4t*_}Ev+$!l@xK*mSh4PO#dZlp4smbXiO@rfT3I>gg% z`iURC3GqW|&MB$4QXW6$*ezxQe$#FPzghhp$s@Pj2N<9xDxmhZkClblxjXCA?sis? zJ?=~xo4kFwBYC)ty~P13<$M4m-}H?y%25zOcN`$!84QD+>N0=k& zX=rEs(1Hb6N5K!QL;7d?AGttmZc#gaaGI`cLeo^am8o1` znh|PWKFy)Axzith#A)VMvnk199D%eKBt{!WTS9Y`(Q3ivY6;-rE0KVfkmcpOoa>K5|A zZfvS9vQ8JJz#4Fuxbx7w8Wy)6Q}DV~&|M*N{Afl^NP7ZPQd3TH2CYe&9<(!5(vCHa zusfdx6yfoaTH>*5y`iK4=mQ|>g8;Y)gId&vL6|4BskX$2V^%#7G~>51FF~0%SDCjy zBAVU^MDDmbQF)++QsDsR)R7Z;HqeDS2q4!KjjD?ik)^|R;Q}{B>RHd?t|-3luP2Po z#zD>MgJ#fYvPAVIf=-*Iz#wRZHLnJFtTFC4R_-s;CDlEI>IGZ=>6sJ^<-X>5F5fp_ z=}fSd?uYbozY%sF8gq!A8>@7T(;L!@p;oXx{ku?Z1I`ej)DVfYv*FRv5DWcW@flrh zm9AW+t2n(8O$)WS37D2^7}_a@HHsm4L@eD1g-1G}P>`p-mke)2Q^KGC2`>s0L)f^a zaL~+RZNgp{F4nn$+bsgXMS}N6ARS)l*~*f{<4T6|rK59_nVgYJ~05(>3n>Mii5; z0xftpbK3Y?9B1(sC?2H6!vkJg=xDsx2qWFUF&NF23a-9O$xZ&Bt38{DtDMZjCX!6m zB#fsmlp}vpo=)r3fL5k^JvCPBX)3ta3y85oFCgzxK~pP^Qkz-W1G)3O+f1O&_cDra zE^PtCO+rL40$R9&p>AWwPCfVcD?1b0htgXuU?-0s!=uN{0mBnP;Vq@?*{o?TVU{ii zBhyUD{MDz|-f`8>lhLgp;=NA)jj~%=krdL>3UO_rxcX8`Yp9>7)e)K zquSwlQi6Dn5Pg(@xS^M{Z3FF^W+16E`H6;PLCXkQJKR(IGALr&iZ;f@`nH0L$H#V& zGB;Z(Y~Bv>6nrmiC-~-lmmak90>+?dL3`me9Sb9*qP_GoECfqCh?R~-26sBcU(k$1 zE8I>*vdmg-PMMmBQ_#yx6U7{Ja(YKA#3<{ol>M8^6RlWU+tKR4(}*Wec}FAz37XnT zXexR}jYiN>%I>V%@U?EL`N+)-=^EV`=`x$F$(Kg-F`cjC10i&~Gazl;F&z3D@}?Zj^ zj*Gg16VgfDL6h-S*j;)UqnkFt%;<6 z_CkbZ7l`SNlQdq8P-`W0S$CI?(e!ceN`!)c>k%?2&UMjv-K;LR7+G*ES+7K4^={ze9__n;m`NB7(D3UvOdv+SXTEo;z7TDl^uujiT25y=w&S zNO}DL9q&N6M@t7-(OOXMer|04zlEnp+#4SChf=hf1p|N#*&Xf<0HcIw#y|-V zI_UL*{!V8O5~mqh#|KGv`I3}87`Vd4p+IPIJ&7NJO;Av25Am0-mLfFuJV2Q#&IMvt zisgO{ptfV259d;>ZhW%Kt8DcV4*mL1@V3>G~o|cm)J&hj$>1G-llB8?ea96tA3ullzvn)TFT6O@0&|I_AMLo_e zsf?I8LOAt|FfHZW2r-18eQESaNeZt>M@EWqp7lC{ibtx}JpLKjh8He6_>3G0<9cKW zQ3u2{Sv}FBC@DkjjTbVc$?8%yV@f}wL|bYm#%F}kGr68IB|FTXXMt@g{n$}LMCscu zB1)s?bKvAQB?-(Fi{EEzkVd7U_ zWkhQ%I6a$eD+QtQpitK)D?_hztl(c~$s|PIV-l!*teSecTl@@*t?6dAU{M#WL5NlK*4V{pH2dLZ0G%x5}!xQ6XDIzi!dW9V6xCy;k?PBkk|Lp$-pgoRQB&Ze8w%k z112fAZfy*=C)~lS35sRl6o5($E1V)maFb~Jf;YlOyG~3WrM;+e1bzMj@`5!Yb}D)@ zhDzR4QO*n7gQ*|jFGQt2eetNkQ?UQFi6VQ7`XtG}q{sVwvhN%g>-pa>P z;#_qLzw}ux`(7EpULttC=SVyhfQ^*CDrae_2>Nmkpen60VXmazz4DG%&XuQz(dTo~ z6ws|==6Q?49Hfh4BCVURCg*{9I0!pl{rO&(OsiTwABsHV$yy+exD!4{=yYg-Gw^RN zz|c{R$2E;I{)i94UF0HS*-BU_@WkY!g-9XNT5}O-W^5VH_3bu?$`@JTWG@mZxD78| zBo1+F$zJSsUW#ibr7f{S?dJE~563bj2QTrjnopOAdX+?Dm2QEvsbHx}e6?lXySm%5 zJxd`f(>eYXoM8?&kk@X`Rj7#H976kE5mazN1-vS;;Xf&%d9MoOnX%Nxi1ssj8E|N} zE#re8*$XLqnHt#@%VeHn{*7FY5EB11Oh=bvzRL4W+6ruifN}8(NZZcO<1}!k3`*>G zM^?&y=Xn=gM#U@DewVXKY{Tv8@G3Z@wVM#?A3Im55N_Ynm~vJFDyGH_gRb$FilJyr zB;8!)?bI+Q=`}G2bGq;~)EAeM(Wsx1UQ-&A2Sw;D)30aj%|-rotzuxT(F5c5zoMw$ z8WCdXZd)UfbAu@?56XNG-m~+ZJ5Fw%HHz;zusLEaY?g+!el6lA#JcN1MCV++4$zX$ zS+P!3A{DdqA?-5@FLLGit`{HYkC|xBdUOL!!Yk`#67n*VwgKL9$W2%K!bNAy_qI_S z81;K?(aG1j=#4_-0knD}9EI~0mC&Yb5Sz8g37wA^de+AyI3o!SB~ kF<_(rB)U1m>%BCiM)%%*%B%dWaN3kDdN`vCw^<4Q1J0m482|tP diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index 3f74cdab1..0a89281ac 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1570,6 +1570,9 @@ bool startsWith(const char* pre, const char* str) #define x87SW_PRE_FIELD_STRING "x87SW_" #define x87CW_PRE_FIELD_STRING "x87CW_" #define x87TW_PRE_FIELD_STRING "x87TW_" +#define MMX_PRE_FIELD_STRING "MM" +#define XMM_PRE_FIELD_STRING "XMM" +#define x8780BITFPU_PRE_FIELD_STRING "x87r" #define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1) @@ -1585,13 +1588,26 @@ void fpustuff(const char* string, uint value) if(startsWith(MxCsr_PRE_FIELD_STRING, string)) { - uint flags = GetContextDataEx(hActiveThread, UE_MXCSR); - flag = getmxcsrflagfromstring(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING)); - if(flags & flag and !set) - xorval = flag; - else if(set) - xorval = flag; - SetContextDataEx(hActiveThread, UE_MXCSR, flags ^ xorval); + if(StrNCmpI(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING), "RC", strlen("RC")) == 0) + { + uint flags = GetContextDataEx(hActiveThread, UE_MXCSR); + int i = 3; + i <<= 13; + flags &= ~i; + value <<= 13; + flags |= value; + SetContextDataEx(hActiveThread, UE_MXCSR, flags); + } + else + { + uint flags = GetContextDataEx(hActiveThread, UE_MXCSR); + flag = getmxcsrflagfromstring(string + STRLEN_USING_SIZEOF(MxCsr_PRE_FIELD_STRING)); + if(flags & flag and !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_MXCSR, flags ^ xorval); + } } else if(startsWith(x87TW_PRE_FIELD_STRING, string)) { @@ -1605,7 +1621,7 @@ void fpustuff(const char* string, uint value) flags = GetContextDataEx(hActiveThread, UE_X87_TAGWORD); - flag = 7; + flag = 3; flag <<= i * 2; flags &= ~flag; @@ -1643,13 +1659,36 @@ void fpustuff(const char* string, uint value) } else if(startsWith(x87CW_PRE_FIELD_STRING, string)) { - uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); - flag = getx87controlwordflagfromstring(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING)); - if(flags & flag and !set) - xorval = flag; - else if(set) - xorval = flag; - SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags ^ xorval); + if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "RC", strlen("RC")) == 0) + { + uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + int i = 3; + i <<= 10; + flags &= ~i; + value <<= 10; + flags |= value; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags); + } + else if(StrNCmpI(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING), "PC", strlen("PC")) == 0) + { + uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + int i = 3; + i <<= 8; + flags &= ~i; + value <<= 8; + flags |= value; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags); + } + else + { + uint flags = GetContextDataEx(hActiveThread, UE_X87_CONTROLWORD); + flag = getx87controlwordflagfromstring(string + STRLEN_USING_SIZEOF(x87CW_PRE_FIELD_STRING)); + if(flags & flag and !set) + xorval = flag; + else if(set) + xorval = flag; + SetContextDataEx(hActiveThread, UE_X87_CONTROLWORD, flags ^ xorval); + } } else if(StrNCmpI(string, "x87TagWord", strlen(string)) == 0) { @@ -1667,6 +1706,176 @@ void fpustuff(const char* string, uint value) { SetContextDataEx(hActiveThread, UE_MXCSR, value); } + else if(startsWith(x8780BITFPU_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(x8780BITFPU_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(*string) + { + case '0': + registerindex = UE_x87_r0; + break; + + case '1': + registerindex = UE_x87_r1; + break; + + case '2': + registerindex = UE_x87_r2; + break; + + case '3': + registerindex = UE_x87_r3; + break; + + case '4': + registerindex = UE_x87_r4; + break; + + case '5': + registerindex = UE_x87_r5; + break; + + case '6': + registerindex = UE_x87_r6; + break; + + case '7': + registerindex = UE_x87_r7; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } + else if(startsWith(MMX_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(MMX_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(*string) + { + case '0': + registerindex = UE_MMX0; + break; + + case '1': + registerindex = UE_MMX1; + break; + + case '2': + registerindex = UE_MMX2; + break; + + case '3': + registerindex = UE_MMX3; + break; + + case '4': + registerindex = UE_MMX4; + break; + + case '5': + registerindex = UE_MMX5; + break; + + case '6': + registerindex = UE_MMX6; + break; + + case '7': + registerindex = UE_MMX7; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } + else if(startsWith(XMM_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(XMM_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(*string) + { + case '0': + registerindex = UE_XMM0; + break; + + case '1': + registerindex = UE_XMM1; + break; + + case '2': + registerindex = UE_XMM2; + break; + + case '3': + registerindex = UE_XMM3; + break; + + case '4': + registerindex = UE_XMM4; + break; + + case '5': + registerindex = UE_XMM5; + break; + + case '6': + registerindex = UE_XMM6; + break; + + case '7': + registerindex = UE_XMM7; + break; + + case '8': + registerindex = UE_XMM8; + break; + + case '9': + registerindex = UE_XMM9; + break; + + case '10': + registerindex = UE_XMM10; + break; + + case '11': + registerindex = UE_XMM11; + break; + + case '12': + registerindex = UE_XMM12; + break; + + case '13': + registerindex = UE_XMM13; + break; + + case '14': + registerindex = UE_XMM14; + break; + + case '15': + registerindex = UE_XMM15; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } } bool valtostring(const char* string, uint* value, bool silent) diff --git a/x64_dbg_gui/Project/Src/Gui/LineEditDialog.cpp b/x64_dbg_gui/Project/Src/Gui/LineEditDialog.cpp index 93b99d76a..ac2dda4d7 100644 --- a/x64_dbg_gui/Project/Src/Gui/LineEditDialog.cpp +++ b/x64_dbg_gui/Project/Src/Gui/LineEditDialog.cpp @@ -12,6 +12,7 @@ LineEditDialog::LineEditDialog(QWidget* parent) : QDialog(parent), ui(new Ui::Li setModal(true); //modal window ui->checkBox->hide(); bChecked = false; + this->fixed_size = 0; } LineEditDialog::~LineEditDialog() @@ -24,6 +25,12 @@ void LineEditDialog::setCursorPosition(int position) ui->textEdit->setCursorPosition(position); } +void LineEditDialog::ForceSize(unsigned int size) +{ + this->fixed_size = size; + +} + void LineEditDialog::setText(const QString & text) { ui->textEdit->setText(text); @@ -52,6 +59,23 @@ void LineEditDialog::setCheckBoxText(const QString & text) void LineEditDialog::on_textEdit_textChanged(const QString & arg1) { editText = arg1; + if(this->fixed_size != 0) + { + if(arg1.size() != this->fixed_size) + { + ui->buttonOk->setEnabled(false); + QString symbolct = ""; + int ct = arg1.size() - (int) this->fixed_size; + if(ct > 0) + symbolct = "+"; + ui->label->setText(QString("") + QString("CT: ") + symbolct + QString::number(ct) + QString("")); + } + else + { + ui->buttonOk->setEnabled(true); + ui->label->setText(QString("")); + } + } } void LineEditDialog::on_checkBox_toggled(bool checked) diff --git a/x64_dbg_gui/Project/Src/Gui/LineEditDialog.h b/x64_dbg_gui/Project/Src/Gui/LineEditDialog.h index 9fcb51438..738d718d5 100644 --- a/x64_dbg_gui/Project/Src/Gui/LineEditDialog.h +++ b/x64_dbg_gui/Project/Src/Gui/LineEditDialog.h @@ -22,6 +22,7 @@ public: void setCheckBox(bool bSet); void setCheckBoxText(const QString & text); void setCursorPosition(int position); + void ForceSize(unsigned int size); private slots: void on_textEdit_textChanged(const QString & arg1); @@ -29,6 +30,7 @@ private slots: private: Ui::LineEditDialog* ui; + unsigned int fixed_size; }; #endif // LINEEDITDIALOG_H diff --git a/x64_dbg_gui/Project/Src/Gui/LineEditDialog.ui b/x64_dbg_gui/Project/Src/Gui/LineEditDialog.ui index f9655f8f5..e34c2e396 100644 --- a/x64_dbg_gui/Project/Src/Gui/LineEditDialog.ui +++ b/x64_dbg_gui/Project/Src/Gui/LineEditDialog.ui @@ -6,7 +6,7 @@ 0 0 - 373 + 414 72 @@ -17,62 +17,56 @@ :/icons/images/ui-combo-box-edit.png:/icons/images/ui-combo-box-edit.png - - - - 10 - 10 - 351 - 53 - - - - - - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - CheckBox - - - - - - - &OK - - - true - - - - - - - &Cancel - - - - - - - + + + + + + + + + + + + + 40 + 20 + + + + + + + + + + + CheckBox + + + + + + + &OK + + + true + + + + + + + &Cancel + + + + + + + + diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 711f0878f..57937f2ac 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -5,6 +5,7 @@ #include "LineEditDialog.h" #include "SelectFields.h" #include +#include RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) @@ -36,6 +37,8 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff wCM_FollowInDisassembly = new QAction(tr("Follow in Disassembler"), this); wCM_FollowInDump = new QAction(tr("Follow in Dump"), this); wCM_FollowInStack = new QAction("Follow in Stack", this); + wCM_Incrementx87Stack = new QAction(tr("Increment x87 Stack"), this); + wCM_Decrementx87Stack = new QAction("Decrement x87 Stack", this); // general purposes register (we allow the user to modify the value) mGPR.insert(CAX); @@ -350,6 +353,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFPUx87.insert(x87CW_RC); mFIELDVALUE.insert(x87CW_RC); mFPU.insert(x87CW_RC); + mMODIFYDISPLAY.insert(x87CW_RC); mFPUx87.insert(x87TW_0); mFIELDVALUE.insert(x87TW_0); @@ -402,6 +406,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFPUx87.insert(x87CW_PC); mFIELDVALUE.insert(x87CW_PC); mFPU.insert(x87CW_PC); + mMODIFYDISPLAY.insert(x87CW_PC); mSETONEZEROTOGGLE.insert(x87CW_IEM); mFPUx87.insert(x87CW_IEM); @@ -496,6 +501,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFIELDVALUE.insert(MxCsr_RC); mFPU.insert(MxCsr_RC); + mMODIFYDISPLAY.insert(MxCsr_RC); mMODIFYDISPLAY.insert(MM0); mFPUMMX.insert(MM0); @@ -824,7 +830,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(x87SW_I, "x87SW_I"); mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); - mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 6)); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 12)); offset++; @@ -893,7 +899,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 13)); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 18)); offset++; @@ -990,6 +996,8 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff // context menu actions connect(wCM_Increment, SIGNAL(triggered()), this, SLOT(onIncrementAction())); connect(wCM_Decrement, SIGNAL(triggered()), this, SLOT(onDecrementAction())); + connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction())); + connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction())); connect(wCM_Zero, SIGNAL(triggered()), this, SLOT(onZeroAction())); connect(wCM_SetToOne, SIGNAL(triggered()), this, SLOT(onSetToOneAction())); connect(wCM_Modify, SIGNAL(triggered()), this, SLOT(onModifyAction())); @@ -1283,93 +1291,29 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); valueText += QString("("); -#define MxCsr_RC_NEAR 0 -#define MxCsr_RC_NEGATIVE 1 -#define MxCsr_RC_POSITIVE 2 -#define MxCsr_RC_TOZERO 3 - switch((* ((unsigned short*) value))) - { - case MxCsr_RC_NEAR: - valueText += "round near"; - break; - - case MxCsr_RC_NEGATIVE: - valueText += "toward negative"; - break; - - case MxCsr_RC_POSITIVE: - valueText += "toward positive"; - break; - - case MxCsr_RC_TOZERO: - valueText += "toward zero"; - break; - } - + valueText += GetMxCsrRCStateString((* ((unsigned short*) value))); valueText += QString(")"); } else if(reg == x87CW_RC) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); valueText += QString("("); -#define x87CW_RC_NEAR 0 -#define x87CW_RC_DOWN 1 -#define x87CW_RC_UP 2 -#define x87CW_RC_TRUNCATE 3 - switch((* ((unsigned short*) value))) - { - case x87CW_RC_NEAR: - valueText += "round near"; - break; - - case x87CW_RC_DOWN: - valueText += "round down"; - break; - - case x87CW_RC_UP: - valueText += "round up"; - break; - - case x87CW_RC_TRUNCATE: - valueText += "truncate"; - break; - } - + valueText += GetControlWordRCStateString((* ((unsigned short*) value))); valueText += QString(")"); } else if(reg == x87CW_PC) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); valueText += QString("("); -#define x87CW_PC_REAL4 0 -#define x87CW_PC_NOTUSED 1 -#define x87CW_PC_REAL8 2 -#define x87CW_PC_REAL10 3 - switch((* ((unsigned short*) value))) - { - case x87CW_PC_REAL4: - valueText += "real4"; - break; - - case x87CW_PC_NOTUSED: - valueText += "not used"; - break; - - case x87CW_PC_REAL8: - valueText += "real8"; - break; - - case x87CW_PC_REAL10: - valueText += "real10"; - break; - } - + valueText += GetControlWordPCStateString((* ((unsigned short*) value))); valueText += QString(")"); } else if(reg == x87SW_TOP) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString("(ST") + valueText + QString(")"); + valueText += QString("(ST0="); + valueText += GetStatusWordTOPStateString((* ((unsigned short*) value))); + valueText += QString(")"); } } else @@ -1384,17 +1328,179 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value return valueText; } +#define MxCsr_RC_NEAR 0 +#define MxCsr_RC_NEGATIVE 1 +#define MxCsr_RC_POSITIVE 2 +#define MxCsr_RC_TOZERO 3 + +STRING_VALUE_TABLE_t MxCsrRCValueStringTable[] = +{ + {"toward zero", MxCsr_RC_TOZERO}, + {"toward positive", MxCsr_RC_POSITIVE}, + {"toward negative", MxCsr_RC_NEGATIVE}, + {"round near", MxCsr_RC_NEAR} +}; + +unsigned int RegistersView::GetMxCsrRCValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(MxCsrRCValueStringTable) / sizeof(*MxCsrRCValueStringTable)); i++) + { + if(MxCsrRCValueStringTable[i].string == string) + return MxCsrRCValueStringTable[i].value; + } + + return i; +} + +QString RegistersView::GetMxCsrRCStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(MxCsrRCValueStringTable) / sizeof(*MxCsrRCValueStringTable)); i++) + { + if(MxCsrRCValueStringTable[i].value == state) + return MxCsrRCValueStringTable[i].string; + } + + return "unknown"; +} + +#define x87CW_RC_NEAR 0 +#define x87CW_RC_DOWN 1 +#define x87CW_RC_UP 2 +#define x87CW_RC_TRUNCATE 3 + +STRING_VALUE_TABLE_t ControlWordRCValueStringTable[] = +{ + {"truncate", x87CW_RC_TRUNCATE}, + {"round up", x87CW_RC_UP}, + {"round down", x87CW_RC_DOWN}, + {"round near", x87CW_RC_NEAR} +}; + +unsigned int RegistersView::GetControlWordRCValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordRCValueStringTable) / sizeof(*ControlWordRCValueStringTable)); i++) + { + if(ControlWordRCValueStringTable[i].string == string) + return ControlWordRCValueStringTable[i].value; + } + + return i; +} + +QString RegistersView::GetControlWordRCStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordRCValueStringTable) / sizeof(*ControlWordRCValueStringTable)); i++) + { + if(ControlWordRCValueStringTable[i].value == state) + return ControlWordRCValueStringTable[i].string; + } + + return "unknown"; +} + +#define x87SW_TOP_0 0 +#define x87SW_TOP_1 1 +#define x87SW_TOP_2 2 +#define x87SW_TOP_3 3 +#define x87SW_TOP_4 4 +#define x87SW_TOP_5 5 +#define x87SW_TOP_6 6 +#define x87SW_TOP_7 7 + +STRING_VALUE_TABLE_t StatusWordTOPValueStringTable[] = +{ + {"x87r0", x87SW_TOP_0}, + {"x87r1", x87SW_TOP_1}, + {"x87r2", x87SW_TOP_2}, + {"x87r3", x87SW_TOP_3}, + {"x87r4", x87SW_TOP_4}, + {"x87r5", x87SW_TOP_5}, + {"x87r6", x87SW_TOP_6}, + {"x87r7", x87SW_TOP_7} +}; + +unsigned int RegistersView::GetStatusWordTOPValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(StatusWordTOPValueStringTable) / sizeof(*StatusWordTOPValueStringTable)); i++) + { + if(StatusWordTOPValueStringTable[i].string == string) + return StatusWordTOPValueStringTable[i].value; + } + + return i; +} + +QString RegistersView::GetStatusWordTOPStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(StatusWordTOPValueStringTable) / sizeof(*StatusWordTOPValueStringTable)); i++) + { + if(StatusWordTOPValueStringTable[i].value == state) + return StatusWordTOPValueStringTable[i].string; + } + + return "unknown"; +} + + +#define x87CW_PC_REAL4 0 +#define x87CW_PC_NOTUSED 1 +#define x87CW_PC_REAL8 2 +#define x87CW_PC_REAL10 3 + +STRING_VALUE_TABLE_t ControlWordPCValueStringTable[] = +{ + {"real4", x87CW_PC_REAL4}, + {"not used", x87CW_PC_NOTUSED}, + {"real8", x87CW_PC_REAL8}, + {"real10", x87CW_PC_REAL10} +}; + + +unsigned int RegistersView::GetControlWordPCValueFromString(QString string) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordPCValueStringTable) / sizeof(*ControlWordPCValueStringTable)); i++) + { + if(ControlWordPCValueStringTable[i].string == string) + return ControlWordPCValueStringTable[i].value; + } + + return i; +} + + +QString RegistersView::GetControlWordPCStateString(unsigned short state) +{ + int i; + + for(i = 0; i < (sizeof(ControlWordPCValueStringTable) / sizeof(*ControlWordPCValueStringTable)); i++) + { + if(ControlWordPCValueStringTable[i].value == state) + return ControlWordPCValueStringTable[i].string; + } + + return "unknown"; +} + + #define X87FPU_TAGWORD_NONZERO 0 #define X87FPU_TAGWORD_ZERO 1 #define X87FPU_TAGWORD_SPECIAL 2 #define X87FPU_TAGWORD_EMPTY 3 -typedef struct -{ - QString string; - unsigned int value; -} STRING_VALUE_TABLE_t; - STRING_VALUE_TABLE_t TagWordValueStringTable[] = { {"nonzero", X87FPU_TAGWORD_NONZERO}, @@ -1481,15 +1587,71 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) if(mFPUx87_80BITSDISPLAY.contains(reg) && DbgIsDebugging()) { + p->setPen(ConfigColor("RegistersExtraInfoColor")); x += 1 * mCharWidth; //1 space QString newText; + if(mRegisterUpdates.contains(x87SW_TOP)) + p->setPen(ConfigColor("RegistersModifiedColor")); + newText = QString("ST%1 ").arg(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->st_value); + width = newText.length() * mCharWidth; + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + + x += width; + + newText = QString(""); + + p->setPen(ConfigColor("RegistersExtraInfoColor")); + + if(reg == x87r0 && mRegisterUpdates.contains(x87TW_0)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r1 && mRegisterUpdates.contains(x87TW_1)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r2 && mRegisterUpdates.contains(x87TW_2)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r3 && mRegisterUpdates.contains(x87TW_3)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r4 && mRegisterUpdates.contains(x87TW_4)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r5 && mRegisterUpdates.contains(x87TW_5)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r6 && mRegisterUpdates.contains(x87TW_6)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } + else if(reg == x87r7 && mRegisterUpdates.contains(x87TW_7)) + { + p->setPen(ConfigColor("RegistersModifiedColor")); + } newText += GetTagWordStateString(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->tag) + QString(" "); + width = newText.length() * mCharWidth; + p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); + + x += width; + + newText = QString(""); + + p->setPen(ConfigColor("RegistersExtraInfoColor")); + + if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) + p->setPen(ConfigColor("RegistersModifiedColor")); + newText += QString::number(readFloat80(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); width = newText.length() * mCharWidth; - p->setPen(ConfigColor("RegistersExtraInfoColor")); p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); } @@ -1522,54 +1684,57 @@ void RegistersView::updateRegistersSlot() setRegisters(&z); } +void RegistersView::ModifyFields(QString title, STRING_VALUE_TABLE_t* table, SIZE_T size) +{ + SelectFields mSelectFields(this); + QListWidget* mQListWidget = mSelectFields.GetList(); + + QStringList items; + unsigned int i; + + for(i = 0; i < size; i++) + items << table[i].string; + + mQListWidget->addItems(items); + + mSelectFields.setWindowTitle(title); + if(mSelectFields.exec() != QDialog::Accepted) + return; + + if(mQListWidget->selectedItems().count() != 1) + return; + + QListWidgetItem* item = mQListWidget->takeItem(mQListWidget->currentRow()); + + uint_t value; + + for(i = 0; i < size; i++) + { + if(table[i].string == item->text()) + break; + } + + value = table[i].value; + + setRegister(mSelected, (uint_t)value); +} + +#define MODIFY_FIELDS_DISPLAY(title, table) ModifyFields(QString("Edit ") + QString(title), (STRING_VALUE_TABLE_t *) & table, SIZE_TABLE(table) ) + void RegistersView::displayEditDialog() { if(mFPU.contains(mSelected)) { if(mTAGWORD.contains(mSelected)) - { - SelectFields mSelectFields(this); - QListWidget* mQListWidget = mSelectFields.GetList(); - - QStringList items; - items << GetTagWordStateString(X87FPU_TAGWORD_EMPTY) << GetTagWordStateString(X87FPU_TAGWORD_NONZERO) - << GetTagWordStateString(X87FPU_TAGWORD_SPECIAL) << GetTagWordStateString(X87FPU_TAGWORD_ZERO); - - mQListWidget->addItems(items); - - mSelectFields.setWindowTitle("Edit TAG"); - if(mSelectFields.exec() != QDialog::Accepted) - return; - - if(mQListWidget->selectedItems().count() != 1) - return; - - QListWidgetItem* item = mQListWidget->takeItem(mQListWidget->currentRow()); - - uint_t value = GetTagWordValueFromString(item->text()); - setRegister(mSelected, (uint_t)value); - } + MODIFY_FIELDS_DISPLAY("Tag " + mRegisterMapping.constFind(mSelected).value(), TagWordValueStringTable); + else if(mSelected == MxCsr_RC) + MODIFY_FIELDS_DISPLAY("MxCsr_RC", MxCsrRCValueStringTable); + else if(mSelected == x87CW_RC) + MODIFY_FIELDS_DISPLAY("x87CW_RC", ControlWordRCValueStringTable); + else if(mSelected == x87CW_PC) + MODIFY_FIELDS_DISPLAY("x87CW_PC", ControlWordPCValueStringTable); else if(mSelected == x87SW_TOP) - { - SelectFields mSelectFields(this); - QListWidget* mQListWidget = mSelectFields.GetList(); - - QStringList items; - items << "ST0" << "ST1" << "ST2" << "ST3" << "ST4" - << "ST5" << "ST6" << "ST7"; - - mQListWidget->addItems(items); - - mSelectFields.setWindowTitle("Edit x87SW_TOP"); - if(mSelectFields.exec() != QDialog::Accepted) - return; - - if(mQListWidget->selectedItems().count() != 1) - return; - - uint_t value = mQListWidget->currentRow(); - setRegister(mSelected, (uint_t)value); - } + MODIFY_FIELDS_DISPLAY("x87SW_TOP ST0=", StatusWordTOPValueStringTable); else { bool errorinput = false; @@ -1579,24 +1744,12 @@ void RegistersView::displayEditDialog() mLineEdit.setWindowTitle("Edit FPU register"); mLineEdit.setWindowIcon(QIcon(":/icons/images/log.png")); mLineEdit.setCursorPosition(0); - + mLineEdit.ForceSize(GetSizeRegister(mSelected) * 2); do { errorinput = false; if(mLineEdit.exec() != QDialog::Accepted) return; //pressed cancel - - if(mLineEdit.editText.size() != GetSizeRegister(mSelected) * 2) - { - mLineEdit.setCursorPosition(GetSizeRegister(mSelected) * 2); - errorinput = true; - - QMessageBox msg(QMessageBox::Warning, "ERROR SIZE INPUT", "ERROR SIZE INPUT MUST BE: " + QString::number(GetSizeRegister(mSelected) * 2)); - msg.setWindowIcon(QIcon(":/icons/images/compile-warning.png")); - msg.setParent(this, Qt::Dialog); - msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); - msg.exec(); - } else { bool ok = false; @@ -1606,7 +1759,40 @@ void RegistersView::displayEditDialog() fpuvalue = (uint_t) mLineEdit.editText.toUShort(&ok, 16); else if(mDWORDDISPLAY.contains(mSelected)) fpuvalue = mLineEdit.editText.toUInt(&ok, 16); + else if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) + { + QByteArray pArray = mLineEdit.editText.toLocal8Bit(); + if(pArray.size() == GetSizeRegister(mSelected) * 2) + { + char* pData = (char*) calloc(1, sizeof(char) * GetSizeRegister(mSelected)); + if(pData != NULL) + { + ok = true; + char actual_char[3]; + unsigned int i; + for(i = 0; i < GetSizeRegister(mSelected); i++) + { + memset(actual_char, 0, sizeof(actual_char)); + memcpy(actual_char, (char*) pArray.data() + (i * 2), 2); + if(! isxdigit(actual_char[0]) || ! isxdigit(actual_char[1])) + { + ok = false; + break; + } + pData[i] = (char)strtol(actual_char, NULL, 16); + } + + if(ok) + setRegister(mSelected, (uint_t) pData); + + free(pData); + + if(ok) + return; + } + } + } if(!ok) { errorinput = true; @@ -1634,6 +1820,18 @@ void RegistersView::displayEditDialog() } } +void RegistersView::onIncrementx87StackAction() +{ + if(mFPUx87_80BITSDISPLAY.contains(mSelected)) + setRegister(x87SW_TOP, ((* ((uint_t*) registerValue(&wRegDumpStruct, x87SW_TOP))) + 1) % 7); +} + +void RegistersView::onDecrementx87StackAction() +{ + if(mFPUx87_80BITSDISPLAY.contains(mSelected)) + setRegister(x87SW_TOP, ((* ((uint_t*) registerValue(&wRegDumpStruct, x87SW_TOP))) - 1) % 7); +} + void RegistersView::onIncrementAction() { if(mINCREMENTDECREMET.contains(mSelected)) @@ -1751,6 +1949,12 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) wMenu.addAction(wCM_ToggleValue); } + if(mFPUx87_80BITSDISPLAY.contains(mSelected)) + { + wMenu.addAction(wCM_Incrementx87Stack); + wMenu.addAction(wCM_Decrementx87Stack); + } + if(mINCREMENTDECREMET.contains(mSelected)) { wMenu.addAction(wCM_Increment); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 0a5ac980e..17541f678 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -8,6 +8,14 @@ #define IsCharacterRegister(x) ((x>=CAX && x Date: Sun, 2 Nov 2014 01:30:29 +0100 Subject: [PATCH 12/58] finish FPU support --- x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 102168 -> 102168 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 105896 bytes x64_dbg_dbg/value.cpp | 58 +- x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp | 1 + x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 703 +++++++++--------- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 5 + 6 files changed, 403 insertions(+), 364 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib index b7a81d99962623477a595fe65064a804d678c1e9..86d6859de3a24da5d313a79294866754fa4bddc5 100644 GIT binary patch delta 10618 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 F{{y(V^k4u0 delta 10618 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 F{{c3(B7gt@ diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index 107449a221c864828f600a3dab7a9e0e36150549..e488efd599c661b3f74bdf2e7a179c8164f08a0e 100644 GIT binary patch delta 9559 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 HGot2o01TnkkwYk@+YejH04f*=g3$ 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 mGeneralRegs->setFixedHeight(1200); + mGeneralRegs->ShowFPU(true); QScrollArea* scrollArea = new QScrollArea; scrollArea->setWidget(mGeneralRegs); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 57937f2ac..36bae7576 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -7,6 +7,353 @@ #include #include +void RegistersView::InitMappings() +{ + // create mapping from internal id to name + mRegisterMapping.clear(); + mRegisterPlaces.clear(); + int offset = 0; + + /* Register_Position is a struct definition the position + * + * (line , start, labelwidth, valuesize ) + */ +#ifdef _WIN64 + mRegisterMapping.insert(CAX, "RAX"); + mRegisterPlaces.insert(CAX, Register_Position(0, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CBX, "RBX"); + mRegisterPlaces.insert(CBX, Register_Position(1, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CCX, "RCX"); + mRegisterPlaces.insert(CCX, Register_Position(2, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDX, "RDX"); + mRegisterPlaces.insert(CDX, Register_Position(3, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSI, "RSI"); + mRegisterPlaces.insert(CSI, Register_Position(6, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDI, "RDI"); + mRegisterPlaces.insert(CDI, Register_Position(7, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CBP, "RBP"); + mRegisterPlaces.insert(CBP, Register_Position(4, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSP, "RSP"); + mRegisterPlaces.insert(CSP, Register_Position(5, 0, 6, sizeof(uint_t) * 2)); + + mRegisterMapping.insert(R8, "R8"); + mRegisterPlaces.insert(R8 , Register_Position(9, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R9, "R9"); + mRegisterPlaces.insert(R9 , Register_Position(10, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R10, "R10"); + mRegisterPlaces.insert(R10, Register_Position(11, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R11, "R11"); + mRegisterPlaces.insert(R11, Register_Position(12, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R12, "R12"); + mRegisterPlaces.insert(R12, Register_Position(13, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R13, "R13"); + mRegisterPlaces.insert(R13, Register_Position(14, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R14, "R14"); + mRegisterPlaces.insert(R14, Register_Position(15, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R15, "R15"); + mRegisterPlaces.insert(R15, Register_Position(16, 0, 6, sizeof(uint_t) * 2)); + + mRegisterMapping.insert(CIP, "RIP"); + mRegisterPlaces.insert(CIP, Register_Position(18, 0, 6, sizeof(uint_t) * 2)); + + mRegisterMapping.insert(EFLAGS, "RFLAGS"); + mRegisterPlaces.insert(EFLAGS, Register_Position(20, 0, 9, sizeof(uint_t) * 2)); + + offset = 21; +#else + mRegisterMapping.insert(CAX, "EAX"); + mRegisterPlaces.insert(CAX, Register_Position(0, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CBX, "EBX"); + mRegisterPlaces.insert(CBX, Register_Position(1, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CCX, "ECX"); + mRegisterPlaces.insert(CCX, Register_Position(2, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDX, "EDX"); + mRegisterPlaces.insert(CDX, Register_Position(3, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSI, "ESI"); + mRegisterPlaces.insert(CSI, Register_Position(6, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDI, "EDI"); + mRegisterPlaces.insert(CDI, Register_Position(7, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CBP, "EBP"); + mRegisterPlaces.insert(CBP, Register_Position(4, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSP, "ESP"); + mRegisterPlaces.insert(CSP, Register_Position(5, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CIP, "EIP"); + mRegisterPlaces.insert(CIP, Register_Position(9, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(EFLAGS, "EFLAGS"); + mRegisterPlaces.insert(EFLAGS, Register_Position(11, 0, 9, sizeof(uint_t) * 2)); + + offset = 12; +#endif + mRegisterMapping.insert(ZF, "ZF"); + mRegisterPlaces.insert(ZF, Register_Position(offset + 0, 0, 3, 1)); + mRegisterMapping.insert(OF, "OF"); + mRegisterPlaces.insert(OF, Register_Position(offset + 1, 0, 3, 1)); + mRegisterMapping.insert(CF, "CF"); + mRegisterPlaces.insert(CF, Register_Position(offset + 2, 0, 3, 1)); + + mRegisterMapping.insert(PF, "PF"); + mRegisterPlaces.insert(PF, Register_Position(offset + 0, 6, 3, 1)); + mRegisterMapping.insert(SF, "SF"); + mRegisterPlaces.insert(SF, Register_Position(offset + 1, 6, 3, 1)); + mRegisterMapping.insert(TF, "TF"); + mRegisterPlaces.insert(TF, Register_Position(offset + 2, 6, 3, 1)); + + mRegisterMapping.insert(AF, "AF"); + mRegisterPlaces.insert(AF, Register_Position(offset + 0, 12, 3, 1)); + mRegisterMapping.insert(DF, "DF"); + mRegisterPlaces.insert(DF, Register_Position(offset + 1, 12, 3, 1)); + mRegisterMapping.insert(IF, "IF"); + mRegisterPlaces.insert(IF, Register_Position(offset + 2, 12, 3, 1)); + + offset++; + mRegisterMapping.insert(GS, "GS"); + mRegisterPlaces.insert(GS, Register_Position(offset + 3, 0, 3, 4)); + mRegisterMapping.insert(ES, "ES"); + mRegisterPlaces.insert(ES, Register_Position(offset + 4, 0, 3, 4)); + mRegisterMapping.insert(CS, "CS"); + mRegisterPlaces.insert(CS, Register_Position(offset + 5, 0, 3, 4)); + + mRegisterMapping.insert(FS, "FS"); + mRegisterPlaces.insert(FS, Register_Position(offset + 3, 9, 3, 4)); + mRegisterMapping.insert(DS, "DS"); + mRegisterPlaces.insert(DS, Register_Position(offset + 4, 9, 3, 4)); + mRegisterMapping.insert(SS, "SS"); + mRegisterPlaces.insert(SS, Register_Position(offset + 5, 9, 3, 4)); + + if(showfpu) + { + offset++; + + mRegisterMapping.insert(x87r0, "x87r0"); + mRegisterPlaces.insert(x87r0, Register_Position(offset + 6, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r1, "x87r1"); + mRegisterPlaces.insert(x87r1, Register_Position(offset + 7, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r2, "x87r2"); + mRegisterPlaces.insert(x87r2, Register_Position(offset + 8, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r3, "x87r3"); + mRegisterPlaces.insert(x87r3, Register_Position(offset + 9, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r4, "x87r4"); + mRegisterPlaces.insert(x87r4, Register_Position(offset + 10, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r5, "x87r5"); + mRegisterPlaces.insert(x87r5, Register_Position(offset + 11, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r6, "x87r6"); + mRegisterPlaces.insert(x87r6, Register_Position(offset + 12, 0, 6, 10 * 2)); + mRegisterMapping.insert(x87r7, "x87r7"); + mRegisterPlaces.insert(x87r7, Register_Position(offset + 13, 0, 6, 10 * 2)); + + offset++; + mRegisterMapping.insert(x87TagWord, "x87TagWord"); + mRegisterPlaces.insert(x87TagWord, Register_Position(offset + 14, 0, 11, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87TW_0, "x87TW_0"); + mRegisterPlaces.insert(x87TW_0, Register_Position(offset + 15, 0, 8, 10)); + mRegisterMapping.insert(x87TW_1, "x87TW_1"); + mRegisterPlaces.insert(x87TW_1, Register_Position(offset + 15, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_2, "x87TW_2"); + mRegisterPlaces.insert(x87TW_2, Register_Position(offset + 16, 0, 8, 10)); + mRegisterMapping.insert(x87TW_3, "x87TW_3"); + mRegisterPlaces.insert(x87TW_3, Register_Position(offset + 16, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_4, "x87TW_4"); + mRegisterPlaces.insert(x87TW_4, Register_Position(offset + 17, 0, 8, 10)); + mRegisterMapping.insert(x87TW_5, "x87TW_5"); + mRegisterPlaces.insert(x87TW_5, Register_Position(offset + 17, 20, 8, 10)); + + mRegisterMapping.insert(x87TW_6, "x87TW_6"); + mRegisterPlaces.insert(x87TW_6, Register_Position(offset + 18, 0, 8, 10)); + mRegisterMapping.insert(x87TW_7, "x87TW_7"); + mRegisterPlaces.insert(x87TW_7, Register_Position(offset + 18, 20, 8, 10)); + + offset += 4; + + offset++; + mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); + mRegisterPlaces.insert(x87StatusWord, Register_Position(offset + 15, 0, 14, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87SW_B, "x87SW_B"); + mRegisterPlaces.insert(x87SW_B, Register_Position(offset + 16, 0, 9, 1)); + mRegisterMapping.insert(x87SW_C3, "x87SW_C3"); + mRegisterPlaces.insert(x87SW_C3, Register_Position(offset + 16, 12, 10, 1)); + mRegisterMapping.insert(x87SW_C2, "x87SW_C2"); + mRegisterPlaces.insert(x87SW_C2, Register_Position(offset + 16, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_C1, "x87SW_C1"); + mRegisterPlaces.insert(x87SW_C1, Register_Position(offset + 17, 0, 9, 1)); + mRegisterMapping.insert(x87SW_C0, "x87SW_C0"); + mRegisterPlaces.insert(x87SW_C0, Register_Position(offset + 17, 12, 10, 1)); + mRegisterMapping.insert(x87SW_IR, "x87SW_IR"); + mRegisterPlaces.insert(x87SW_IR, Register_Position(offset + 17, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_SF, "x87SW_SF"); + mRegisterPlaces.insert(x87SW_SF, Register_Position(offset + 18, 0, 9, 1)); + mRegisterMapping.insert(x87SW_P, "x87SW_P"); + mRegisterPlaces.insert(x87SW_P, Register_Position(offset + 18, 12, 10, 1)); + mRegisterMapping.insert(x87SW_U, "x87SW_U"); + mRegisterPlaces.insert(x87SW_U, Register_Position(offset + 18, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_O, "x87SW_O"); + mRegisterPlaces.insert(x87SW_O, Register_Position(offset + 19, 0, 9, 1)); + mRegisterMapping.insert(x87SW_Z, "x87SW_Z"); + mRegisterPlaces.insert(x87SW_Z, Register_Position(offset + 19, 12, 10, 1)); + mRegisterMapping.insert(x87SW_D, "x87SW_D"); + mRegisterPlaces.insert(x87SW_D, Register_Position(offset + 19, 25, 10, 1)); + + mRegisterMapping.insert(x87SW_I, "x87SW_I"); + mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); + mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 12)); + + offset++; + + mRegisterMapping.insert(x87ControlWord, "x87ControlWord"); + mRegisterPlaces.insert(x87ControlWord, Register_Position(offset + 21, 0, 15, sizeof(WORD) * 2)); + + mRegisterMapping.insert(x87CW_IC, "x87CW_IC"); + mRegisterPlaces.insert(x87CW_IC, Register_Position(offset + 22, 0, 9, 1)); + mRegisterMapping.insert(x87CW_IEM, "x87CW_IEM"); + mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset + 22, 12, 10, 1)); + mRegisterMapping.insert(x87CW_PM, "x87CW_PM"); + mRegisterPlaces.insert(x87CW_PM, Register_Position(offset + 22, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_UM, "x87CW_UM"); + mRegisterPlaces.insert(x87CW_UM, Register_Position(offset + 23, 0, 9, 1)); + mRegisterMapping.insert(x87CW_OM, "x87CW_OM"); + mRegisterPlaces.insert(x87CW_OM, Register_Position(offset + 23, 12, 10, 1)); + mRegisterMapping.insert(x87CW_ZM, "x87CW_ZM"); + mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset + 23, 25, 10, 1)); + + mRegisterMapping.insert(x87CW_DM, "x87CW_DM"); + mRegisterPlaces.insert(x87CW_DM, Register_Position(offset + 24, 0, 9, 1)); + mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); + mRegisterPlaces.insert(x87CW_IM, Register_Position(offset + 24, 12, 10, 1)); + mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); + mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 13)); + + mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); + mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 13)); + + offset++; + + mRegisterMapping.insert(MxCsr, "MxCsr"); + mRegisterPlaces.insert(MxCsr, Register_Position(offset + 26, 0, 6, sizeof(DWORD) * 2)); + + mRegisterMapping.insert(MxCsr_FZ, "MxCsr_FZ"); + mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset + 27, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_PM, "MxCsr_PM"); + mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset + 27, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_UM, "MxCsr_UM"); + mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset + 27, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_OM, "MxCsr_OM"); + mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset + 28, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_ZM, "MxCsr_ZM"); + mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset + 28, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_IM, "MxCsr_IM"); + mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset + 28, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_UE, "MxCsr_UE"); + mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset + 29, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_PE, "MxCsr_PE"); + mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset + 29, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_DAZ, "MxCsr_DAZ"); + mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset + 29, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_OE, "MxCsr_OE"); + mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset + 30, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_ZE, "MxCsr_ZE"); + mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset + 30, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_DE, "MxCsr_DE"); + mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset + 30, 25, 10, 1)); + + mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); + mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset + 31, 0, 9, 1)); + mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); + mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); + mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 18)); + + offset++; + + mRegisterMapping.insert(MM0, "MM0"); + mRegisterPlaces.insert(MM0, Register_Position(offset + 32, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM1, "MM1"); + mRegisterPlaces.insert(MM1, Register_Position(offset + 33, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM2, "MM2"); + mRegisterPlaces.insert(MM2, Register_Position(offset + 34, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM3, "MM3"); + mRegisterPlaces.insert(MM3, Register_Position(offset + 35, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM4, "MM4"); + mRegisterPlaces.insert(MM4, Register_Position(offset + 36, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM5, "MM5"); + mRegisterPlaces.insert(MM5, Register_Position(offset + 37, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM6, "MM6"); + mRegisterPlaces.insert(MM6, Register_Position(offset + 38, 0, 4, 8 * 2)); + mRegisterMapping.insert(MM7, "MM7"); + mRegisterPlaces.insert(MM7, Register_Position(offset + 39, 0, 4, 8 * 2)); + } + else + offset -= 34; + + offset++; + + mRegisterMapping.insert(DR0, "DR0"); + mRegisterPlaces.insert(DR0, Register_Position(offset + 40, 0, 4, sizeof(uint_t) * 2)); + mRegisterMapping.insert(DR1, "DR1"); + mRegisterPlaces.insert(DR1, Register_Position(offset + 41, 0, 4, sizeof(uint_t) * 2)); + mRegisterMapping.insert(DR2, "DR2"); + mRegisterPlaces.insert(DR2, Register_Position(offset + 42, 0, 4, sizeof(uint_t) * 2)); + mRegisterMapping.insert(DR3, "DR3"); + mRegisterPlaces.insert(DR3, Register_Position(offset + 43, 0, 4, sizeof(uint_t) * 2)); + mRegisterMapping.insert(DR6, "DR6"); + mRegisterPlaces.insert(DR6, Register_Position(offset + 44, 0, 4, sizeof(uint_t) * 2)); + mRegisterMapping.insert(DR7, "DR7"); + mRegisterPlaces.insert(DR7, Register_Position(offset + 45, 0, 4, sizeof(uint_t) * 2)); + + if(showfpu) + { + offset++; + + mRegisterMapping.insert(XMM0, "XMM0"); + mRegisterPlaces.insert(XMM0, Register_Position(offset + 46, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM1, "XMM1"); + mRegisterPlaces.insert(XMM1, Register_Position(offset + 47, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM2, "XMM2"); + mRegisterPlaces.insert(XMM2, Register_Position(offset + 48, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM3, "XMM3"); + mRegisterPlaces.insert(XMM3, Register_Position(offset + 49, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM4, "XMM4"); + mRegisterPlaces.insert(XMM4, Register_Position(offset + 50, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM5, "XMM5"); + mRegisterPlaces.insert(XMM5, Register_Position(offset + 51, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM6, "XMM6"); + mRegisterPlaces.insert(XMM6, Register_Position(offset + 52, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM7, "XMM7"); + mRegisterPlaces.insert(XMM7, Register_Position(offset + 53, 0, 6, 16 * 2)); + +#ifdef _WIN64 + mRegisterMapping.insert(XMM8, "XMM8"); + mRegisterPlaces.insert(XMM8, Register_Position(offset + 54, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM9, "XMM9"); + mRegisterPlaces.insert(XMM9, Register_Position(offset + 55, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM10, "XMM10"); + mRegisterPlaces.insert(XMM10, Register_Position(offset + 56, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM11, "XMM11"); + mRegisterPlaces.insert(XMM11, Register_Position(offset + 57, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM12, "XMM12"); + mRegisterPlaces.insert(XMM12, Register_Position(offset + 58, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM13, "XMM13"); + mRegisterPlaces.insert(XMM13, Register_Position(offset + 59, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM14, "XMM14"); + mRegisterPlaces.insert(XMM14, Register_Position(offset + 60, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM15, "XMM15"); + mRegisterPlaces.insert(XMM15, Register_Position(offset + 61, 0, 6, 16 * 2)); +#endif + } + + mRowsNeeded = offset + 16; + mRowsNeeded++; +} RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) { @@ -39,6 +386,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff wCM_FollowInStack = new QAction("Follow in Stack", this); wCM_Incrementx87Stack = new QAction(tr("Increment x87 Stack"), this); wCM_Decrementx87Stack = new QAction("Decrement x87 Stack", this); + wCM_ChangeFPUView = new QAction("Change FPU View", this); // general purposes register (we allow the user to modify the value) mGPR.insert(CAX); @@ -639,339 +987,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mONLYMODULEANDLABELDISPLAY.insert(CIP); mCANSTOREADDRESS.insert(CIP); - // create mapping from internal id to name - mRegisterMapping.clear(); - mRegisterPlaces.clear(); - int offset = 0; - - /* Register_Position is a struct definition the position - * - * (line , start, labelwidth, valuesize ) - */ -#ifdef _WIN64 - mRegisterMapping.insert(CAX, "RAX"); - mRegisterPlaces.insert(CAX, Register_Position(0, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CBX, "RBX"); - mRegisterPlaces.insert(CBX, Register_Position(1, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CCX, "RCX"); - mRegisterPlaces.insert(CCX, Register_Position(2, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDX, "RDX"); - mRegisterPlaces.insert(CDX, Register_Position(3, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSI, "RSI"); - mRegisterPlaces.insert(CSI, Register_Position(6, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDI, "RDI"); - mRegisterPlaces.insert(CDI, Register_Position(7, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CBP, "RBP"); - mRegisterPlaces.insert(CBP, Register_Position(4, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSP, "RSP"); - mRegisterPlaces.insert(CSP, Register_Position(5, 0, 6, sizeof(uint_t) * 2)); - - mRegisterMapping.insert(R8, "R8"); - mRegisterPlaces.insert(R8 , Register_Position(9, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R9, "R9"); - mRegisterPlaces.insert(R9 , Register_Position(10, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R10, "R10"); - mRegisterPlaces.insert(R10, Register_Position(11, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R11, "R11"); - mRegisterPlaces.insert(R11, Register_Position(12, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R12, "R12"); - mRegisterPlaces.insert(R12, Register_Position(13, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R13, "R13"); - mRegisterPlaces.insert(R13, Register_Position(14, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R14, "R14"); - mRegisterPlaces.insert(R14, Register_Position(15, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R15, "R15"); - mRegisterPlaces.insert(R15, Register_Position(16, 0, 6, sizeof(uint_t) * 2)); - - mRegisterMapping.insert(CIP, "RIP"); - mRegisterPlaces.insert(CIP, Register_Position(18, 0, 6, sizeof(uint_t) * 2)); - - mRegisterMapping.insert(EFLAGS, "RFLAGS"); - mRegisterPlaces.insert(EFLAGS, Register_Position(20, 0, 9, sizeof(uint_t) * 2)); - - offset = 21; -#else - mRegisterMapping.insert(CAX, "EAX"); - mRegisterPlaces.insert(CAX, Register_Position(0, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CBX, "EBX"); - mRegisterPlaces.insert(CBX, Register_Position(1, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CCX, "ECX"); - mRegisterPlaces.insert(CCX, Register_Position(2, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDX, "EDX"); - mRegisterPlaces.insert(CDX, Register_Position(3, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSI, "ESI"); - mRegisterPlaces.insert(CSI, Register_Position(6, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDI, "EDI"); - mRegisterPlaces.insert(CDI, Register_Position(7, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CBP, "EBP"); - mRegisterPlaces.insert(CBP, Register_Position(4, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSP, "ESP"); - mRegisterPlaces.insert(CSP, Register_Position(5, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CIP, "EIP"); - mRegisterPlaces.insert(CIP, Register_Position(9, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(EFLAGS, "EFLAGS"); - mRegisterPlaces.insert(EFLAGS, Register_Position(11, 0, 9, sizeof(uint_t) * 2)); - - offset = 12; -#endif - mRegisterMapping.insert(ZF, "ZF"); - mRegisterPlaces.insert(ZF, Register_Position(offset + 0, 0, 3, 1)); - mRegisterMapping.insert(OF, "OF"); - mRegisterPlaces.insert(OF, Register_Position(offset + 1, 0, 3, 1)); - mRegisterMapping.insert(CF, "CF"); - mRegisterPlaces.insert(CF, Register_Position(offset + 2, 0, 3, 1)); - - mRegisterMapping.insert(PF, "PF"); - mRegisterPlaces.insert(PF, Register_Position(offset + 0, 6, 3, 1)); - mRegisterMapping.insert(SF, "SF"); - mRegisterPlaces.insert(SF, Register_Position(offset + 1, 6, 3, 1)); - mRegisterMapping.insert(TF, "TF"); - mRegisterPlaces.insert(TF, Register_Position(offset + 2, 6, 3, 1)); - - mRegisterMapping.insert(AF, "AF"); - mRegisterPlaces.insert(AF, Register_Position(offset + 0, 12, 3, 1)); - mRegisterMapping.insert(DF, "DF"); - mRegisterPlaces.insert(DF, Register_Position(offset + 1, 12, 3, 1)); - mRegisterMapping.insert(IF, "IF"); - mRegisterPlaces.insert(IF, Register_Position(offset + 2, 12, 3, 1)); - - offset++; - mRegisterMapping.insert(GS, "GS"); - mRegisterPlaces.insert(GS, Register_Position(offset + 3, 0, 3, 4)); - mRegisterMapping.insert(ES, "ES"); - mRegisterPlaces.insert(ES, Register_Position(offset + 4, 0, 3, 4)); - mRegisterMapping.insert(CS, "CS"); - mRegisterPlaces.insert(CS, Register_Position(offset + 5, 0, 3, 4)); - - mRegisterMapping.insert(FS, "FS"); - mRegisterPlaces.insert(FS, Register_Position(offset + 3, 9, 3, 4)); - mRegisterMapping.insert(DS, "DS"); - mRegisterPlaces.insert(DS, Register_Position(offset + 4, 9, 3, 4)); - mRegisterMapping.insert(SS, "SS"); - mRegisterPlaces.insert(SS, Register_Position(offset + 5, 9, 3, 4)); - - offset++; - - mRegisterMapping.insert(x87r0, "x87r0"); - mRegisterPlaces.insert(x87r0, Register_Position(offset + 6, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r1, "x87r1"); - mRegisterPlaces.insert(x87r1, Register_Position(offset + 7, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r2, "x87r2"); - mRegisterPlaces.insert(x87r2, Register_Position(offset + 8, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r3, "x87r3"); - mRegisterPlaces.insert(x87r3, Register_Position(offset + 9, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r4, "x87r4"); - mRegisterPlaces.insert(x87r4, Register_Position(offset + 10, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r5, "x87r5"); - mRegisterPlaces.insert(x87r5, Register_Position(offset + 11, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r6, "x87r6"); - mRegisterPlaces.insert(x87r6, Register_Position(offset + 12, 0, 6, 10 * 2)); - mRegisterMapping.insert(x87r7, "x87r7"); - mRegisterPlaces.insert(x87r7, Register_Position(offset + 13, 0, 6, 10 * 2)); - - offset++; - mRegisterMapping.insert(x87TagWord, "x87TagWord"); - mRegisterPlaces.insert(x87TagWord, Register_Position(offset + 14, 0, 11, sizeof(WORD) * 2)); - - mRegisterMapping.insert(x87TW_0, "x87TW_0"); - mRegisterPlaces.insert(x87TW_0, Register_Position(offset + 15, 0, 8, 10)); - mRegisterMapping.insert(x87TW_1, "x87TW_1"); - mRegisterPlaces.insert(x87TW_1, Register_Position(offset + 15, 20, 8, 10)); - - mRegisterMapping.insert(x87TW_2, "x87TW_2"); - mRegisterPlaces.insert(x87TW_2, Register_Position(offset + 16, 0, 8, 10)); - mRegisterMapping.insert(x87TW_3, "x87TW_3"); - mRegisterPlaces.insert(x87TW_3, Register_Position(offset + 16, 20, 8, 10)); - - mRegisterMapping.insert(x87TW_4, "x87TW_4"); - mRegisterPlaces.insert(x87TW_4, Register_Position(offset + 17, 0, 8, 10)); - mRegisterMapping.insert(x87TW_5, "x87TW_5"); - mRegisterPlaces.insert(x87TW_5, Register_Position(offset + 17, 20, 8, 10)); - - mRegisterMapping.insert(x87TW_6, "x87TW_6"); - mRegisterPlaces.insert(x87TW_6, Register_Position(offset + 18, 0, 8, 10)); - mRegisterMapping.insert(x87TW_7, "x87TW_7"); - mRegisterPlaces.insert(x87TW_7, Register_Position(offset + 18, 20, 8, 10)); - - offset += 4; - - offset++; - mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); - mRegisterPlaces.insert(x87StatusWord, Register_Position(offset + 15, 0, 14, sizeof(WORD) * 2)); - - mRegisterMapping.insert(x87SW_B, "x87SW_B"); - mRegisterPlaces.insert(x87SW_B, Register_Position(offset + 16, 0, 9, 1)); - mRegisterMapping.insert(x87SW_C3, "x87SW_C3"); - mRegisterPlaces.insert(x87SW_C3, Register_Position(offset + 16, 12, 10, 1)); - mRegisterMapping.insert(x87SW_C2, "x87SW_C2"); - mRegisterPlaces.insert(x87SW_C2, Register_Position(offset + 16, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_C1, "x87SW_C1"); - mRegisterPlaces.insert(x87SW_C1, Register_Position(offset + 17, 0, 9, 1)); - mRegisterMapping.insert(x87SW_C0, "x87SW_C0"); - mRegisterPlaces.insert(x87SW_C0, Register_Position(offset + 17, 12, 10, 1)); - mRegisterMapping.insert(x87SW_IR, "x87SW_IR"); - mRegisterPlaces.insert(x87SW_IR, Register_Position(offset + 17, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_SF, "x87SW_SF"); - mRegisterPlaces.insert(x87SW_SF, Register_Position(offset + 18, 0, 9, 1)); - mRegisterMapping.insert(x87SW_P, "x87SW_P"); - mRegisterPlaces.insert(x87SW_P, Register_Position(offset + 18, 12, 10, 1)); - mRegisterMapping.insert(x87SW_U, "x87SW_U"); - mRegisterPlaces.insert(x87SW_U, Register_Position(offset + 18, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_O, "x87SW_O"); - mRegisterPlaces.insert(x87SW_O, Register_Position(offset + 19, 0, 9, 1)); - mRegisterMapping.insert(x87SW_Z, "x87SW_Z"); - mRegisterPlaces.insert(x87SW_Z, Register_Position(offset + 19, 12, 10, 1)); - mRegisterMapping.insert(x87SW_D, "x87SW_D"); - mRegisterPlaces.insert(x87SW_D, Register_Position(offset + 19, 25, 10, 1)); - - mRegisterMapping.insert(x87SW_I, "x87SW_I"); - mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); - mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); - mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 12)); - - offset++; - - mRegisterMapping.insert(x87ControlWord, "x87ControlWord"); - mRegisterPlaces.insert(x87ControlWord, Register_Position(offset + 21, 0, 15, sizeof(WORD) * 2)); - - mRegisterMapping.insert(x87CW_IC, "x87CW_IC"); - mRegisterPlaces.insert(x87CW_IC, Register_Position(offset + 22, 0, 9, 1)); - mRegisterMapping.insert(x87CW_IEM, "x87CW_IEM"); - mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset + 22, 12, 10, 1)); - mRegisterMapping.insert(x87CW_PM, "x87CW_PM"); - mRegisterPlaces.insert(x87CW_PM, Register_Position(offset + 22, 25, 10, 1)); - - mRegisterMapping.insert(x87CW_UM, "x87CW_UM"); - mRegisterPlaces.insert(x87CW_UM, Register_Position(offset + 23, 0, 9, 1)); - mRegisterMapping.insert(x87CW_OM, "x87CW_OM"); - mRegisterPlaces.insert(x87CW_OM, Register_Position(offset + 23, 12, 10, 1)); - mRegisterMapping.insert(x87CW_ZM, "x87CW_ZM"); - mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset + 23, 25, 10, 1)); - - mRegisterMapping.insert(x87CW_DM, "x87CW_DM"); - mRegisterPlaces.insert(x87CW_DM, Register_Position(offset + 24, 0, 9, 1)); - mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); - mRegisterPlaces.insert(x87CW_IM, Register_Position(offset + 24, 12, 10, 1)); - mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); - mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 13)); - - mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); - mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 13)); - - offset++; - - mRegisterMapping.insert(MxCsr, "MxCsr"); - mRegisterPlaces.insert(MxCsr, Register_Position(offset + 26, 0, 6, sizeof(DWORD) * 2)); - - mRegisterMapping.insert(MxCsr_FZ, "MxCsr_FZ"); - mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset + 27, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_PM, "MxCsr_PM"); - mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset + 27, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_UM, "MxCsr_UM"); - mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset + 27, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_OM, "MxCsr_OM"); - mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset + 28, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_ZM, "MxCsr_ZM"); - mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset + 28, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_IM, "MxCsr_IM"); - mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset + 28, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_UE, "MxCsr_UE"); - mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset + 29, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_PE, "MxCsr_PE"); - mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset + 29, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_DAZ, "MxCsr_DAZ"); - mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset + 29, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_OE, "MxCsr_OE"); - mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset + 30, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_ZE, "MxCsr_ZE"); - mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset + 30, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_DE, "MxCsr_DE"); - mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset + 30, 25, 10, 1)); - - mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); - mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset + 31, 0, 9, 1)); - mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); - mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); - mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 18)); - - offset++; - - mRegisterMapping.insert(MM0, "MM0"); - mRegisterPlaces.insert(MM0, Register_Position(offset + 32, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM1, "MM1"); - mRegisterPlaces.insert(MM1, Register_Position(offset + 33, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM2, "MM2"); - mRegisterPlaces.insert(MM2, Register_Position(offset + 34, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM3, "MM3"); - mRegisterPlaces.insert(MM3, Register_Position(offset + 35, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM4, "MM4"); - mRegisterPlaces.insert(MM4, Register_Position(offset + 36, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM5, "MM5"); - mRegisterPlaces.insert(MM5, Register_Position(offset + 37, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM6, "MM6"); - mRegisterPlaces.insert(MM6, Register_Position(offset + 38, 0, 4, 8 * 2)); - mRegisterMapping.insert(MM7, "MM7"); - mRegisterPlaces.insert(MM7, Register_Position(offset + 39, 0, 4, 8 * 2)); - - offset++; - - mRegisterMapping.insert(DR0, "DR0"); - mRegisterPlaces.insert(DR0, Register_Position(offset + 40, 0, 4, sizeof(uint_t) * 2)); - mRegisterMapping.insert(DR1, "DR1"); - mRegisterPlaces.insert(DR1, Register_Position(offset + 41, 0, 4, sizeof(uint_t) * 2)); - mRegisterMapping.insert(DR2, "DR2"); - mRegisterPlaces.insert(DR2, Register_Position(offset + 42, 0, 4, sizeof(uint_t) * 2)); - mRegisterMapping.insert(DR3, "DR3"); - mRegisterPlaces.insert(DR3, Register_Position(offset + 43, 0, 4, sizeof(uint_t) * 2)); - mRegisterMapping.insert(DR6, "DR6"); - mRegisterPlaces.insert(DR6, Register_Position(offset + 44, 0, 4, sizeof(uint_t) * 2)); - mRegisterMapping.insert(DR7, "DR7"); - mRegisterPlaces.insert(DR7, Register_Position(offset + 45, 0, 4, sizeof(uint_t) * 2)); - - offset++; - - mRegisterMapping.insert(XMM0, "XMM0"); - mRegisterPlaces.insert(XMM0, Register_Position(offset + 46, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM1, "XMM1"); - mRegisterPlaces.insert(XMM1, Register_Position(offset + 47, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM2, "XMM2"); - mRegisterPlaces.insert(XMM2, Register_Position(offset + 48, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM3, "XMM3"); - mRegisterPlaces.insert(XMM3, Register_Position(offset + 49, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM4, "XMM4"); - mRegisterPlaces.insert(XMM4, Register_Position(offset + 50, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM5, "XMM5"); - mRegisterPlaces.insert(XMM5, Register_Position(offset + 51, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM6, "XMM6"); - mRegisterPlaces.insert(XMM6, Register_Position(offset + 52, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM7, "XMM7"); - mRegisterPlaces.insert(XMM7, Register_Position(offset + 53, 0, 6, 16 * 2)); - -#ifdef _WIN64 - mRegisterMapping.insert(XMM8, "XMM8"); - mRegisterPlaces.insert(XMM8, Register_Position(offset + 54, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM9, "XMM9"); - mRegisterPlaces.insert(XMM9, Register_Position(offset + 55, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM10, "XMM10"); - mRegisterPlaces.insert(XMM10, Register_Position(offset + 56, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM11, "XMM11"); - mRegisterPlaces.insert(XMM11, Register_Position(offset + 57, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM12, "XMM12"); - mRegisterPlaces.insert(XMM12, Register_Position(offset + 58, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM13, "XMM13"); - mRegisterPlaces.insert(XMM13, Register_Position(offset + 59, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM14, "XMM14"); - mRegisterPlaces.insert(XMM14, Register_Position(offset + 60, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM15, "XMM15"); - mRegisterPlaces.insert(XMM15, Register_Position(offset + 61, 0, 6, 16 * 2)); -#endif + InitMappings(); fontsUpdatedSlot(); connect(Config(), SIGNAL(fontsUpdated()), this, SLOT(fontsUpdatedSlot())); @@ -981,8 +997,6 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mCip = 0; mRegisterUpdates.clear(); - mRowsNeeded = offset + 16; - mRowsNeeded++; yTopSpacing = 3; //set top spacing (in pixels) // Context Menu @@ -995,6 +1009,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff connect(this, SIGNAL(refresh()), this, SLOT(repaint())); // context menu actions connect(wCM_Increment, SIGNAL(triggered()), this, SLOT(onIncrementAction())); + connect(wCM_ChangeFPUView, SIGNAL(triggered()), this, SLOT(onChangeFPUViewAction())); connect(wCM_Decrement, SIGNAL(triggered()), this, SLOT(onDecrementAction())); connect(wCM_Incrementx87Stack, SIGNAL(triggered()), this, SLOT(onIncrementx87StackAction())); connect(wCM_Decrementx87Stack, SIGNAL(triggered()), this, SLOT(onDecrementx87StackAction())); @@ -1038,6 +1053,14 @@ void RegistersView::fontsUpdatedSlot() repaint(); } +void RegistersView::ShowFPU(bool set_showfpu) +{ + showfpu = set_showfpu; + InitMappings(); + repaint(); +} + + /** * @brief retrieves the register id from given corrdinates of the viewport * @param line @@ -1932,12 +1955,22 @@ void RegistersView::onFollowInStack() } } +void RegistersView::onChangeFPUViewAction() +{ + if(showfpu == true) + ShowFPU(false); + else + ShowFPU(true); +} + void RegistersView::displayCustomContextMenuSlot(QPoint pos) { if(!DbgIsDebugging()) return; QMenu wMenu(this); + wMenu.addAction(wCM_ChangeFPUView); + if(mSelected != UNKNOWN) { if(mSETONEZEROTOGGLE.contains(mSelected)) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 17541f678..05a89b69d 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -96,6 +96,7 @@ public slots: void setRegister(REGISTER_NAME reg, uint_t value); void debugStateChangedSlot(DBGSTATE state); void repaint(); + void ShowFPU(bool set_showfpu); signals: void refresh(); @@ -129,6 +130,8 @@ protected slots: void onFollowInDisassembly(); void onFollowInDump(); void onFollowInStack(); + void onChangeFPUViewAction(); + void InitMappings(); QString getRegisterLabel(REGISTER_NAME); int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2); SIZE_T GetSizeRegister(const REGISTER_NAME reg_name); @@ -146,6 +149,7 @@ protected slots: QString GetStatusWordTOPStateString(unsigned short state); private: + bool showfpu; int mVScrollOffset; int mRowsNeeded; int yTopSpacing; @@ -200,6 +204,7 @@ private: QAction* wCM_FollowInStack; QAction* wCM_Incrementx87Stack; QAction* wCM_Decrementx87Stack; + QAction* wCM_ChangeFPUView; int_t mCip; }; From 2bc08e3ac4e266d0744a28172d72f3c1a1e6638a Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 2 Nov 2014 01:45:24 +0100 Subject: [PATCH 13/58] fix a bug in MMX get --- x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 102168 -> 102168 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 105896 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib index 86d6859de3a24da5d313a79294866754fa4bddc5..687bdf7c9a1e38713aee20934fafe5ffad8b9e83 100644 GIT binary patch delta 8943 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 delta 8943 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 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index e488efd599c661b3f74bdf2e7a179c8164f08a0e..d156dcfd207b20ae6a8e40a4fb0854a1a68237bb 100644 GIT binary patch delta 9120 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 BSHb`Q delta 9120 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 Date: Sun, 2 Nov 2014 02:10:58 +0100 Subject: [PATCH 14/58] some fixes in libs struct --- x64_dbg_dbg/XEDParse/XEDParse_x64.a | Bin 0 -> 2912 bytes x64_dbg_dbg/XEDParse/XEDParse_x86.a | Bin 0 -> 2940 bytes x64_dbg_dbg/XEDParse/XEDParse_x86.lib | Bin 1934 -> 1934 bytes x64_dbg_dbg/lz4/lz4.h | 40 +++++++++++++------------- x64_dbg_dbg/lz4/lz4_x64.a | Bin 0 -> 33634 bytes x64_dbg_dbg/lz4/lz4_x86.a | Bin 0 -> 33554 bytes x64_dbg_dbg/lz4/lz4_x86.lib | Bin 11606 -> 11606 bytes x64_dbg_dbg/lz4/lz4file.h | 8 +++--- x64_dbg_dbg/lz4/lz4hc.h | 36 +++++++++++------------ 9 files changed, 42 insertions(+), 42 deletions(-) create mode 100644 x64_dbg_dbg/XEDParse/XEDParse_x64.a create mode 100644 x64_dbg_dbg/XEDParse/XEDParse_x86.a create mode 100644 x64_dbg_dbg/lz4/lz4_x64.a create mode 100644 x64_dbg_dbg/lz4/lz4_x86.a diff --git a/x64_dbg_dbg/XEDParse/XEDParse_x64.a b/x64_dbg_dbg/XEDParse/XEDParse_x64.a new file mode 100644 index 0000000000000000000000000000000000000000..c08940befee42657e126a80d2d1c2c16da647a06 GIT binary patch literal 2912 zcmd5;O>fgc5S_#=l&A<)6$Ij9q#`bralYI{LMWAr#04pb9ylNzmn2QpBvf&bD#W1& z#JNAIXVl+BnK$dT*NIKiOJSt!j%S}UvomjJ{rq(>{XBS6dS$1jTy0kBUZt_;*|sZ7 z=4jjHYAt%9QzD`}{QE^@9kTjZ{Wh+MHm-dC!`p*)Fb#YDnOE}ze>e%oJ@N;=pgXrj z8o3{az46hAQT}jz8lz(K!D#e87*3*P{nQQn$1~?kypg;elwH^JcvtmCGu}b>CpJK| zQy_XE+B!M2-q}p_{K2Mn$LR*MARi(tEoxsnM`5@GM(4l{@rOG#jon~njpH((4eB7SKJ!EA&1E<&ZtgGR4MLB zMy{+pjFG1`!5{-^iE=49TIVIJkc*N0fCX0Je)>Q>14+=5V_NCJt`EM6bql z6zP;S6FtrxD#f+`*G#NP7(8qv8jkBpR8>?ai-{U<&IT@Kwz;l#;IuwJZ?eH6j5wo~ z?4!k)Z`n9c$A!wii!j>8JHEVr zfv1a$#Fl7<#rsfd3!kdq_gGVWQQW}05lf7_3vT&@7`K#kT{3ehJ(ePFNw(mD-%>p` z>7Uvn8Avfw_KM1@h*X3`@U9s7h&2dKnzHQ5vl@!D&x*ct;;TOA3m}ur(szZm?rN;9 zH_a~q#oF&2@G{mOVpA-bZj-g248MP4?I0Vsz}jgxE@mzAa8uS2>F+UB<^P|pNxUXo XHGdPfZlUCn6zL^vik$lWY)<|G%@$fn literal 0 HcmV?d00001 diff --git a/x64_dbg_dbg/XEDParse/XEDParse_x86.a b/x64_dbg_dbg/XEDParse/XEDParse_x86.a new file mode 100644 index 0000000000000000000000000000000000000000..286630e1c8c23c34a63a125a4dcc35cdf5a71da3 GIT binary patch literal 2940 zcmdT`&2G~`5FW=Z2~qhuR0siwMJgABj2#jul`0gZa4S*|91sT_mn7KA4=7Hh960a@ zeWX4>pMgiA%*=Y7b-ZrEp_N$0v+LO}`}57`*?oQ#&c8-)>#s$=cyA6HEx*xe9}3}e zmu`jdTFvwi{W<{L!RI%C-N)vEd}@~fwaXy*^uBiz&XZxV?D#<##ItZZgdm89;b5%~ zy}ilgLm1DxUITyl9#4M+1+Ngg?osNJp)elD`uU+WI{e?6eI1j{J8@7W{twJa-@EpD;nBf8=qi0 zPn9x^#*tly(fFY~+ZNe;NjYS0cCqUk4D&+Kx2=2mLDDxhI$!iTw9~9^} z+XV&s$Q(t8Vy?5wE`zy21vb=l`@9-}$7xh4GA0Eoyk2X#OwoG3Y7HwYTThcGHEA>nK5~r)8=K#6pf}$C$v`IC6 zQvgrcN>c$38)fNNedoDc%^FTzES?ndrY!0=GY!( z-`mvb7j53_bQ+m)1)a{#xJ;)MuWfY-pmIlcE8`gduUdU1MX71kNj+3mpoccQzGho4 JyNH_e?O%D4V+{ZR literal 0 HcmV?d00001 diff --git a/x64_dbg_dbg/XEDParse/XEDParse_x86.lib b/x64_dbg_dbg/XEDParse/XEDParse_x86.lib index 5e87ad2ae514518f65ef4a459a6eb533f97133af..53e0a789f41b38171eda776330ccb4b6cd6aa193 100644 GIT binary patch delta 243 zcmeC<@8h2!$!Tn9WNKz)ZfrLB9Glogi>s&tlXV#Hqlk!4)@I^oF}TDKJlT$EBa`&p z$sd`bL6jf!YZQfIlOtFJAPRF>Iw1(=dTmfE8r&waK|G@{{A3 vq$l5JEraNk=5k2R&n?i)OaWUZHF+8vs%|ZaRe#uw(G2xt7lBBnv1s&tlXV#Hqlk!4)@I^ospJt0nQX_jktx4y z@<*m<5aq}G8bzVlUB;w5%OE>2>gMnt6m diff --git a/x64_dbg_dbg/lz4/lz4.h b/x64_dbg_dbg/lz4/lz4.h index 3adcc0db6..766a6052a 100644 --- a/x64_dbg_dbg/lz4/lz4.h +++ b/x64_dbg_dbg/lz4/lz4.h @@ -60,8 +60,8 @@ extern "C" Simple Functions **************************************/ -__declspec(dllexport) int LZ4_compress(const char* source, char* dest, int inputSize); -__declspec(dllexport) int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) int LZ4_compress(const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_decompress_safe(const char* source, char* dest, int inputSize, int maxOutputSize); /* LZ4_compress() : @@ -98,7 +98,7 @@ LZ4_compressBound() : return : maximum output size in a "worst case" scenario or 0, if input size is too large ( > LZ4_MAX_INPUT_SIZE) */ -__declspec(dllexport) int LZ4_compressBound(int isize); +__declspec(dllimport) int LZ4_compressBound(int isize); /* @@ -112,7 +112,7 @@ LZ4_compress_limitedOutput() : return : the number of bytes written in buffer 'dest' or 0 if the compression fails */ -__declspec(dllexport) int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) int LZ4_compress_limitedOutput(const char* source, char* dest, int inputSize, int maxOutputSize); /* @@ -125,7 +125,7 @@ LZ4_decompress_fast() : Use this function preferably into a trusted environment (data to decode comes from a trusted source). Destination buffer must be already allocated. Its size must be a minimum of 'outputSize' bytes. */ -__declspec(dllexport) int LZ4_decompress_fast(const char* source, char* dest, int originalSize); +__declspec(dllimport) int LZ4_decompress_fast(const char* source, char* dest, int originalSize); /* @@ -140,7 +140,7 @@ LZ4_decompress_safe_partial() : If the source stream is detected malformed, the function will stop decoding and return a negative result. This function never writes outside of output buffer, and never reads outside of input buffer. It is therefore protected against malicious data packets */ -__declspec(dllexport) int LZ4_decompress_safe_partial(const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); +__declspec(dllimport) int LZ4_decompress_safe_partial(const char* source, char* dest, int inputSize, int targetOutputSize, int maxOutputSize); /* @@ -154,19 +154,19 @@ The allocated memory can be provided to the compressions functions using 'void* LZ4_compress_withState() and LZ4_compress_limitedOutput_withState() are equivalent to previously described functions. They just use the externally allocated memory area instead of allocating their own (on stack, or on heap). */ -__declspec(dllexport) int LZ4_sizeofState(void); -__declspec(dllexport) int LZ4_compress_withState(void* state, const char* source, char* dest, int inputSize); -__declspec(dllexport) int LZ4_compress_limitedOutput_withState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) int LZ4_sizeofState(void); +__declspec(dllimport) int LZ4_compress_withState(void* state, const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_compress_limitedOutput_withState(void* state, const char* source, char* dest, int inputSize, int maxOutputSize); /************************************** Streaming Functions **************************************/ -__declspec(dllexport) void* LZ4_create(const char* inputBuffer); -__declspec(dllexport) int LZ4_compress_continue(void* LZ4_Data, const char* source, char* dest, int inputSize); -__declspec(dllexport) int LZ4_compress_limitedOutput_continue(void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllexport) char* LZ4_slideInputBuffer(void* LZ4_Data); -__declspec(dllexport) int LZ4_free(void* LZ4_Data); +__declspec(dllimport) void* LZ4_create(const char* inputBuffer); +__declspec(dllimport) int LZ4_compress_continue(void* LZ4_Data, const char* source, char* dest, int inputSize); +__declspec(dllimport) int LZ4_compress_limitedOutput_continue(void* LZ4_Data, const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) char* LZ4_slideInputBuffer(void* LZ4_Data); +__declspec(dllimport) int LZ4_free(void* LZ4_Data); /* These functions allow the compression of dependent blocks, where each block benefits from prior 64 KB within preceding blocks. @@ -198,8 +198,8 @@ When compression is completed, a call to LZ4_free() will release the memory used */ -__declspec(dllexport) int LZ4_sizeofStreamState(void); -__declspec(dllexport) int LZ4_resetStreamState(void* state, const char* inputBuffer); +__declspec(dllimport) int LZ4_sizeofStreamState(void); +__declspec(dllimport) int LZ4_resetStreamState(void* state, const char* inputBuffer); /* These functions achieve the same result as : @@ -223,8 +223,8 @@ Any other value means there was an error (typically, pointer is not aligned on 4 */ -__declspec(dllexport) int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int inputSize, int maxOutputSize); -__declspec(dllexport) int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize); +__declspec(dllimport) int LZ4_decompress_safe_withPrefix64k(const char* source, char* dest, int inputSize, int maxOutputSize); +__declspec(dllimport) int LZ4_decompress_fast_withPrefix64k(const char* source, char* dest, int outputSize); /* *_withPrefix64k() : @@ -241,8 +241,8 @@ __declspec(dllexport) int LZ4_decompress_fast_withPrefix64k(const char* source, These functions are deprecated and should no longer be used. They are provided here for compatibility with existing user programs. */ -__declspec(dllexport) int LZ4_uncompress(const char* source, char* dest, int outputSize); -__declspec(dllexport) int LZ4_uncompress_unknownOutputSize(const char* source, char* dest, int isize, int maxOutputSize); +__declspec(dllimport) int LZ4_uncompress(const char* source, char* dest, int outputSize); +__declspec(dllimport) int LZ4_uncompress_unknownOutputSize(const char* source, char* dest, int isize, int maxOutputSize); #if defined (__cplusplus) diff --git a/x64_dbg_dbg/lz4/lz4_x64.a b/x64_dbg_dbg/lz4/lz4_x64.a new file mode 100644 index 0000000000000000000000000000000000000000..6d38e9bb571d95564bcc8072c106e60b30f79d53 GIT binary patch literal 33634 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 N)87#0hu_hr{|91>0UQ7T literal 0 HcmV?d00001 diff --git a/x64_dbg_dbg/lz4/lz4_x86.a b/x64_dbg_dbg/lz4/lz4_x86.a new file mode 100644 index 0000000000000000000000000000000000000000..b712e2897022de41f9df3b8f11abcc3790e60c2e GIT binary patch literal 33554 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 literal 0 HcmV?d00001 diff --git a/x64_dbg_dbg/lz4/lz4_x86.lib b/x64_dbg_dbg/lz4/lz4_x86.lib index 71ab58d03c3aeaaef39b1f4e23238e935d9a14db..aa960265e2a15e38ba4cc777421d7d49a3e5140d 100644 GIT binary patch delta 1456 zcmZ`(O-K}B82)s1THR4sXPVjB*_oZ$_IFm@#dMR%TErkq!b4pw$RGpjpmr2Oqf=n$ z_MW4lpi@yu5eWTUx_Ri35ELG&Yt+F@f%X0D%=b;uz`*c)&-=d5`+V;^+tb_A>*l`d zaBZYk8-}{3HAdfc<@OLFuS?#ISj&laSm^12b;*T-)CDtAb>odR+a`v=cxTZoH6hb_nV6k(EEaFsD6kHSa>FQGjFmAo-lv zzX~i3783Ce%slfPA=C=%Fl#7NKhvhejp;ce80O*<9h z?AokWEG=qadatL)11_omDXr2wsNj4t=uImiI|oCI^A2MSVTMc@tIkNkAewd@h33d& zMi*styM++ro5vK*xkm!Lu5rgdx?#sF8P;VAXN==6T}gqNj1|N-t5WBlW$FP=I_f^4 zQild`Y#)xj-<^kBE_aA%St2?8+57GB zJ0!TjC0EOQORz@j$mep{DSr-5_46F0Pyf%b+0XwBWWMA9RVG{N;XX=uPwz+>I6V;k E3&K)<5Lp6n*WqG3`w2v`Lf6WRgk7$$Vtm&N$X~5UWE`5N)M`ZmM7fD^wS?E?g9( ziYuYgj`s&BD7aFTst5%?HtxFU!h)c5p>9PN-6#~_$0T_X3YIABu z-&L*DhH869pspy5+J`QC2O;u0MYxdD1#}9Xho<999R( z=bZYDV<~Vo5%0jv(=QQ1tuUwP@F;PS#grL831_qlAEQ-ADi(XDJI7lhh{SI+pw zHqYX9SWJpuj)%#9E{6(RS&1r)=v59+z=GS$l=2i1FQJie~MDK3-P>$3NL&$IBVkWeR7E<1TGMg6WLm$2O}{=bmTkK2AF7 z-Xl|o25@XIj(yObgFANM5aBE}IfIxZQH}vWTRY)WG1w+j<9?CpwzIr$71j$3Z)ExD z3?^$k%TJaHU?LOISw&E;uS2Z{H2u4zHF*Q-2N2(lASg^Eu1U^Q`33 zQxl&i>FGLmT33SVc0Q=yoF(euay~p0yeb1{l;Eb^25;K_Ri?n@0-N4jg+X5rsp$Fh zwGjA&b<%qwIxXyZOI(4OV$f;RZ_2SS$EF+&?v_M&YDs>6Z}S{C*gSrgmfc{MNKS9| z{ Date: Sun, 2 Nov 2014 02:13:16 +0100 Subject: [PATCH 15/58] DBG+EXE: fixed some bugs --- x64_dbg_dbg/_exports.cpp | 2 +- x64_dbg_dbg/symbolinfo.cpp | 4 ++-- x64_dbg_dbg/value.cpp | 1 + x64_dbg_exe/x64_dbg_exe.vcxproj | 4 ++++ x64_dbg_exe/x64_dbg_exe.vcxproj.filters | 6 ++++++ 5 files changed, 14 insertions(+), 3 deletions(-) diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 0160c1978..b952f58dd 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -104,7 +104,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_LABEL_SIZE; + pSymbol->MaxNameLen = MAX_LABEL_SIZE - 1; if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement) { if(bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) diff --git a/x64_dbg_dbg/symbolinfo.cpp b/x64_dbg_dbg/symbolinfo.cpp index d91412283..ddb29ab71 100644 --- a/x64_dbg_dbg/symbolinfo.cpp +++ b/x64_dbg_dbg/symbolinfo.cpp @@ -131,7 +131,7 @@ bool symfromname(const char* name, uint* addr) char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_LABEL_SIZE; + pSymbol->MaxNameLen = MAX_LABEL_SIZE - 1; if(!SymFromName(fdProcessInfo->hProcess, name, pSymbol)) return false; *addr = (uint)pSymbol->Address; @@ -152,7 +152,7 @@ const char* symgetsymbolicname(uint addr) char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_LABEL_SIZE; + pSymbol->MaxNameLen = MAX_LABEL_SIZE - 1; if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement) { if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index a40322e89..d7258a828 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1953,6 +1953,7 @@ bool valtostring(const char* string, uint* value, bool silent) { uint csp = GetContextDataEx(hActiveThread, UE_CSP); GuiStackDumpAt(csp, csp); + GuiUpdateRegisterView(); } else GuiUpdateAllViews(); //repaint gui diff --git a/x64_dbg_exe/x64_dbg_exe.vcxproj b/x64_dbg_exe/x64_dbg_exe.vcxproj index 2ad12bb5b..4e831d7c7 100644 --- a/x64_dbg_exe/x64_dbg_exe.vcxproj +++ b/x64_dbg_exe/x64_dbg_exe.vcxproj @@ -19,6 +19,10 @@ + + + + {3A22175E-6B72-FDCC-1603-C4A2163C7900} Win32Proj diff --git a/x64_dbg_exe/x64_dbg_exe.vcxproj.filters b/x64_dbg_exe/x64_dbg_exe.vcxproj.filters index aeb105a7e..c37e6d1af 100644 --- a/x64_dbg_exe/x64_dbg_exe.vcxproj.filters +++ b/x64_dbg_exe/x64_dbg_exe.vcxproj.filters @@ -29,4 +29,10 @@ Resource Files + + + Resource Files + + + \ No newline at end of file From 29576b4bf50a69d6a29b06a667206a90be89ca96 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sun, 2 Nov 2014 02:34:18 +0100 Subject: [PATCH 16/58] GUI: prettified some stings --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 46 +++++++++---------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 36bae7576..5b48495dc 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -1306,35 +1306,35 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value if(mTAGWORD.contains(reg)) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString("("); + valueText += QString(" ("); valueText += GetTagWordStateString((* ((unsigned short*) value))); valueText += QString(")"); } if(reg == MxCsr_RC) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString("("); + valueText += QString(" ("); valueText += GetMxCsrRCStateString((* ((unsigned short*) value))); valueText += QString(")"); } else if(reg == x87CW_RC) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString("("); + valueText += QString(" ("); valueText += GetControlWordRCStateString((* ((unsigned short*) value))); valueText += QString(")"); } else if(reg == x87CW_PC) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString("("); + valueText += QString(" ("); valueText += GetControlWordPCStateString((* ((unsigned short*) value))); valueText += QString(")"); } else if(reg == x87SW_TOP) { valueText = QString("%1").arg((* ((unsigned short*) value)), 1, 16, QChar('0')).toUpper(); - valueText += QString("(ST0="); + valueText += QString(" (ST0="); valueText += GetStatusWordTOPStateString((* ((unsigned short*) value))); valueText += QString(")"); } @@ -1358,10 +1358,10 @@ QString RegistersView::GetRegStringValueFromValue(REGISTER_NAME reg, char* value STRING_VALUE_TABLE_t MxCsrRCValueStringTable[] = { - {"toward zero", MxCsr_RC_TOZERO}, - {"toward positive", MxCsr_RC_POSITIVE}, - {"toward negative", MxCsr_RC_NEGATIVE}, - {"round near", MxCsr_RC_NEAR} + {"Toward Zero", MxCsr_RC_TOZERO}, + {"Toward Positive", MxCsr_RC_POSITIVE}, + {"Toward Negative", MxCsr_RC_NEGATIVE}, + {"Round Near", MxCsr_RC_NEAR} }; unsigned int RegistersView::GetMxCsrRCValueFromString(QString string) @@ -1387,7 +1387,7 @@ QString RegistersView::GetMxCsrRCStateString(unsigned short state) return MxCsrRCValueStringTable[i].string; } - return "unknown"; + return "Unknown"; } #define x87CW_RC_NEAR 0 @@ -1397,10 +1397,10 @@ QString RegistersView::GetMxCsrRCStateString(unsigned short state) STRING_VALUE_TABLE_t ControlWordRCValueStringTable[] = { - {"truncate", x87CW_RC_TRUNCATE}, - {"round up", x87CW_RC_UP}, - {"round down", x87CW_RC_DOWN}, - {"round near", x87CW_RC_NEAR} + {"Truncate", x87CW_RC_TRUNCATE}, + {"Round Up", x87CW_RC_UP}, + {"Round Down", x87CW_RC_DOWN}, + {"Round Near", x87CW_RC_NEAR} }; unsigned int RegistersView::GetControlWordRCValueFromString(QString string) @@ -1484,10 +1484,10 @@ QString RegistersView::GetStatusWordTOPStateString(unsigned short state) STRING_VALUE_TABLE_t ControlWordPCValueStringTable[] = { - {"real4", x87CW_PC_REAL4}, - {"not used", x87CW_PC_NOTUSED}, - {"real8", x87CW_PC_REAL8}, - {"real10", x87CW_PC_REAL10} + {"Real4", x87CW_PC_REAL4}, + {"Not Used", x87CW_PC_NOTUSED}, + {"Real8", x87CW_PC_REAL8}, + {"Real10", x87CW_PC_REAL10} }; @@ -1526,10 +1526,10 @@ QString RegistersView::GetControlWordPCStateString(unsigned short state) STRING_VALUE_TABLE_t TagWordValueStringTable[] = { - {"nonzero", X87FPU_TAGWORD_NONZERO}, - {"zero", X87FPU_TAGWORD_ZERO}, - {"special", X87FPU_TAGWORD_SPECIAL}, - {"empty", X87FPU_TAGWORD_EMPTY} + {"Nonzero", X87FPU_TAGWORD_NONZERO}, + {"Zero", X87FPU_TAGWORD_ZERO}, + {"Special", X87FPU_TAGWORD_SPECIAL}, + {"Empty", X87FPU_TAGWORD_EMPTY} }; unsigned int RegistersView::GetTagWordValueFromString(QString string) @@ -1556,7 +1556,7 @@ QString RegistersView::GetTagWordStateString(unsigned short state) return TagWordValueStringTable[i].string; } - return "unknown"; + return "Unknown"; } void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) From 6d9a4520c07dff154fac262608a7d8cd5466b6ac Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sun, 2 Nov 2014 02:50:09 +0100 Subject: [PATCH 17/58] simple custom-drawn button in registersview --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 35 +++++++++++++------ x64_dbg_gui/Project/Src/Gui/RegistersView.h | 1 + 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 5b48495dc..6385ecf90 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -997,7 +997,8 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mCip = 0; mRegisterUpdates.clear(); - yTopSpacing = 3; //set top spacing (in pixels) + mButtonHeight = 5; + yTopSpacing = 20; //set top spacing (in pixels) // Context Menu this->setContextMenuPolicy(Qt::CustomContextMenu); @@ -1099,19 +1100,27 @@ void RegistersView::mousePressEvent(QMouseEvent* event) { if(!DbgIsDebugging()) return; - // get mouse position - const int y = (event->y() - 3) / (double)mRowHeight; - const int x = event->x() / (double)mCharWidth; - REGISTER_NAME r; - // do we find a corresponding register? - if(identifyRegister(y, x, &r)) + if(event->y() < yTopSpacing - mButtonHeight) { - mSelected = r; - emit refresh(); + QMessageBox::information(this, "Troll", "You are now dead..."); } else - mSelected = UNKNOWN; + { + // get mouse position + const int y = (event->y() - yTopSpacing) / (double)mRowHeight; + const int x = event->x() / (double)mCharWidth; + + REGISTER_NAME r; + // do we find a corresponding register? + if(identifyRegister(y, x, &r)) + { + mSelected = r; + emit refresh(); + } + else + mSelected = UNKNOWN; + } } void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) @@ -1120,7 +1129,7 @@ void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) if(!DbgIsDebugging() || event->button() != Qt::LeftButton) return; // get mouse position - const int y = (event->y() - 3) / (double)mRowHeight; + const int y = (event->y() - yTopSpacing) / (double)mRowHeight; const int x = event->x() / (double)mCharWidth; // do we find a corresponding register? @@ -1143,6 +1152,10 @@ void RegistersView::paintEvent(QPaintEvent* event) QPainter wPainter(this->viewport()); wPainter.fillRect(wPainter.viewport(), QBrush(ConfigColor("RegistersBackgroundColor"))); + wPainter.setPen(Qt::black); + wPainter.drawLine(0, yTopSpacing - mButtonHeight, this->viewport()->width(), yTopSpacing - mButtonHeight); + wPainter.drawText(0, 0, this->viewport()->width(), yTopSpacing - mButtonHeight, Qt::AlignVCenter, " Press here to die..."); + QMap::const_iterator it = mRegisterMapping.begin(); // iterate all registers while(it != mRegisterMapping.end()) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 05a89b69d..0c7688e86 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -153,6 +153,7 @@ private: int mVScrollOffset; int mRowsNeeded; int yTopSpacing; + int mButtonHeight; QSet mUINTDISPLAY; QSet mUSHORTDISPLAY; QSet mDWORDDISPLAY; From 89b7910352386faf7352bd48cde48f20be608bf4 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 2 Nov 2014 03:11:10 +0100 Subject: [PATCH 18/58] eflags fix and button tunning in registers --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 2 +- x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 102168 -> 102168 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 105896 bytes x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 8 ++++---- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index 3c5bf4245..94e21eeb6 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -343,7 +343,7 @@ typedef struct ULONG_PTR r15; #endif //_WIN64 ULONG_PTR cip; - unsigned int eflags; + ULONG_PTR eflags; unsigned short gs; unsigned short fs; unsigned short es; diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib index 687bdf7c9a1e38713aee20934fafe5ffad8b9e83..f8c1d8a69ca381acd9f2ff6f003d22e1f39a97f9 100644 GIT binary patch delta 9383 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 XT2&%QF{Z?q6bnkQo(pol#EAbNl!@d2 delta 9383 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 Y;H%37DMpoflVV{R)>A>Qml<*Y1D=ufG5`Po diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index d156dcfd207b20ae6a8e40a4fb0854a1a68237bb..bc5345d16cb69f9c816e90db65071da569e55f11 100644 GIT binary patch delta 9366 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 diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 6385ecf90..c45277e26 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -1103,7 +1103,7 @@ void RegistersView::mousePressEvent(QMouseEvent* event) if(event->y() < yTopSpacing - mButtonHeight) { - QMessageBox::information(this, "Troll", "You are now dead..."); + onChangeFPUViewAction(); } else { @@ -1154,7 +1154,7 @@ void RegistersView::paintEvent(QPaintEvent* event) wPainter.setPen(Qt::black); wPainter.drawLine(0, yTopSpacing - mButtonHeight, this->viewport()->width(), yTopSpacing - mButtonHeight); - wPainter.drawText(0, 0, this->viewport()->width(), yTopSpacing - mButtonHeight, Qt::AlignVCenter, " Press here to die..."); + wPainter.drawText(0, 0, this->viewport()->width(), yTopSpacing - mButtonHeight, Qt::AlignVCenter, " Press here to FPU change..."); QMap::const_iterator it = mRegisterMapping.begin(); // iterate all registers @@ -1982,8 +1982,6 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) return; QMenu wMenu(this); - wMenu.addAction(wCM_ChangeFPUView); - if(mSelected != UNKNOWN) { if(mSETONEZEROTOGGLE.contains(mSelected)) @@ -2046,6 +2044,8 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) QAction* wHwbpCsp = wMenu.addAction("HW Break on [ESP]"); #endif QAction* wAction = wMenu.exec(this->mapToGlobal(pos)); + wMenu.addSeparator(); + wMenu.addAction(wCM_ChangeFPUView); if(wAction == wHwbpCsp) DbgCmdExec("bphws csp,rw"); From fe593d12b773b8c1dc9302f60135a2702a381031 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 2 Nov 2014 03:16:49 +0100 Subject: [PATCH 19/58] fixed the size selection in special fpu fields --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index c45277e26..0cf682829 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -202,7 +202,7 @@ void RegistersView::InitMappings() mRegisterMapping.insert(x87SW_I, "x87SW_I"); mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); - mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 12)); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 13)); offset++; @@ -228,10 +228,10 @@ void RegistersView::InitMappings() mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); mRegisterPlaces.insert(x87CW_IM, Register_Position(offset + 24, 12, 10, 1)); mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); - mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 13)); + mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 14)); mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); - mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 13)); + mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 14)); offset++; @@ -271,7 +271,7 @@ void RegistersView::InitMappings() mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 18)); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 19)); offset++; From 2082be74ac67d215b3788cd15d0c828c3798f6db Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 2 Nov 2014 03:32:35 +0100 Subject: [PATCH 20/58] new tunning button --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 0cf682829..a1064a7e9 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -1154,7 +1154,16 @@ void RegistersView::paintEvent(QPaintEvent* event) wPainter.setPen(Qt::black); wPainter.drawLine(0, yTopSpacing - mButtonHeight, this->viewport()->width(), yTopSpacing - mButtonHeight); - wPainter.drawText(0, 0, this->viewport()->width(), yTopSpacing - mButtonHeight, Qt::AlignVCenter, " Press here to FPU change..."); + + QString fpu_button_text = QString(""); + if(DbgIsDebugging()) + { + if(showfpu) + fpu_button_text = QString(" Hide FPU - "); + else + fpu_button_text = QString(" Show FPU - "); + } + wPainter.drawText(0, 0, this->viewport()->width(), yTopSpacing - mButtonHeight, Qt::AlignVCenter, fpu_button_text); QMap::const_iterator it = mRegisterMapping.begin(); // iterate all registers @@ -2038,14 +2047,14 @@ void RegistersView::displayCustomContextMenuSlot(QPoint pos) else { wMenu.addSeparator(); + wMenu.addAction(wCM_ChangeFPUView); + wMenu.addSeparator(); #ifdef _WIN64 QAction* wHwbpCsp = wMenu.addAction("HW Break on [RSP]"); #else QAction* wHwbpCsp = wMenu.addAction("HW Break on [ESP]"); #endif QAction* wAction = wMenu.exec(this->mapToGlobal(pos)); - wMenu.addSeparator(); - wMenu.addAction(wCM_ChangeFPUView); if(wAction == wHwbpCsp) DbgCmdExec("bphws csp,rw"); From ce1064c7ccfa2668b33a5af4d84f282db9c7edb5 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sun, 2 Nov 2014 17:21:07 +0100 Subject: [PATCH 21/58] Added a real PUSHBUTTON to switch FPU view --- x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp | 17 ++++++++--- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 29 ++++++++++--------- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 4 ++- 3 files changed, 32 insertions(+), 18 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp b/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp index 2a815e74c..0a167fe2d 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp @@ -42,10 +42,19 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget) scrollArea->horizontalScrollBar()->setStyleSheet("QScrollBar:horizontal{border:1px solid grey;background:#f1f1f1;height:10px}QScrollBar::handle:horizontal{background:#aaa;min-width:20px;margin:1px}QScrollBar::add-line:horizontal,QScrollBar::sub-line:horizontal{width:0;height:0}"); scrollArea->verticalScrollBar()->setStyleSheet("QScrollBar:vertical{border:1px solid grey;background:#f1f1f1;width:10px}QScrollBar::handle:vertical{background:#aaa;min-height:20px;margin:1px}QScrollBar::add-line:vertical,QScrollBar::sub-line:vertical{width:0;height:0}"); - /* - mRegsTab = new QTabWidget(this); - mRegsTab->addTab(scrollArea, "General"); - */ + QPushButton* button_changeview = new QPushButton(""); + + mGeneralRegs->SetChangeButton(button_changeview); + + button_changeview->setStyleSheet("Text-align:left;padding: 4px;padding-left: 10px;"); + QFont font = QFont("Lucida Console"); + font.setStyleHint(QFont::Monospace); + font.setPointSize(8); + button_changeview->setFont(font); + connect(button_changeview, SIGNAL(clicked()), mGeneralRegs, SLOT(onChangeFPUViewAction())); + + ui->mTopRightFrameLayout->addWidget(button_changeview); + ui->mTopRightFrameLayout->addWidget(scrollArea); mDump = new CPUDump(0); //dump widget diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index a1064a7e9..ef117e3a6 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -7,6 +7,11 @@ #include #include +void RegistersView::SetChangeButton(QPushButton* push_button) +{ + button = push_button; +} + void RegistersView::InitMappings() { // create mapping from internal id to name @@ -357,6 +362,8 @@ void RegistersView::InitMappings() RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) { + button = NULL; + // precreate ContextMenu Actions wCM_Increment = new QAction(tr("Increment"), this); wCM_Increment->setShortcutContext(Qt::WidgetShortcut); @@ -386,7 +393,7 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff wCM_FollowInStack = new QAction("Follow in Stack", this); wCM_Incrementx87Stack = new QAction(tr("Increment x87 Stack"), this); wCM_Decrementx87Stack = new QAction("Decrement x87 Stack", this); - wCM_ChangeFPUView = new QAction("Change FPU View", this); + wCM_ChangeFPUView = new QAction("Change View", this); // general purposes register (we allow the user to modify the value) mGPR.insert(CAX); @@ -997,8 +1004,8 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mCip = 0; mRegisterUpdates.clear(); - mButtonHeight = 5; - yTopSpacing = 20; //set top spacing (in pixels) + mButtonHeight = 0; + yTopSpacing = 4; //set top spacing (in pixels) // Context Menu this->setContextMenuPolicy(Qt::CustomContextMenu); @@ -1149,21 +1156,17 @@ void RegistersView::mouseDoubleClickEvent(QMouseEvent* event) void RegistersView::paintEvent(QPaintEvent* event) { Q_UNUSED(event); - QPainter wPainter(this->viewport()); - wPainter.fillRect(wPainter.viewport(), QBrush(ConfigColor("RegistersBackgroundColor"))); - wPainter.setPen(Qt::black); - wPainter.drawLine(0, yTopSpacing - mButtonHeight, this->viewport()->width(), yTopSpacing - mButtonHeight); - - QString fpu_button_text = QString(""); - if(DbgIsDebugging()) + if(button != NULL) { if(showfpu) - fpu_button_text = QString(" Hide FPU - "); + button->setText("Show Only General Registers"); else - fpu_button_text = QString(" Show FPU - "); + button->setText("Show FPU"); } - wPainter.drawText(0, 0, this->viewport()->width(), yTopSpacing - mButtonHeight, Qt::AlignVCenter, fpu_button_text); + + QPainter wPainter(this->viewport()); + wPainter.fillRect(wPainter.viewport(), QBrush(ConfigColor("RegistersBackgroundColor"))); QMap::const_iterator it = mRegisterMapping.begin(); // iterate all registers diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 0c7688e86..9214fbd9d 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -97,6 +97,8 @@ public slots: void debugStateChangedSlot(DBGSTATE state); void repaint(); void ShowFPU(bool set_showfpu); + void onChangeFPUViewAction(); + void SetChangeButton(QPushButton* push_button); signals: void refresh(); @@ -130,7 +132,6 @@ protected slots: void onFollowInDisassembly(); void onFollowInDump(); void onFollowInStack(); - void onChangeFPUViewAction(); void InitMappings(); QString getRegisterLabel(REGISTER_NAME); int CompareRegisters(const REGISTER_NAME reg_name, REGDUMP* regdump1, REGDUMP* regdump2); @@ -149,6 +150,7 @@ protected slots: QString GetStatusWordTOPStateString(unsigned short state); private: + QPushButton* button; bool showfpu; int mVScrollOffset; int mRowsNeeded; From ed0f837dfdf075347d76fb645a0949ce305fc74a Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Sat, 8 Nov 2014 13:48:48 +0100 Subject: [PATCH 22/58] jit support improved --- x64_dbg_dbg/debugger.cpp | 4 ++ x64_dbg_dbg/debugger_commands.cpp | 16 ++++--- .../Project/Src/Gui/SettingsDialog.cpp | 48 +++++++++---------- 3 files changed, 37 insertions(+), 31 deletions(-) diff --git a/x64_dbg_dbg/debugger.cpp b/x64_dbg_dbg/debugger.cpp index a6a78763f..dcc707ae7 100644 --- a/x64_dbg_dbg/debugger.cpp +++ b/x64_dbg_dbg/debugger.cpp @@ -1570,7 +1570,11 @@ static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, ch { lRv = RegOpenKeyEx(HKEY_LOCAL_MACHINE, JIT_REG_KEY, 0, key_flags, &hKey); if(lRv != ERROR_SUCCESS) + { + if(error != NULL) + *error = ERROR_RW_FILE_NOT_FOUND; return false; + } lRv = RegQueryValueExW(hKey, ConvertUtf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size); if(lRv != ERROR_SUCCESS) diff --git a/x64_dbg_dbg/debugger_commands.cpp b/x64_dbg_dbg/debugger_commands.cpp index 764e489e2..629632d25 100644 --- a/x64_dbg_dbg/debugger_commands.cpp +++ b/x64_dbg_dbg/debugger_commands.cpp @@ -1564,13 +1564,12 @@ CMDRESULT cbDebugSetJIT(int argc, char* argv[]) char path[JIT_ENTRY_DEF_SIZE]; dbggetdefjit(path); char get_entry[JIT_ENTRY_MAX_SIZE] = ""; + bool get_last_jit = true; if(!dbggetjit(get_entry, notfound, & actual_arch, NULL)) - { - dprintf("Error getting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); - return STATUS_ERROR; - } - strcpy_s(oldjit, get_entry); + get_last_jit = false; + else + strcpy_s(oldjit, get_entry); jit_debugger_cmd = path; if(!dbgsetjit(jit_debugger_cmd, notfound, & actual_arch, NULL)) @@ -1578,8 +1577,11 @@ CMDRESULT cbDebugSetJIT(int argc, char* argv[]) dprintf("Error setting JIT %s\n", (actual_arch == x64) ? "x64" : "x32"); return STATUS_ERROR; } - if(_stricmp(oldjit, path)) - BridgeSettingSet("JIT", "Old", oldjit); + if(get_last_jit) + { + if(_stricmp(oldjit, path)) + BridgeSettingSet("JIT", "Old", oldjit); + } } else if(!_strcmpi(argv[1], "restore")) { diff --git a/x64_dbg_gui/Project/Src/Gui/SettingsDialog.cpp b/x64_dbg_gui/Project/Src/Gui/SettingsDialog.cpp index d1afa836f..c631bb41d 100644 --- a/x64_dbg_gui/Project/Src/Gui/SettingsDialog.cpp +++ b/x64_dbg_gui/Project/Src/Gui/SettingsDialog.cpp @@ -173,39 +173,39 @@ void SettingsDialog::LoadSettings() #ifndef _WIN64 isx64 = false; #endif - if(DbgFunctions()->GetJit) - { - bool jit_auto_on; - DbgFunctions()->GetJit(jit_entry, isx64); - DbgFunctions()->GetDefJit(jit_def_entry); + bool jit_auto_on; + bool get_jit_works; + get_jit_works = DbgFunctions()->GetJit(jit_entry, isx64); + DbgFunctions()->GetDefJit(jit_def_entry); + if(get_jit_works) + { if(_strcmpi(jit_entry, jit_def_entry) == 0) settings.miscSetJIT = true; - else - settings.miscSetJIT = false; - ui->editJIT->setText(jit_entry); - ui->editJIT->setCursorPosition(0); + } + else + settings.miscSetJIT = false; + ui->editJIT->setText(jit_entry); + ui->editJIT->setCursorPosition(0); - ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT)); + ui->chkSetJIT->setCheckState(bool2check(settings.miscSetJIT)); - if(DbgFunctions()->GetJitAuto(&jit_auto_on)) - { - if(!jit_auto_on) - settings.miscSetJITAuto = true; - else - settings.miscSetJITAuto = false; + bool get_jit_auto_works = DbgFunctions()->GetJitAuto(&jit_auto_on); + if(!get_jit_auto_works || !jit_auto_on) + settings.miscSetJITAuto = true; + else + settings.miscSetJITAuto = false; - ui->chkConfirmBeforeAtt->setCheckState(bool2check(settings.miscSetJITAuto)); - } + ui->chkConfirmBeforeAtt->setCheckState(bool2check(settings.miscSetJITAuto)); - if(!DbgFunctions()->IsProcessElevated()) - { - ui->chkSetJIT->setDisabled(true); - ui->chkConfirmBeforeAtt->setDisabled(true); - ui->lbladminwarning->setText(QString("Warning: Run the debugger as Admin to enable JIT.")); - } + if(!DbgFunctions()->IsProcessElevated()) + { + ui->chkSetJIT->setDisabled(true); + ui->chkConfirmBeforeAtt->setDisabled(true); + ui->lbladminwarning->setText(QString("Warning: Run the debugger as Admin to enable JIT.")); } } + bJitOld = settings.miscSetJIT; bJitAutoOld = settings.miscSetJITAuto; } From 7bb177a2b46c08170c170fc536df58e70f129fb6 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 8 Nov 2014 20:29:06 +0100 Subject: [PATCH 23/58] DBG: fixed issue #209, the issue was with dbghelp, which simply doesn't respect the MaxNameLen member. --- x64_dbg_dbg/_exports.cpp | 8 +++++--- x64_dbg_dbg/symbolinfo.cpp | 5 +++-- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index b952f58dd..85eaca02a 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -104,10 +104,11 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_LABEL_SIZE - 1; + pSymbol->MaxNameLen = MAX_LABEL_SIZE; if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement) { - if(bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) + pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; + if(bUndecorateSymbolNames and !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) strcpy_s(addrinfo->label, pSymbol->Name); retval = true; } @@ -122,7 +123,8 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR { if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement) { - if(bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) + pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; + if(bUndecorateSymbolNames and !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name); retval = true; } diff --git a/x64_dbg_dbg/symbolinfo.cpp b/x64_dbg_dbg/symbolinfo.cpp index ddb29ab71..ce52b3584 100644 --- a/x64_dbg_dbg/symbolinfo.cpp +++ b/x64_dbg_dbg/symbolinfo.cpp @@ -152,10 +152,11 @@ const char* symgetsymbolicname(uint addr) char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer; pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO); - pSymbol->MaxNameLen = MAX_LABEL_SIZE - 1; + pSymbol->MaxNameLen = MAX_LABEL_SIZE; if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement) { - if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) + pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; + if(bUndecorateSymbolNames and !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) strcpy_s(label, pSymbol->Name); retval = true; } From bdda41563caf44a545c559a2627a8d42f99db799 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 8 Nov 2014 20:44:22 +0100 Subject: [PATCH 24/58] DBG: fixed some possible buffer overflows in dbghelp + fixed condition to copy the original name in the label buffer --- x64_dbg_dbg/_exports.cpp | 6 +++--- x64_dbg_dbg/symbolinfo.cpp | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 85eaca02a..5707ad469 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -101,14 +101,14 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR else //no user labels { DWORD64 displacement = 0; - char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; + 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(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; - if(bUndecorateSymbolNames and !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) + if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) strcpy_s(addrinfo->label, pSymbol->Name); retval = true; } @@ -124,7 +124,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR if(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)val, &displacement, pSymbol) and !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; - if(bUndecorateSymbolNames and !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) + if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, addrinfo->label, MAX_LABEL_SIZE, UNDNAME_COMPLETE)) sprintf_s(addrinfo->label, "JMP.&%s", pSymbol->Name); retval = true; } diff --git a/x64_dbg_dbg/symbolinfo.cpp b/x64_dbg_dbg/symbolinfo.cpp index ce52b3584..256c81bf2 100644 --- a/x64_dbg_dbg/symbolinfo.cpp +++ b/x64_dbg_dbg/symbolinfo.cpp @@ -128,10 +128,10 @@ bool symfromname(const char* name, uint* addr) { if(!name or !strlen(name) or !addr or !_strnicmp(name, "ordinal", 7)) //skip 'OrdinalXXX' return false; - char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; + 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 - 1; + pSymbol->MaxNameLen = MAX_LABEL_SIZE; if(!SymFromName(fdProcessInfo->hProcess, name, pSymbol)) return false; *addr = (uint)pSymbol->Address; @@ -149,14 +149,14 @@ const char* symgetsymbolicname(uint addr) else //no user labels { DWORD64 displacement = 0; - char buffer[sizeof(SYMBOL_INFO) + MAX_LABEL_SIZE * sizeof(char)]; + 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(SymFromAddr(fdProcessInfo->hProcess, (DWORD64)addr, &displacement, pSymbol) and !displacement) { pSymbol->Name[pSymbol->MaxNameLen - 1] = '\0'; - if(bUndecorateSymbolNames and !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) + if(!bUndecorateSymbolNames or !UnDecorateSymbolName(pSymbol->Name, label, MAX_SYM_NAME, UNDNAME_COMPLETE)) strcpy_s(label, pSymbol->Name); retval = true; } From 9c1e22800e077430987d7711028a53c7b19f1b62 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 8 Nov 2014 21:08:36 +0100 Subject: [PATCH 25/58] GUI: resolved issue #202 (separator feature in HexDump) --- x64_dbg_gui/Project/Src/BasicView/HexDump.cpp | 20 ++++++----- x64_dbg_gui/Project/Src/BasicView/HexDump.h | 1 + x64_dbg_gui/Project/Src/Gui/CPUDump.cpp | 36 +++++++++++++++++++ x64_dbg_gui/Project/Src/Gui/CPUStack.cpp | 2 ++ 4 files changed, 51 insertions(+), 8 deletions(-) diff --git a/x64_dbg_gui/Project/Src/BasicView/HexDump.cpp b/x64_dbg_gui/Project/Src/BasicView/HexDump.cpp index 584caed6b..31f9cf63a 100644 --- a/x64_dbg_gui/Project/Src/BasicView/HexDump.cpp +++ b/x64_dbg_gui/Project/Src/BasicView/HexDump.cpp @@ -267,26 +267,30 @@ void HexDump::printSelected(QPainter* painter, int_t rowBase, int rowOffset, int { if((col > 0) && ((col - 1) < mDescriptor.size())) { - int wI = 0; + ColumnDescriptor_t curDescriptor = mDescriptor.at(col - 1); int wBytePerRowCount = getBytePerRowCount(); int_t wRva = (rowBase + rowOffset) * wBytePerRowCount - mByteOffset; - int wItemPixWidth = getItemPixelWidth(mDescriptor.at(col - 1)); + int wItemPixWidth = getItemPixelWidth(curDescriptor); int wCharWidth = getCharWidth(); if(wItemPixWidth == wCharWidth) x += 4; - int wSelectionX; - int wSelectionWidth; - for(wI = 0; wI < mDescriptor.at(col - 1).itemCount; wI++) + for(int i = 0; i < curDescriptor.itemCount; i++) { - if(isSelected(wRva + wI * getSizeOf(mDescriptor.at(col - 1).data.itemSize)) == true) + int wSelectionX = x + i * wItemPixWidth; + if(isSelected(wRva + i * getSizeOf(curDescriptor.data.itemSize)) == true) { - wSelectionX = x + wI * wItemPixWidth; - wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth; + int wSelectionWidth = wItemPixWidth > w - (wSelectionX - x) ? w - (wSelectionX - x) : wItemPixWidth; wSelectionWidth = wSelectionWidth < 0 ? 0 : wSelectionWidth; painter->setPen(textColor); painter->fillRect(QRect(wSelectionX, y, wSelectionWidth, h), QBrush(selectionColor)); } + int separator = curDescriptor.separator; + if(i && separator && !(i % separator)) + { + painter->setPen(separatorColor); + painter->drawLine(wSelectionX, y, wSelectionX, y + h); + } } } } diff --git a/x64_dbg_gui/Project/Src/BasicView/HexDump.h b/x64_dbg_gui/Project/Src/BasicView/HexDump.h index 3dd4c1c77..9a1e28bf6 100644 --- a/x64_dbg_gui/Project/Src/BasicView/HexDump.h +++ b/x64_dbg_gui/Project/Src/BasicView/HexDump.h @@ -72,6 +72,7 @@ public: { bool isData; int itemCount; + int separator; DataDescriptor_t data; } ColumnDescriptor_t; diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp index dbaadba94..06be7061e 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp @@ -561,6 +561,7 @@ void CPUDump::hexAsciiSlot() wColDesc.isData = true; //hex byte wColDesc.itemCount = 16; + wColDesc.separator = 4; dDesc.itemSize = Byte; dDesc.byteMode = HexByte; wColDesc.data = dDesc; @@ -568,6 +569,7 @@ void CPUDump::hexAsciiSlot() wColDesc.isData = true; //ascii byte wColDesc.itemCount = 16; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -575,6 +577,7 @@ void CPUDump::hexAsciiSlot() wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -592,6 +595,7 @@ void CPUDump::hexUnicodeSlot() wColDesc.isData = true; //hex byte wColDesc.itemCount = 16; + wColDesc.separator = 4; dDesc.itemSize = Byte; dDesc.byteMode = HexByte; wColDesc.data = dDesc; @@ -599,6 +603,7 @@ void CPUDump::hexUnicodeSlot() wColDesc.isData = true; //unicode short wColDesc.itemCount = 8; + wColDesc.separator = 0; dDesc.itemSize = Word; dDesc.wordMode = UnicodeWord; wColDesc.data = dDesc; @@ -606,6 +611,7 @@ void CPUDump::hexUnicodeSlot() wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -623,6 +629,7 @@ void CPUDump::textAsciiSlot() wColDesc.isData = true; //ascii byte wColDesc.itemCount = 64; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -630,6 +637,7 @@ void CPUDump::textAsciiSlot() wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -647,6 +655,7 @@ void CPUDump::textUnicodeSlot() wColDesc.isData = true; //unicode short wColDesc.itemCount = 64; + wColDesc.separator = 0; dDesc.itemSize = Word; dDesc.wordMode = UnicodeWord; wColDesc.data = dDesc; @@ -654,6 +663,7 @@ void CPUDump::textUnicodeSlot() wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -671,12 +681,14 @@ void CPUDump::integerSignedShortSlot() wColDesc.isData = true; //signed short wColDesc.itemCount = 8; + wColDesc.separator = 0; wColDesc.data.itemSize = Word; wColDesc.data.wordMode = SignedDecWord; appendResetDescriptor(8 + charwidth * 55, "Signed short (16-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -694,12 +706,14 @@ void CPUDump::integerSignedLongSlot() wColDesc.isData = true; //signed long wColDesc.itemCount = 4; + wColDesc.separator = 0; wColDesc.data.itemSize = Dword; wColDesc.data.dwordMode = SignedDecDword; appendResetDescriptor(8 + charwidth * 47, "Signed long (32-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -717,12 +731,14 @@ void CPUDump::integerSignedLongLongSlot() wColDesc.isData = true; //signed long long wColDesc.itemCount = 2; + wColDesc.separator = 0; wColDesc.data.itemSize = Qword; wColDesc.data.qwordMode = SignedDecQword; appendResetDescriptor(8 + charwidth * 41, "Signed long long (64-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -740,12 +756,14 @@ void CPUDump::integerUnsignedShortSlot() wColDesc.isData = true; //unsigned short wColDesc.itemCount = 8; + wColDesc.separator = 0; wColDesc.data.itemSize = Word; wColDesc.data.wordMode = UnsignedDecWord; appendResetDescriptor(8 + charwidth * 47, "Unsigned short (16-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -763,12 +781,14 @@ void CPUDump::integerUnsignedLongSlot() wColDesc.isData = true; //unsigned long wColDesc.itemCount = 4; + wColDesc.separator = 0; wColDesc.data.itemSize = Dword; wColDesc.data.dwordMode = UnsignedDecDword; appendResetDescriptor(8 + charwidth * 43, "Unsigned long (32-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -786,12 +806,14 @@ void CPUDump::integerUnsignedLongLongSlot() wColDesc.isData = true; //unsigned long long wColDesc.itemCount = 2; + wColDesc.separator = 0; wColDesc.data.itemSize = Qword; wColDesc.data.qwordMode = UnsignedDecQword; appendResetDescriptor(8 + charwidth * 41, "Unsigned long long (64-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -809,12 +831,14 @@ void CPUDump::integerHexShortSlot() wColDesc.isData = true; //hex short wColDesc.itemCount = 8; + wColDesc.separator = 0; wColDesc.data.itemSize = Word; wColDesc.data.wordMode = HexWord; appendResetDescriptor(8 + charwidth * 34, "Hex short (16-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -832,12 +856,14 @@ void CPUDump::integerHexLongSlot() wColDesc.isData = true; //hex long wColDesc.itemCount = 4; + wColDesc.separator = 0; wColDesc.data.itemSize = Dword; wColDesc.data.dwordMode = HexDword; appendResetDescriptor(8 + charwidth * 35, "Hex long (32-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -855,12 +881,14 @@ void CPUDump::integerHexLongLongSlot() wColDesc.isData = true; //hex long long wColDesc.itemCount = 2; + wColDesc.separator = 0; wColDesc.data.itemSize = Qword; wColDesc.data.qwordMode = HexQword; appendResetDescriptor(8 + charwidth * 33, "Hex long long (64-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -878,12 +906,14 @@ void CPUDump::floatFloatSlot() wColDesc.isData = true; //float dword wColDesc.itemCount = 4; + wColDesc.separator = 0; wColDesc.data.itemSize = Dword; wColDesc.data.dwordMode = FloatDword; appendResetDescriptor(8 + charwidth * 55, "Float (32-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -901,12 +931,14 @@ void CPUDump::floatDoubleSlot() wColDesc.isData = true; //float qword wColDesc.itemCount = 2; + wColDesc.separator = 0; wColDesc.data.itemSize = Qword; wColDesc.data.qwordMode = DoubleQword; appendResetDescriptor(8 + charwidth * 47, "Double (64-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -924,12 +956,14 @@ void CPUDump::floatLongDoubleSlot() wColDesc.isData = true; //float qword wColDesc.itemCount = 2; + wColDesc.separator = 0; wColDesc.data.itemSize = Tword; wColDesc.data.twordMode = FloatTword; appendResetDescriptor(8 + charwidth * 59, "Long double (80-bit)", false, wColDesc); wColDesc.isData = false; //empty column wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; @@ -947,6 +981,7 @@ void CPUDump::addressSlot() wColDesc.isData = true; //void* wColDesc.itemCount = 1; + wColDesc.separator = 0; #ifdef _WIN64 wColDesc.data.itemSize = Qword; wColDesc.data.qwordMode = HexQword; @@ -958,6 +993,7 @@ void CPUDump::addressSlot() wColDesc.isData = false; //comments wColDesc.itemCount = 1; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; diff --git a/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp b/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp index 2994200d1..519a0825b 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUStack.cpp @@ -17,6 +17,7 @@ CPUStack::CPUStack(QWidget* parent) : HexDump(parent) wColDesc.isData = true; //void* wColDesc.itemCount = 1; + wColDesc.separator = 0; #ifdef _WIN64 wColDesc.data.itemSize = Qword; wColDesc.data.qwordMode = HexQword; @@ -28,6 +29,7 @@ CPUStack::CPUStack(QWidget* parent) : HexDump(parent) wColDesc.isData = false; //comments wColDesc.itemCount = 0; + wColDesc.separator = 0; dDesc.itemSize = Byte; dDesc.byteMode = AsciiByte; wColDesc.data = dDesc; From e7c15d2596aaf49fa0dbffb5bff62f8ce15a8678 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sun, 9 Nov 2014 00:44:25 +0100 Subject: [PATCH 26/58] DBG: fixed some bugs wirh printing the debug string + thread name + fixed SetThreadName --- x64_dbg_dbg/debugger.cpp | 98 +++++++++++++++---------------- x64_dbg_dbg/debugger.h | 1 + x64_dbg_dbg/debugger_commands.cpp | 6 +- x64_dbg_dbg/dynamicmem.h | 9 ++- 4 files changed, 58 insertions(+), 56 deletions(-) diff --git a/x64_dbg_dbg/debugger.cpp b/x64_dbg_dbg/debugger.cpp index dcc707ae7..d8e4c4796 100644 --- a/x64_dbg_dbg/debugger.cpp +++ b/x64_dbg_dbg/debugger.cpp @@ -115,6 +115,7 @@ void dbginit() exceptionNames.insert(std::make_pair(0x04242420, "CLRDBG_NOTIFICATION_EXCEPTION_CODE")); exceptionNames.insert(std::make_pair(0xE0434352, "CLR_EXCEPTION")); exceptionNames.insert(std::make_pair(0xE06D7363, "CPP_EH_EXCEPTION")); + exceptionNames.insert(std::make_pair(MS_VC_EXCEPTION, "MS_VC_EXCEPTION")); CloseHandle(CreateThread(0, 0, memMapThread, 0, 0, 0)); } @@ -1005,7 +1006,7 @@ static void cbOutputDebugString(OUTPUT_DEBUG_STRING_INFO* DebugString) break; } } - dprintf("DebugString: \"%s\"\n", DebugTextEscaped); + dprintf("DebugString: \"%s\"\n", DebugTextEscaped()); } } @@ -1066,63 +1067,58 @@ static void cbException(EXCEPTION_DEBUG_INFO* ExceptionData) } SetContextDataEx(hActiveThread, UE_CIP, (uint)ExceptionData->ExceptionRecord.ExceptionAddress); } - else if(ExceptionData->ExceptionRecord.ExceptionCode == 0x406D1388) //SetThreadName exception + else if(ExceptionData->ExceptionRecord.ExceptionCode == MS_VC_EXCEPTION) //SetThreadName exception { - if(ExceptionData->ExceptionRecord.NumberParameters == sizeof(THREADNAME_INFO) / sizeof(uint)) + THREADNAME_INFO nameInfo; + memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO)); + if(nameInfo.dwThreadID == -1) //current thread + nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; + if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and threadisvalid(nameInfo.dwThreadID)) //passed basic checks { - THREADNAME_INFO nameInfo; - memcpy(&nameInfo, ExceptionData->ExceptionRecord.ExceptionInformation, sizeof(THREADNAME_INFO)); - if(nameInfo.dwThreadID == -1) //current thread - nameInfo.dwThreadID = ((DEBUG_EVENT*)GetDebugData())->dwThreadId; - if(nameInfo.dwType == 0x1000 and nameInfo.dwFlags == 0 and threadisvalid(nameInfo.dwThreadID)) //passed basic checks + Memory ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName"); + if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0)) { - Memory ThreadName(MAX_THREAD_NAME_SIZE, "cbException:ThreadName"); - memset(ThreadName, 0, MAX_THREAD_NAME_SIZE); - if(memread(fdProcessInfo->hProcess, nameInfo.szName, ThreadName, MAX_THREAD_NAME_SIZE - 1, 0)) + int len = (int)strlen(ThreadName); + int escape_count = 0; + for(int i = 0; i < len; i++) + if(ThreadName[i] == '\\' or ThreadName[i] == '\"' or !isprint(ThreadName[i])) + escape_count++; + Memory ThreadNameEscaped(len + escape_count * 3 + 1, "cbException:ThreadNameEscaped"); + for(int i = 0, j = 0; i < len; i++) { - int len = (int)strlen(ThreadName); - int escape_count = 0; - for(int i = 0; i < len; i++) - if(ThreadName[i] == '\\' or ThreadName[i] == '\"' or !isprint(ThreadName[i])) - escape_count++; - Memory ThreadNameEscaped(len + escape_count * 3 + 1, "cbException:ThreadNameEscaped"); - memset(ThreadNameEscaped, 0, len + escape_count * 3 + 1); - for(int i = 0, j = 0; i < len; i++) + switch(ThreadName[i]) { - switch(ThreadName[i]) - { - case '\t': - j += sprintf(ThreadNameEscaped + j, "\\t"); - break; - case '\f': - j += sprintf(ThreadNameEscaped + j, "\\f"); - break; - case '\v': - j += sprintf(ThreadNameEscaped + j, "\\v"); - break; - case '\n': - j += sprintf(ThreadNameEscaped + j, "\\n"); - break; - case '\r': - j += sprintf(ThreadNameEscaped + j, "\\r"); - break; - case '\\': - j += sprintf(ThreadNameEscaped + j, "\\\\"); - break; - case '\"': - j += sprintf(ThreadNameEscaped + j, "\\\""); - break; - default: - if(!isprint(ThreadName[i])) //unknown unprintable character - j += sprintf(ThreadNameEscaped + j, "\\%.2x", ThreadName[i]); - else - j += sprintf(ThreadNameEscaped + j, "%c", ThreadName[i]); - break; - } + case '\t': + j += sprintf(ThreadNameEscaped + j, "\\t"); + break; + case '\f': + j += sprintf(ThreadNameEscaped + j, "\\f"); + break; + case '\v': + j += sprintf(ThreadNameEscaped + j, "\\v"); + break; + case '\n': + j += sprintf(ThreadNameEscaped + j, "\\n"); + break; + case '\r': + j += sprintf(ThreadNameEscaped + j, "\\r"); + break; + case '\\': + j += sprintf(ThreadNameEscaped + j, "\\\\"); + break; + case '\"': + j += sprintf(ThreadNameEscaped + j, "\\\""); + break; + default: + if(!isprint(ThreadName[i])) //unknown unprintable character + j += sprintf(ThreadNameEscaped + j, "\\%.2x", ThreadName[i]); + else + j += sprintf(ThreadNameEscaped + j, "%c", ThreadName[i]); + break; } - dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped); - threadsetname(nameInfo.dwThreadID, ThreadNameEscaped); } + dprintf("SetThreadName(%X, \"%s\")\n", nameInfo.dwThreadID, ThreadNameEscaped()); + threadsetname(nameInfo.dwThreadID, ThreadNameEscaped); } } } diff --git a/x64_dbg_dbg/debugger.h b/x64_dbg_dbg/debugger.h index 77a712d9c..acd69db05 100644 --- a/x64_dbg_dbg/debugger.h +++ b/x64_dbg_dbg/debugger.h @@ -12,6 +12,7 @@ #define JIT_ENTRY_DEF_SIZE (MAX_PATH + sizeof(ATTACH_CMD_LINE) + 2) #define JIT_ENTRY_MAX_SIZE 512 #define JIT_REG_KEY TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\AeDebug") +#define MS_VC_EXCEPTION 0x406D1388 typedef enum { diff --git a/x64_dbg_dbg/debugger_commands.cpp b/x64_dbg_dbg/debugger_commands.cpp index 629632d25..256faec06 100644 --- a/x64_dbg_dbg/debugger_commands.cpp +++ b/x64_dbg_dbg/debugger_commands.cpp @@ -199,17 +199,17 @@ CMDRESULT cbDebugSetBPX(int argc, char* argv[]) //bp addr [,name [,type]] } if(IsBPXEnabled(addr)) { - dprintf("error setting breakpoint at "fhex"!\n (IsBPXEnabled)", addr); + dprintf("error setting breakpoint at "fhex"! (IsBPXEnabled)\n", addr); return STATUS_ERROR; } else if(!memread(fdProcessInfo->hProcess, (void*)addr, &oldbytes, sizeof(short), 0)) { - dprintf("error setting breakpoint at "fhex"!\n (memread)", addr); + dprintf("error setting breakpoint at "fhex"! (memread)\n", addr); return STATUS_ERROR; } else if(!bpnew(addr, true, singleshoot, oldbytes, BPNORMAL, type, bpname)) { - dprintf("error setting breakpoint at "fhex"!\n (bpnew)", addr); + dprintf("error setting breakpoint at "fhex"! (bpnew)\n", addr); return STATUS_ERROR; } else if(!SetBPX(addr, type, (void*)cbUserBreakpoint)) diff --git a/x64_dbg_dbg/dynamicmem.h b/x64_dbg_dbg/dynamicmem.h index 7eab14dd3..1e251e444 100644 --- a/x64_dbg_dbg/dynamicmem.h +++ b/x64_dbg_dbg/dynamicmem.h @@ -1,7 +1,7 @@ #ifndef _DYNAMICMEM_H #define _DYNAMICMEM_H -template +template class Memory { public: @@ -34,7 +34,7 @@ public: return mPtr; } - template + template operator U() { return (U)mPtr; @@ -45,6 +45,11 @@ public: return mPtr; } + T operator()() + { + return mPtr; + } + size_t size() { return mSize; From 7e7f302dfc23094be7f9d1bc19aa736f0b96b9bc Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sun, 9 Nov 2014 22:52:17 +0100 Subject: [PATCH 27/58] DBG: some fixes in valfromstring (mathfromstring did not handle operations with spaces in them correctly) --- x64_dbg_dbg/math.cpp | 4 +++- x64_dbg_dbg/value.cpp | 17 +---------------- x64_dbg_dbg/value.h | 5 +---- 3 files changed, 5 insertions(+), 21 deletions(-) diff --git a/x64_dbg_dbg/math.cpp b/x64_dbg_dbg/math.cpp index 9d44cb0ae..fe9c671f3 100644 --- a/x64_dbg_dbg/math.cpp +++ b/x64_dbg_dbg/math.cpp @@ -383,7 +383,9 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly, memset(strright, 0, len + 1); strncpy(strleft, string - negative, highestop_pos + negative); strcpy(strright, string + highestop_pos + 1); - //dprintf("left: %s, right: %s, op: %c\n", strleft, strright, string[highestop_pos]); + strcpy(strleft, UString(strleft).Trim().c_str()); + strcpy(strright, UString(strright).Trim().c_str()); + //dprintf("left: %s, right: %s, op: %c\n", strleft(), strright(), string[highestop_pos]); if(!*strright) return false; uint right = 0; diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index d7258a828..88badbccd 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1452,7 +1452,7 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly, *isvar = true; return true; } - else if(isregister(string)) //re gister + else if(isregister(string)) //register { if(!DbgIsDebugging()) { @@ -1535,21 +1535,6 @@ bool valfromstring(const char* string, uint* value, bool silent, bool baseonly, return false; //nothing was OK } -bool valfromstring(const char* string, uint* value, bool silent, bool baseonly) -{ - return valfromstring(string, value, silent, baseonly, 0, 0, 0); -} - -bool valfromstring(const char* string, uint* value, bool silent) -{ - return valfromstring(string, value, silent, false); -} - -bool valfromstring(const char* string, uint* value) -{ - return valfromstring(string, value, true); -} - bool longEnough(const char* str, size_t min_length) { size_t length = 0; diff --git a/x64_dbg_dbg/value.h b/x64_dbg_dbg/value.h index 37ab02fac..ea0856da8 100644 --- a/x64_dbg_dbg/value.h +++ b/x64_dbg_dbg/value.h @@ -7,10 +7,7 @@ bool valuesignedcalc(); void valuesetsignedcalc(bool a); bool valapifromstring(const char* name, uint* value, int* value_size, bool printall, bool silent, bool* hexonly); -bool valfromstring(const char* string, uint* value, bool silent, bool baseonly, int* value_size, bool* isvar, bool* hexonly); -bool valfromstring(const char* string, uint* value, bool silent, bool baseonly); -bool valfromstring(const char* string, uint* value, bool silent); -bool valfromstring(const char* string, uint* value); +bool valfromstring(const char* string, uint* value, bool silent = true, bool baseonly = false, int* value_size = 0, bool* isvar = 0, bool* hexonly = 0); bool valflagfromstring(uint eflags, const char* string); bool valtostring(const char* string, uint* value, bool silent); bool valmxcsrflagfromstring(uint mxcsrflags, const char* string); From 12e30a4ea32c266a15cf0a902eed6c6ac9a71c06 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sun, 9 Nov 2014 23:35:52 +0100 Subject: [PATCH 28/58] DBG: resolved issue #212 (problems with maximum comment size) --- x64_dbg_dbg/_exports.cpp | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 5707ad469..92ccd992c 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -174,6 +174,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR { DISASM_INSTR instr; std::string temp_string; + std::string comment; ADDRINFO newinfo; char ascii[256 * 2] = ""; char unicode[256 * 2] = ""; @@ -181,7 +182,7 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR memset(&instr, 0, sizeof(DISASM_INSTR)); disasmget(addr, &instr); int len_left = MAX_COMMENT_SIZE; - for(int i = 0, j = 0; i < instr.argcount; i++) + for(int i = 0; i < instr.argcount; i++) { memset(&newinfo, 0, sizeof(ADDRINFO)); newinfo.flags = flaglabel; @@ -268,18 +269,16 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR else continue; - if(!strstr(addrinfo->comment, temp_string.c_str())) + if(!strstr(comment.c_str(), temp_string.c_str())) { - unsigned int maxlen = MAX_COMMENT_SIZE - j - 1; - if(maxlen < temp_string.length()) - temp_string.at(maxlen - 1) = 0; - if(j) - j += sprintf(addrinfo->comment + j, ", %s", temp_string.c_str()); - else - j += sprintf(addrinfo->comment + j, "%s", temp_string.c_str()); + if(comment.length()) + comment.append(", "); + comment.append(temp_string); retval = true; } } + comment.resize(MAX_COMMENT_SIZE - 1); + strcpy_s(addrinfo->comment, comment.c_str()); } } } From cc635db502bc0022886e4789e8c3ef65f686be8a Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sun, 9 Nov 2014 23:49:41 +0100 Subject: [PATCH 29/58] PROJECT: updated release script --- release.bat | 1 + 1 file changed, 1 insertion(+) diff --git a/release.bat b/release.bat index 1bf2e4f18..92f203258 100644 --- a/release.bat +++ b/release.bat @@ -1,5 +1,6 @@ @echo off set RELEASEDIR=.\release +rmdir /S /Q %RELEASEDIR% mkdir %RELEASEDIR% echo qt_base From 6cc28a1c9533dc63cef3ba265be3264da7746970 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 10 Nov 2014 12:20:16 +0100 Subject: [PATCH 30/58] GUI: better register view code, no more working with offset + X --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 436 +++++++++--------- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 4 +- 2 files changed, 221 insertions(+), 219 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index ef117e3a6..a17bff8b9 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -9,7 +9,7 @@ void RegistersView::SetChangeButton(QPushButton* push_button) { - button = push_button; + mChangeViewButton = push_button; } void RegistersView::InitMappings() @@ -25,344 +25,346 @@ void RegistersView::InitMappings() */ #ifdef _WIN64 mRegisterMapping.insert(CAX, "RAX"); - mRegisterPlaces.insert(CAX, Register_Position(0, 0, 6, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(CAX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CBX, "RBX"); - mRegisterPlaces.insert(CBX, Register_Position(1, 0, 6, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(CBX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CCX, "RCX"); - mRegisterPlaces.insert(CCX, Register_Position(2, 0, 6, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(CCX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CDX, "RDX"); - mRegisterPlaces.insert(CDX, Register_Position(3, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSI, "RSI"); - mRegisterPlaces.insert(CSI, Register_Position(6, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDI, "RDI"); - mRegisterPlaces.insert(CDI, Register_Position(7, 0, 6, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(CDX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CBP, "RBP"); - mRegisterPlaces.insert(CBP, Register_Position(4, 0, 6, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(CBP, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); mRegisterMapping.insert(CSP, "RSP"); - mRegisterPlaces.insert(CSP, Register_Position(5, 0, 6, sizeof(uint_t) * 2)); - - mRegisterMapping.insert(R8, "R8"); - mRegisterPlaces.insert(R8 , Register_Position(9, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R9, "R9"); - mRegisterPlaces.insert(R9 , Register_Position(10, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R10, "R10"); - mRegisterPlaces.insert(R10, Register_Position(11, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R11, "R11"); - mRegisterPlaces.insert(R11, Register_Position(12, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R12, "R12"); - mRegisterPlaces.insert(R12, Register_Position(13, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R13, "R13"); - mRegisterPlaces.insert(R13, Register_Position(14, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R14, "R14"); - mRegisterPlaces.insert(R14, Register_Position(15, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(R15, "R15"); - mRegisterPlaces.insert(R15, Register_Position(16, 0, 6, sizeof(uint_t) * 2)); - - mRegisterMapping.insert(CIP, "RIP"); - mRegisterPlaces.insert(CIP, Register_Position(18, 0, 6, sizeof(uint_t) * 2)); - - mRegisterMapping.insert(EFLAGS, "RFLAGS"); - mRegisterPlaces.insert(EFLAGS, Register_Position(20, 0, 9, sizeof(uint_t) * 2)); - - offset = 21; -#else - mRegisterMapping.insert(CAX, "EAX"); - mRegisterPlaces.insert(CAX, Register_Position(0, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CBX, "EBX"); - mRegisterPlaces.insert(CBX, Register_Position(1, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CCX, "ECX"); - mRegisterPlaces.insert(CCX, Register_Position(2, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDX, "EDX"); - mRegisterPlaces.insert(CDX, Register_Position(3, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSI, "ESI"); - mRegisterPlaces.insert(CSI, Register_Position(6, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CDI, "EDI"); - mRegisterPlaces.insert(CDI, Register_Position(7, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CBP, "EBP"); - mRegisterPlaces.insert(CBP, Register_Position(4, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CSP, "ESP"); - mRegisterPlaces.insert(CSP, Register_Position(5, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(CIP, "EIP"); - mRegisterPlaces.insert(CIP, Register_Position(9, 0, 6, sizeof(uint_t) * 2)); - mRegisterMapping.insert(EFLAGS, "EFLAGS"); - mRegisterPlaces.insert(EFLAGS, Register_Position(11, 0, 9, sizeof(uint_t) * 2)); - - offset = 12; -#endif - mRegisterMapping.insert(ZF, "ZF"); - mRegisterPlaces.insert(ZF, Register_Position(offset + 0, 0, 3, 1)); - mRegisterMapping.insert(OF, "OF"); - mRegisterPlaces.insert(OF, Register_Position(offset + 1, 0, 3, 1)); - mRegisterMapping.insert(CF, "CF"); - mRegisterPlaces.insert(CF, Register_Position(offset + 2, 0, 3, 1)); - - mRegisterMapping.insert(PF, "PF"); - mRegisterPlaces.insert(PF, Register_Position(offset + 0, 6, 3, 1)); - mRegisterMapping.insert(SF, "SF"); - mRegisterPlaces.insert(SF, Register_Position(offset + 1, 6, 3, 1)); - mRegisterMapping.insert(TF, "TF"); - mRegisterPlaces.insert(TF, Register_Position(offset + 2, 6, 3, 1)); - - mRegisterMapping.insert(AF, "AF"); - mRegisterPlaces.insert(AF, Register_Position(offset + 0, 12, 3, 1)); - mRegisterMapping.insert(DF, "DF"); - mRegisterPlaces.insert(DF, Register_Position(offset + 1, 12, 3, 1)); - mRegisterMapping.insert(IF, "IF"); - mRegisterPlaces.insert(IF, Register_Position(offset + 2, 12, 3, 1)); + mRegisterPlaces.insert(CSP, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSI, "RSI"); + mRegisterPlaces.insert(CSI, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDI, "RDI"); + mRegisterPlaces.insert(CDI, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); offset++; + + mRegisterMapping.insert(R8, "R8"); + mRegisterPlaces.insert(R8 , Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R9, "R9"); + mRegisterPlaces.insert(R9 , Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R10, "R10"); + mRegisterPlaces.insert(R10, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R11, "R11"); + mRegisterPlaces.insert(R11, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R12, "R12"); + mRegisterPlaces.insert(R12, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R13, "R13"); + mRegisterPlaces.insert(R13, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R14, "R14"); + mRegisterPlaces.insert(R14, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(R15, "R15"); + mRegisterPlaces.insert(R15, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + + offset++; + + mRegisterMapping.insert(CIP, "RIP"); + mRegisterPlaces.insert(CIP, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + + offset++; + + mRegisterMapping.insert(EFLAGS, "RFLAGS"); + mRegisterPlaces.insert(EFLAGS, Register_Position(offset++, 0, 9, sizeof(uint_t) * 2)); +#else //x32 + mRegisterMapping.insert(CAX, "EAX"); + mRegisterPlaces.insert(CAX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CBX, "EBX"); + mRegisterPlaces.insert(CBX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CCX, "ECX"); + mRegisterPlaces.insert(CCX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDX, "EDX"); + mRegisterPlaces.insert(CDX, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CBP, "EBP"); + mRegisterPlaces.insert(CBP, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSP, "ESP"); + mRegisterPlaces.insert(CSP, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CSI, "ESI"); + mRegisterPlaces.insert(CSI, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + mRegisterMapping.insert(CDI, "EDI"); + mRegisterPlaces.insert(CDI, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + + offset++; + + mRegisterMapping.insert(CIP, "EIP"); + mRegisterPlaces.insert(CIP, Register_Position(offset++, 0, 6, sizeof(uint_t) * 2)); + + offset++; + + mRegisterMapping.insert(EFLAGS, "EFLAGS"); + mRegisterPlaces.insert(EFLAGS, Register_Position(offset++, 0, 9, sizeof(uint_t) * 2)); +#endif + + mRegisterMapping.insert(ZF, "ZF"); + mRegisterPlaces.insert(ZF, Register_Position(offset, 0, 3, 1)); + mRegisterMapping.insert(PF, "PF"); + mRegisterPlaces.insert(PF, Register_Position(offset, 6, 3, 1)); + mRegisterMapping.insert(AF, "AF"); + mRegisterPlaces.insert(AF, Register_Position(offset++, 12, 3, 1)); + + mRegisterMapping.insert(OF, "OF"); + mRegisterPlaces.insert(OF, Register_Position(offset, 0, 3, 1)); + mRegisterMapping.insert(SF, "SF"); + mRegisterPlaces.insert(SF, Register_Position(offset, 6, 3, 1)); + mRegisterMapping.insert(DF, "DF"); + mRegisterPlaces.insert(DF, Register_Position(offset++, 12, 3, 1)); + + mRegisterMapping.insert(CF, "CF"); + mRegisterPlaces.insert(CF, Register_Position(offset, 0, 3, 1)); + mRegisterMapping.insert(TF, "TF"); + mRegisterPlaces.insert(TF, Register_Position(offset, 6, 3, 1)); + mRegisterMapping.insert(IF, "IF"); + mRegisterPlaces.insert(IF, Register_Position(offset++, 12, 3, 1)); + + offset++; + mRegisterMapping.insert(GS, "GS"); - mRegisterPlaces.insert(GS, Register_Position(offset + 3, 0, 3, 4)); - mRegisterMapping.insert(ES, "ES"); - mRegisterPlaces.insert(ES, Register_Position(offset + 4, 0, 3, 4)); - mRegisterMapping.insert(CS, "CS"); - mRegisterPlaces.insert(CS, Register_Position(offset + 5, 0, 3, 4)); - + mRegisterPlaces.insert(GS, Register_Position(offset, 0, 3, 4)); mRegisterMapping.insert(FS, "FS"); - mRegisterPlaces.insert(FS, Register_Position(offset + 3, 9, 3, 4)); + mRegisterPlaces.insert(FS, Register_Position(offset++, 9, 3, 4)); + mRegisterMapping.insert(ES, "ES"); + mRegisterPlaces.insert(ES, Register_Position(offset, 0, 3, 4)); mRegisterMapping.insert(DS, "DS"); - mRegisterPlaces.insert(DS, Register_Position(offset + 4, 9, 3, 4)); + mRegisterPlaces.insert(DS, Register_Position(offset++, 9, 3, 4)); + mRegisterMapping.insert(CS, "CS"); + mRegisterPlaces.insert(CS, Register_Position(offset, 0, 3, 4)); mRegisterMapping.insert(SS, "SS"); - mRegisterPlaces.insert(SS, Register_Position(offset + 5, 9, 3, 4)); + mRegisterPlaces.insert(SS, Register_Position(offset++, 9, 3, 4)); - if(showfpu) + if(mShowFpu) { offset++; mRegisterMapping.insert(x87r0, "x87r0"); - mRegisterPlaces.insert(x87r0, Register_Position(offset + 6, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r0, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r1, "x87r1"); - mRegisterPlaces.insert(x87r1, Register_Position(offset + 7, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r1, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r2, "x87r2"); - mRegisterPlaces.insert(x87r2, Register_Position(offset + 8, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r2, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r3, "x87r3"); - mRegisterPlaces.insert(x87r3, Register_Position(offset + 9, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r3, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r4, "x87r4"); - mRegisterPlaces.insert(x87r4, Register_Position(offset + 10, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r4, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r5, "x87r5"); - mRegisterPlaces.insert(x87r5, Register_Position(offset + 11, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r5, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r6, "x87r6"); - mRegisterPlaces.insert(x87r6, Register_Position(offset + 12, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r6, Register_Position(offset++, 0, 6, 10 * 2)); mRegisterMapping.insert(x87r7, "x87r7"); - mRegisterPlaces.insert(x87r7, Register_Position(offset + 13, 0, 6, 10 * 2)); + mRegisterPlaces.insert(x87r7, Register_Position(offset++, 0, 6, 10 * 2)); offset++; + mRegisterMapping.insert(x87TagWord, "x87TagWord"); - mRegisterPlaces.insert(x87TagWord, Register_Position(offset + 14, 0, 11, sizeof(WORD) * 2)); + mRegisterPlaces.insert(x87TagWord, Register_Position(offset++, 0, 11, sizeof(WORD) * 2)); mRegisterMapping.insert(x87TW_0, "x87TW_0"); - mRegisterPlaces.insert(x87TW_0, Register_Position(offset + 15, 0, 8, 10)); + mRegisterPlaces.insert(x87TW_0, Register_Position(offset, 0, 8, 10)); mRegisterMapping.insert(x87TW_1, "x87TW_1"); - mRegisterPlaces.insert(x87TW_1, Register_Position(offset + 15, 20, 8, 10)); + mRegisterPlaces.insert(x87TW_1, Register_Position(offset++, 20, 8, 10)); mRegisterMapping.insert(x87TW_2, "x87TW_2"); - mRegisterPlaces.insert(x87TW_2, Register_Position(offset + 16, 0, 8, 10)); + mRegisterPlaces.insert(x87TW_2, Register_Position(offset, 0, 8, 10)); mRegisterMapping.insert(x87TW_3, "x87TW_3"); - mRegisterPlaces.insert(x87TW_3, Register_Position(offset + 16, 20, 8, 10)); + mRegisterPlaces.insert(x87TW_3, Register_Position(offset++, 20, 8, 10)); mRegisterMapping.insert(x87TW_4, "x87TW_4"); - mRegisterPlaces.insert(x87TW_4, Register_Position(offset + 17, 0, 8, 10)); + mRegisterPlaces.insert(x87TW_4, Register_Position(offset, 0, 8, 10)); mRegisterMapping.insert(x87TW_5, "x87TW_5"); - mRegisterPlaces.insert(x87TW_5, Register_Position(offset + 17, 20, 8, 10)); + mRegisterPlaces.insert(x87TW_5, Register_Position(offset++, 20, 8, 10)); mRegisterMapping.insert(x87TW_6, "x87TW_6"); - mRegisterPlaces.insert(x87TW_6, Register_Position(offset + 18, 0, 8, 10)); + mRegisterPlaces.insert(x87TW_6, Register_Position(offset, 0, 8, 10)); mRegisterMapping.insert(x87TW_7, "x87TW_7"); - mRegisterPlaces.insert(x87TW_7, Register_Position(offset + 18, 20, 8, 10)); - - offset += 4; + mRegisterPlaces.insert(x87TW_7, Register_Position(offset++, 20, 8, 10)); offset++; + mRegisterMapping.insert(x87StatusWord, "x87StatusWord"); - mRegisterPlaces.insert(x87StatusWord, Register_Position(offset + 15, 0, 14, sizeof(WORD) * 2)); + mRegisterPlaces.insert(x87StatusWord, Register_Position(offset++, 0, 14, sizeof(WORD) * 2)); mRegisterMapping.insert(x87SW_B, "x87SW_B"); - mRegisterPlaces.insert(x87SW_B, Register_Position(offset + 16, 0, 9, 1)); + mRegisterPlaces.insert(x87SW_B, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87SW_C3, "x87SW_C3"); - mRegisterPlaces.insert(x87SW_C3, Register_Position(offset + 16, 12, 10, 1)); + mRegisterPlaces.insert(x87SW_C3, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87SW_C2, "x87SW_C2"); - mRegisterPlaces.insert(x87SW_C2, Register_Position(offset + 16, 25, 10, 1)); + mRegisterPlaces.insert(x87SW_C2, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(x87SW_C1, "x87SW_C1"); - mRegisterPlaces.insert(x87SW_C1, Register_Position(offset + 17, 0, 9, 1)); + mRegisterPlaces.insert(x87SW_C1, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87SW_C0, "x87SW_C0"); - mRegisterPlaces.insert(x87SW_C0, Register_Position(offset + 17, 12, 10, 1)); + mRegisterPlaces.insert(x87SW_C0, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87SW_IR, "x87SW_IR"); - mRegisterPlaces.insert(x87SW_IR, Register_Position(offset + 17, 25, 10, 1)); + mRegisterPlaces.insert(x87SW_IR, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(x87SW_SF, "x87SW_SF"); - mRegisterPlaces.insert(x87SW_SF, Register_Position(offset + 18, 0, 9, 1)); + mRegisterPlaces.insert(x87SW_SF, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87SW_P, "x87SW_P"); - mRegisterPlaces.insert(x87SW_P, Register_Position(offset + 18, 12, 10, 1)); + mRegisterPlaces.insert(x87SW_P, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87SW_U, "x87SW_U"); - mRegisterPlaces.insert(x87SW_U, Register_Position(offset + 18, 25, 10, 1)); + mRegisterPlaces.insert(x87SW_U, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(x87SW_O, "x87SW_O"); - mRegisterPlaces.insert(x87SW_O, Register_Position(offset + 19, 0, 9, 1)); + mRegisterPlaces.insert(x87SW_O, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87SW_Z, "x87SW_Z"); - mRegisterPlaces.insert(x87SW_Z, Register_Position(offset + 19, 12, 10, 1)); + mRegisterPlaces.insert(x87SW_Z, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87SW_D, "x87SW_D"); - mRegisterPlaces.insert(x87SW_D, Register_Position(offset + 19, 25, 10, 1)); + mRegisterPlaces.insert(x87SW_D, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(x87SW_I, "x87SW_I"); - mRegisterPlaces.insert(x87SW_I, Register_Position(offset + 20, 0, 9, 1)); + mRegisterPlaces.insert(x87SW_I, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87SW_TOP, "x87SW_TOP"); - mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset + 20, 12, 10, 13)); + mRegisterPlaces.insert(x87SW_TOP, Register_Position(offset++, 12, 10, 13)); offset++; mRegisterMapping.insert(x87ControlWord, "x87ControlWord"); - mRegisterPlaces.insert(x87ControlWord, Register_Position(offset + 21, 0, 15, sizeof(WORD) * 2)); + mRegisterPlaces.insert(x87ControlWord, Register_Position(offset++, 0, 15, sizeof(WORD) * 2)); mRegisterMapping.insert(x87CW_IC, "x87CW_IC"); - mRegisterPlaces.insert(x87CW_IC, Register_Position(offset + 22, 0, 9, 1)); + mRegisterPlaces.insert(x87CW_IC, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87CW_IEM, "x87CW_IEM"); - mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset + 22, 12, 10, 1)); + mRegisterPlaces.insert(x87CW_IEM, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87CW_PM, "x87CW_PM"); - mRegisterPlaces.insert(x87CW_PM, Register_Position(offset + 22, 25, 10, 1)); + mRegisterPlaces.insert(x87CW_PM, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(x87CW_UM, "x87CW_UM"); - mRegisterPlaces.insert(x87CW_UM, Register_Position(offset + 23, 0, 9, 1)); + mRegisterPlaces.insert(x87CW_UM, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87CW_OM, "x87CW_OM"); - mRegisterPlaces.insert(x87CW_OM, Register_Position(offset + 23, 12, 10, 1)); + mRegisterPlaces.insert(x87CW_OM, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87CW_ZM, "x87CW_ZM"); - mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset + 23, 25, 10, 1)); + mRegisterPlaces.insert(x87CW_ZM, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(x87CW_DM, "x87CW_DM"); - mRegisterPlaces.insert(x87CW_DM, Register_Position(offset + 24, 0, 9, 1)); + mRegisterPlaces.insert(x87CW_DM, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(x87CW_IM, "x87CW_IM"); - mRegisterPlaces.insert(x87CW_IM, Register_Position(offset + 24, 12, 10, 1)); + mRegisterPlaces.insert(x87CW_IM, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(x87CW_RC, "x87CW_RC"); - mRegisterPlaces.insert(x87CW_RC, Register_Position(offset + 24, 25, 10, 14)); + mRegisterPlaces.insert(x87CW_RC, Register_Position(offset++, 25, 10, 14)); mRegisterMapping.insert(x87CW_PC, "x87CW_PC"); - mRegisterPlaces.insert(x87CW_PC, Register_Position(offset + 25, 0, 9, 14)); + mRegisterPlaces.insert(x87CW_PC, Register_Position(offset++, 0, 9, 14)); offset++; mRegisterMapping.insert(MxCsr, "MxCsr"); - mRegisterPlaces.insert(MxCsr, Register_Position(offset + 26, 0, 6, sizeof(DWORD) * 2)); + mRegisterPlaces.insert(MxCsr, Register_Position(offset++, 0, 6, sizeof(DWORD) * 2)); mRegisterMapping.insert(MxCsr_FZ, "MxCsr_FZ"); - mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset + 27, 0, 9, 1)); + mRegisterPlaces.insert(MxCsr_FZ, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(MxCsr_PM, "MxCsr_PM"); - mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset + 27, 12, 10, 1)); + mRegisterPlaces.insert(MxCsr_PM, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(MxCsr_UM, "MxCsr_UM"); - mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset + 27, 25, 10, 1)); + mRegisterPlaces.insert(MxCsr_UM, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(MxCsr_OM, "MxCsr_OM"); - mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset + 28, 0, 9, 1)); + mRegisterPlaces.insert(MxCsr_OM, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(MxCsr_ZM, "MxCsr_ZM"); - mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset + 28, 12, 10, 1)); + mRegisterPlaces.insert(MxCsr_ZM, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(MxCsr_IM, "MxCsr_IM"); - mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset + 28, 25, 10, 1)); + mRegisterPlaces.insert(MxCsr_IM, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(MxCsr_UE, "MxCsr_UE"); - mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset + 29, 0, 9, 1)); + mRegisterPlaces.insert(MxCsr_UE, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(MxCsr_PE, "MxCsr_PE"); - mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset + 29, 12, 10, 1)); + mRegisterPlaces.insert(MxCsr_PE, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(MxCsr_DAZ, "MxCsr_DAZ"); - mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset + 29, 25, 10, 1)); + mRegisterPlaces.insert(MxCsr_DAZ, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(MxCsr_OE, "MxCsr_OE"); - mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset + 30, 0, 9, 1)); + mRegisterPlaces.insert(MxCsr_OE, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(MxCsr_ZE, "MxCsr_ZE"); - mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset + 30, 12, 10, 1)); + mRegisterPlaces.insert(MxCsr_ZE, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(MxCsr_DE, "MxCsr_DE"); - mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset + 30, 25, 10, 1)); + mRegisterPlaces.insert(MxCsr_DE, Register_Position(offset++, 25, 10, 1)); mRegisterMapping.insert(MxCsr_IE, "MxCsr_IE"); - mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset + 31, 0, 9, 1)); + mRegisterPlaces.insert(MxCsr_IE, Register_Position(offset, 0, 9, 1)); mRegisterMapping.insert(MxCsr_DM, "MxCsr_DM"); - mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset + 31, 12, 10, 1)); + mRegisterPlaces.insert(MxCsr_DM, Register_Position(offset, 12, 10, 1)); mRegisterMapping.insert(MxCsr_RC, "MxCsr_RC"); - mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset + 31, 25, 10, 19)); + mRegisterPlaces.insert(MxCsr_RC, Register_Position(offset++, 25, 10, 19)); offset++; mRegisterMapping.insert(MM0, "MM0"); - mRegisterPlaces.insert(MM0, Register_Position(offset + 32, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM0, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM1, "MM1"); - mRegisterPlaces.insert(MM1, Register_Position(offset + 33, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM1, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM2, "MM2"); - mRegisterPlaces.insert(MM2, Register_Position(offset + 34, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM2, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM3, "MM3"); - mRegisterPlaces.insert(MM3, Register_Position(offset + 35, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM3, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM4, "MM4"); - mRegisterPlaces.insert(MM4, Register_Position(offset + 36, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM4, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM5, "MM5"); - mRegisterPlaces.insert(MM5, Register_Position(offset + 37, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM5, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM6, "MM6"); - mRegisterPlaces.insert(MM6, Register_Position(offset + 38, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM6, Register_Position(offset++, 0, 4, 8 * 2)); mRegisterMapping.insert(MM7, "MM7"); - mRegisterPlaces.insert(MM7, Register_Position(offset + 39, 0, 4, 8 * 2)); + mRegisterPlaces.insert(MM7, Register_Position(offset++, 0, 4, 8 * 2)); + + offset++; + + mRegisterMapping.insert(XMM0, "XMM0"); + mRegisterPlaces.insert(XMM0, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM1, "XMM1"); + mRegisterPlaces.insert(XMM1, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM2, "XMM2"); + mRegisterPlaces.insert(XMM2, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM3, "XMM3"); + mRegisterPlaces.insert(XMM3, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM4, "XMM4"); + mRegisterPlaces.insert(XMM4, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM5, "XMM5"); + mRegisterPlaces.insert(XMM5, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM6, "XMM6"); + mRegisterPlaces.insert(XMM6, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM7, "XMM7"); + mRegisterPlaces.insert(XMM7, Register_Position(offset++, 0, 6, 16 * 2)); +#ifdef _WIN64 + mRegisterMapping.insert(XMM8, "XMM8"); + mRegisterPlaces.insert(XMM8, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM9, "XMM9"); + mRegisterPlaces.insert(XMM9, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM10, "XMM10"); + mRegisterPlaces.insert(XMM10, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM11, "XMM11"); + mRegisterPlaces.insert(XMM11, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM12, "XMM12"); + mRegisterPlaces.insert(XMM12, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM13, "XMM13"); + mRegisterPlaces.insert(XMM13, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM14, "XMM14"); + mRegisterPlaces.insert(XMM14, Register_Position(offset++, 0, 6, 16 * 2)); + mRegisterMapping.insert(XMM15, "XMM15"); + mRegisterPlaces.insert(XMM15, Register_Position(offset++, 0, 6, 16 * 2)); +#endif } - else - offset -= 34; offset++; mRegisterMapping.insert(DR0, "DR0"); - mRegisterPlaces.insert(DR0, Register_Position(offset + 40, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR0, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR1, "DR1"); - mRegisterPlaces.insert(DR1, Register_Position(offset + 41, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR1, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR2, "DR2"); - mRegisterPlaces.insert(DR2, Register_Position(offset + 42, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR2, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR3, "DR3"); - mRegisterPlaces.insert(DR3, Register_Position(offset + 43, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR3, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR6, "DR6"); - mRegisterPlaces.insert(DR6, Register_Position(offset + 44, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR6, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR7, "DR7"); - mRegisterPlaces.insert(DR7, Register_Position(offset + 45, 0, 4, sizeof(uint_t) * 2)); + mRegisterPlaces.insert(DR7, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); - if(showfpu) - { - offset++; - - mRegisterMapping.insert(XMM0, "XMM0"); - mRegisterPlaces.insert(XMM0, Register_Position(offset + 46, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM1, "XMM1"); - mRegisterPlaces.insert(XMM1, Register_Position(offset + 47, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM2, "XMM2"); - mRegisterPlaces.insert(XMM2, Register_Position(offset + 48, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM3, "XMM3"); - mRegisterPlaces.insert(XMM3, Register_Position(offset + 49, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM4, "XMM4"); - mRegisterPlaces.insert(XMM4, Register_Position(offset + 50, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM5, "XMM5"); - mRegisterPlaces.insert(XMM5, Register_Position(offset + 51, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM6, "XMM6"); - mRegisterPlaces.insert(XMM6, Register_Position(offset + 52, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM7, "XMM7"); - mRegisterPlaces.insert(XMM7, Register_Position(offset + 53, 0, 6, 16 * 2)); - -#ifdef _WIN64 - mRegisterMapping.insert(XMM8, "XMM8"); - mRegisterPlaces.insert(XMM8, Register_Position(offset + 54, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM9, "XMM9"); - mRegisterPlaces.insert(XMM9, Register_Position(offset + 55, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM10, "XMM10"); - mRegisterPlaces.insert(XMM10, Register_Position(offset + 56, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM11, "XMM11"); - mRegisterPlaces.insert(XMM11, Register_Position(offset + 57, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM12, "XMM12"); - mRegisterPlaces.insert(XMM12, Register_Position(offset + 58, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM13, "XMM13"); - mRegisterPlaces.insert(XMM13, Register_Position(offset + 59, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM14, "XMM14"); - mRegisterPlaces.insert(XMM14, Register_Position(offset + 60, 0, 6, 16 * 2)); - mRegisterMapping.insert(XMM15, "XMM15"); - mRegisterPlaces.insert(XMM15, Register_Position(offset + 61, 0, 6, 16 * 2)); -#endif - } - - mRowsNeeded = offset + 16; - mRowsNeeded++; + mRowsNeeded = offset + 1; } RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOffset(0) { - button = NULL; + mChangeViewButton = NULL; // precreate ContextMenu Actions wCM_Increment = new QAction(tr("Increment"), this); @@ -1063,7 +1065,7 @@ void RegistersView::fontsUpdatedSlot() void RegistersView::ShowFPU(bool set_showfpu) { - showfpu = set_showfpu; + mShowFpu = set_showfpu; InitMappings(); repaint(); } @@ -1157,12 +1159,12 @@ void RegistersView::paintEvent(QPaintEvent* event) { Q_UNUSED(event); - if(button != NULL) + if(mChangeViewButton != NULL) { - if(showfpu) - button->setText("Show Only General Registers"); + if(mShowFpu) + mChangeViewButton->setText("Hide FPU"); else - button->setText("Show FPU"); + mChangeViewButton->setText("Show FPU"); } QPainter wPainter(this->viewport()); @@ -1982,7 +1984,7 @@ void RegistersView::onFollowInStack() void RegistersView::onChangeFPUViewAction() { - if(showfpu == true) + if(mShowFpu == true) ShowFPU(false); else ShowFPU(true); diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 9214fbd9d..26e72b3b0 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -150,8 +150,8 @@ protected slots: QString GetStatusWordTOPStateString(unsigned short state); private: - QPushButton* button; - bool showfpu; + QPushButton* mChangeViewButton; + bool mShowFpu; int mVScrollOffset; int mRowsNeeded; int yTopSpacing; From 3394b99aa7104b651e55ab51f1e8d27162eb82fe Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 10 Nov 2014 12:44:42 +0100 Subject: [PATCH 31/58] DBG+GUI+BRIDGE+LAUNCHER: fixed various bugs (thanks to Coverity!) --- x64_dbg_bridge/bridgemain.cpp | 2 +- x64_dbg_bridge/simpleini.h | 3 ++- x64_dbg_dbg/UString/String.cpp | 17 +++++++++-------- x64_dbg_dbg/value.cpp | 2 +- x64_dbg_gui/Project/Src/Gui/CPUWidget.h | 1 - x64_dbg_gui/Project/Src/Gui/MainWindow.cpp | 2 +- x64_dbg_launcher/x64_dbg_launcher.cpp | 2 +- 7 files changed, 15 insertions(+), 14 deletions(-) diff --git a/x64_dbg_bridge/bridgemain.cpp b/x64_dbg_bridge/bridgemain.cpp index 8c825d705..aed60351e 100644 --- a/x64_dbg_bridge/bridgemain.cpp +++ b/x64_dbg_bridge/bridgemain.cpp @@ -40,7 +40,7 @@ BRIDGE_IMPEXP const char* BridgeInit() if(szIniFile[len] == L'\\') wcscat_s(szIniFile, L".ini"); else - wcscpy_s(&szIniFile[len], sizeof(szIniFile) - len, L".ini"); + wcscpy_s(&szIniFile[len], _countof(szIniFile) - len, L".ini"); HINSTANCE hInst; const char* szLib; diff --git a/x64_dbg_bridge/simpleini.h b/x64_dbg_bridge/simpleini.h index 5df0c3649..3fddf4044 100644 --- a/x64_dbg_bridge/simpleini.h +++ b/x64_dbg_bridge/simpleini.h @@ -2070,7 +2070,8 @@ CSimpleIniTempl::AddEntry( { DeleteString(a_pComment); a_pComment = pComment; - CopyString(a_pComment); + rc = CopyString(a_pComment); + if(rc < 0) return rc; } Delete(a_pSection, a_pKey); iKey = keyval.end(); diff --git a/x64_dbg_dbg/UString/String.cpp b/x64_dbg_dbg/UString/String.cpp index 299f6da20..3a80cdaa4 100644 --- a/x64_dbg_dbg/UString/String.cpp +++ b/x64_dbg_dbg/UString/String.cpp @@ -65,7 +65,7 @@ UTF8::String UTF8::String::FromFile(const UTF8::String & Path) File.read(buf, Length); s.AppendString(buf); - delete buf; + delete[] buf; } else { @@ -94,7 +94,7 @@ long UTF8::String::Search(const UTF8::String & SubString, unsigned int StartPosi } } - if(n < 0) + if((int)n < 0) { if(Direction == SearchDirectionFromRightToLeft) { @@ -106,12 +106,11 @@ long UTF8::String::Search(const UTF8::String & SubString, unsigned int StartPosi } } - while(((Direction == SearchDirectionFromLeftToRight) && (n < Length() - SubstringLength + 1)) || ((Direction == SearchDirectionFromRightToLeft) && (n >= 0))) + while(((Direction == SearchDirectionFromLeftToRight) && (n < Length() - SubstringLength + 1)) || ((Direction == SearchDirectionFromRightToLeft) && ((int)n >= 0))) { if(this->Substring(n, SubstringLength) == SubString) { - return n; } @@ -390,7 +389,7 @@ void UTF8::String::ConvertFromInt64(int64_t n) n /= 10; i--; - if((i < 0) || ((i < 1) && minus)) + if(((int)i < 0) || ((i < 1) && minus)) { throw Exception("[ConvertFromInt] Cycle terminated, buffer overflow."); } @@ -492,7 +491,7 @@ UTF8::String UTF8::String::Substring(unsigned int Start, unsigned int Count) con tmp[CopyAmount] = 0; UTF8::String r(tmp); - delete tmp; + delete[] tmp; return r; } @@ -559,7 +558,7 @@ void UTF8::String::ConvertFromUTF32(const uint32_t* s) SetString(tmp); - delete tmp; + delete[] tmp; } } @@ -680,7 +679,7 @@ UTF8::String UTF8::String::operator[](unsigned int const n) const return UTF8::String(); } - if(n < 0) + if((int)n < 0) { return UTF8::String(); } @@ -728,6 +727,8 @@ unsigned int UTF8::String::GetSequenceLength(const char* StartByte) const } else { + if(StartByte == 0) + StartByte = "(null)"; throw Exception(std::string("[GetSequenceLength] Invalid UTF8 start byte (it is empty). My own string is: [") + Data + "] Argument is: [" + StartByte + "]"); } } diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index 88badbccd..c34cabe31 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1173,7 +1173,7 @@ bool valapifromstring(const char* name, uint* value, int* value_size, bool print if(apiname) { char modname[MAX_MODULE_SIZE] = ""; - strcpy(modname, name); + strcpy_s(modname, name); modname[apiname - name] = 0; apiname++; if(!strlen(apiname)) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUWidget.h b/x64_dbg_gui/Project/Src/Gui/CPUWidget.h index 0fe082f8e..81a0081ec 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUWidget.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUWidget.h @@ -36,7 +36,6 @@ public: CPUStack* mStack; RegistersView* mGeneralRegs; CPUInfoBox* mInfo; - QTabWidget* mRegsTab; private: Ui::CPUWidget* ui; diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp index 033aa58d2..f2af2055e 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp @@ -963,7 +963,7 @@ void MainWindow::changeCommandLine() cmdline = new char[cbsize]; DbgFunctions()->GetCmdline(cmdline, 0); mLineEdit.setText(QString(cmdline)); - delete cmdline; + delete[] cmdline; } mLineEdit.setCursorPosition(0); diff --git a/x64_dbg_launcher/x64_dbg_launcher.cpp b/x64_dbg_launcher/x64_dbg_launcher.cpp index edb0ba6ff..2239e07d8 100644 --- a/x64_dbg_launcher/x64_dbg_launcher.cpp +++ b/x64_dbg_launcher/x64_dbg_launcher.cpp @@ -183,7 +183,7 @@ int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLi if(MessageBoxW(0, L"Do you want to register a shell extension?", L"Question", MB_YESNO | MB_ICONQUESTION) == IDYES) { wchar_t szLauncherCommand[MAX_PATH] = L""; - swprintf_s(szLauncherCommand, sizeof(szLauncherCommand), L"\"%s\" \"%%1\"", szModulePath); + swprintf_s(szLauncherCommand, _countof(szLauncherCommand), L"\"%s\" \"%%1\"", szModulePath); RegisterShellExtension(SHELLEXT_EXE_KEY, szLauncherCommand); RegisterShellExtension(SHELLEXT_DLL_KEY, szLauncherCommand); } From 6c33a178585bf6153151aa25784de055a9bae6f4 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 10 Nov 2014 14:36:46 +0100 Subject: [PATCH 32/58] DBG+BRIDGE+GUI: no more TitanEngine in the bridge (added separate structures + translation functions) --- x64_dbg_bridge/bridgemain.h | 82 +++++++++++-- x64_dbg_dbg/_exports.cpp | 89 ++++++++++++-- x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp | 24 ++-- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 116 +++++++++--------- 4 files changed, 220 insertions(+), 91 deletions(-) diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 5d89cf399..294a3650e 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -2,7 +2,6 @@ #define _BRIDGEMAIN_H_ #include -#include "..\x64_dbg_dbg\TitanEngine\TitanEngine.h" #ifndef __cplusplus #include @@ -386,7 +385,7 @@ typedef struct bool IE; unsigned short RC; -} MxCsr_FIELDS_t; +} MXCSRFIELDS; typedef struct { @@ -406,7 +405,7 @@ typedef struct unsigned short TOP; -} x87StatusWord_FIELDS_t; +} X87STATUSWORDFIELDS; typedef struct { @@ -422,17 +421,80 @@ typedef struct unsigned short RC; unsigned short PC; -} x87ControlWord_FIELDS_t; +} X87CONTROLWORDFIELDS; typedef struct { - TITAN_ENGINE_CONTEXT_t titcontext; + BYTE data[10]; + int st_value; + int tag; +} X87FPUREGISTER; + +typedef struct +{ + WORD ControlWord; + WORD StatusWord; + WORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + DWORD Cr0NpxState; +} X87FPU; + +typedef struct +{ + ULONG_PTR cax; + ULONG_PTR ccx; + ULONG_PTR cdx; + ULONG_PTR cbx; + ULONG_PTR csp; + ULONG_PTR cbp; + ULONG_PTR csi; + ULONG_PTR cdi; +#ifdef _WIN64 + ULONG_PTR r8; + ULONG_PTR r9; + ULONG_PTR r10; + ULONG_PTR r11; + ULONG_PTR r12; + ULONG_PTR r13; + ULONG_PTR r14; + ULONG_PTR r15; +#endif //_WIN64 + ULONG_PTR cip; + ULONG_PTR eflags; + unsigned short gs; + unsigned short fs; + unsigned short es; + unsigned short ds; + unsigned short cs; + unsigned short ss; + ULONG_PTR dr0; + ULONG_PTR dr1; + ULONG_PTR dr2; + ULONG_PTR dr3; + ULONG_PTR dr6; + ULONG_PTR dr7; + BYTE RegisterArea[80]; + X87FPU x87fpu; + DWORD MxCsr; +#ifdef _WIN64 + M128A XmmRegisters[16]; +#else // x86 + M128A XmmRegisters[8]; +#endif +} REGISTERCONTEXT; + +typedef struct +{ + REGISTERCONTEXT regcontext; FLAGS flags; - x87FPURegister_t x87FPURegisters[8]; - uint64_t mmx[8]; - MxCsr_FIELDS_t MxCsrFields; - x87StatusWord_FIELDS_t x87StatusWordFields; - x87ControlWord_FIELDS_t x87ControlWordFields; + X87FPUREGISTER x87FPURegisters[8]; + unsigned long long mmx[8]; + MXCSRFIELDS MxCsrFields; + X87STATUSWORDFIELDS x87StatusWordFields; + X87CONTROLWORDFIELDS x87ControlWordFields; } REGDUMP; typedef struct diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 92ccd992c..ad9b717e3 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -333,7 +333,7 @@ extern "C" DLL_EXPORT int _dbg_bpgettypeat(duint addr) return cacheResult; } -void GetMxCsrFields(MxCsr_FIELDS_t* MxCsrFields, DWORD MxCsr) +static void GetMxCsrFields(MXCSRFIELDS* MxCsrFields, DWORD MxCsr) { MxCsrFields->DAZ = valmxcsrflagfromstring(MxCsr, "DAZ"); MxCsrFields->DE = valmxcsrflagfromstring(MxCsr, "DE"); @@ -353,7 +353,7 @@ void GetMxCsrFields(MxCsr_FIELDS_t* MxCsrFields, DWORD MxCsr) MxCsrFields->RC = valmxcsrfieldfromstring(MxCsr, "RC"); } -void Getx87ControlWordFields(x87ControlWord_FIELDS_t* x87ControlWordFields, WORD ControlWord) +static void Getx87ControlWordFields(X87CONTROLWORDFIELDS* x87ControlWordFields, WORD ControlWord) { x87ControlWordFields->DM = valx87controlwordflagfromstring(ControlWord, "DM"); x87ControlWordFields->IC = valx87controlwordflagfromstring(ControlWord, "IC"); @@ -368,7 +368,7 @@ void Getx87ControlWordFields(x87ControlWord_FIELDS_t* x87ControlWordFields, WORD x87ControlWordFields->PC = valx87controlwordfieldfromstring(ControlWord, "PC"); } -void Getx87StatusWordFields(x87StatusWord_FIELDS_t* x87StatusWordFields, WORD StatusWord) +static void Getx87StatusWordFields(X87STATUSWORDFIELDS* x87StatusWordFields, WORD StatusWord) { x87StatusWordFields->B = valx87statuswordflagfromstring(StatusWord, "B"); x87StatusWordFields->C0 = valx87statuswordflagfromstring(StatusWord, "C0"); @@ -387,6 +387,71 @@ void Getx87StatusWordFields(x87StatusWord_FIELDS_t* x87StatusWordFields, WORD St x87StatusWordFields->TOP = valx87statuswordfieldfromstring(StatusWord, "TOP"); } +static void TranslateTitanFpu(const x87FPU_t* titanfpu, X87FPU* fpu) +{ + fpu->ControlWord = titanfpu->ControlWord; + fpu->StatusWord = titanfpu->StatusWord; + fpu->TagWord = titanfpu->TagWord; + fpu->ErrorOffset = titanfpu->ErrorOffset; + fpu->ErrorSelector = titanfpu->ErrorSelector; + fpu->DataOffset = titanfpu->DataOffset; + fpu->DataSelector = titanfpu->DataSelector; + fpu->Cr0NpxState = titanfpu->Cr0NpxState; +} + +static void TranslateTitanContextToRegContext(const TITAN_ENGINE_CONTEXT_t* titcontext, REGISTERCONTEXT* regcontext) +{ + regcontext->cax = titcontext->cax; + regcontext->ccx = titcontext->ccx; + regcontext->cdx = titcontext->cdx; + regcontext->cbx = titcontext->cbx; + regcontext->csp = titcontext->csp; + regcontext->cbp = titcontext->cbp; + regcontext->csi = titcontext->csi; + regcontext->cdi = titcontext->cdi; +#ifdef _WIN64 + regcontext->r8 = titcontext->r8; + regcontext->r9 = titcontext->r9; + regcontext->r10 = titcontext->r10; + regcontext->r11 = titcontext->r11; + regcontext->r12 = titcontext->r12; + regcontext->r13 = titcontext->r13; + regcontext->r14 = titcontext->r14; + regcontext->r15 = titcontext->r15; +#endif //_WIN64 + regcontext->cip = titcontext->cip; + regcontext->eflags = titcontext->eflags; + regcontext->gs = titcontext->gs; + regcontext->fs = titcontext->fs; + regcontext->es = titcontext->es; + regcontext->ds = titcontext->ds; + regcontext->cs = titcontext->cs; + regcontext->ss = titcontext->ss; + regcontext->dr0 = titcontext->dr0; + regcontext->dr1 = titcontext->dr1; + regcontext->dr2 = titcontext->dr2; + regcontext->dr3 = titcontext->dr3; + regcontext->dr6 = titcontext->dr6; + regcontext->dr7 = titcontext->dr7; + memcpy(regcontext->RegisterArea, titcontext->RegisterArea, sizeof(regcontext->RegisterArea)); + TranslateTitanFpu(&titcontext->x87fpu, ®context->x87fpu); + regcontext->MxCsr = titcontext->MxCsr; + memcpy(regcontext->XmmRegisters, titcontext->XmmRegisters, sizeof(regcontext->XmmRegisters)); +} + +static void TranslateTitanFpuRegister(const x87FPURegister_t* titanReg, X87FPUREGISTER* reg) +{ + memcpy(reg->data, titanReg->data, sizeof(reg->data)); + reg->st_value = titanReg->st_value; + reg->tag = titanReg->tag; +} + +static void TranslateTitanFpuRegisters(const x87FPURegister_t titanFpu[8], X87FPUREGISTER fpu[8]) +{ + for(int i = 0; i < 8; i++) + TranslateTitanFpuRegister(&titanFpu[i], &fpu[i]); +} + extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) { if(!DbgIsDebugging()) @@ -395,10 +460,12 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) return true; } - if(!GetFullContextDataEx(hActiveThread, & (regdump->titcontext))) + TITAN_ENGINE_CONTEXT_t titcontext; + if(!GetFullContextDataEx(hActiveThread, &titcontext)) return false; + TranslateTitanContextToRegContext(&titcontext, ®dump->regcontext); - duint cflags = regdump->titcontext.eflags; + duint cflags = regdump->regcontext.eflags; regdump->flags.c = valflagfromstring(cflags, "cf"); regdump->flags.p = valflagfromstring(cflags, "pf"); regdump->flags.a = valflagfromstring(cflags, "af"); @@ -409,12 +476,14 @@ extern "C" DLL_EXPORT bool _dbg_getregdump(REGDUMP* regdump) regdump->flags.d = valflagfromstring(cflags, "df"); regdump->flags.o = valflagfromstring(cflags, "of"); - Getx87FPURegisters(regdump->x87FPURegisters, & (regdump->titcontext)); - GetMMXRegisters(regdump->mmx, & (regdump->titcontext)); - GetMxCsrFields(& (regdump->MxCsrFields), regdump->titcontext.MxCsr); - Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->titcontext.x87fpu.ControlWord); - Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->titcontext.x87fpu.StatusWord); + x87FPURegister_t x87FPURegisters[8]; + Getx87FPURegisters(x87FPURegisters, &titcontext); + TranslateTitanFpuRegisters(x87FPURegisters, regdump->x87FPURegisters); + GetMMXRegisters(regdump->mmx, &titcontext); + GetMxCsrFields(& (regdump->MxCsrFields), regdump->regcontext.MxCsr); + Getx87ControlWordFields(& (regdump->x87ControlWordFields), regdump->regcontext.x87fpu.ControlWord); + Getx87StatusWordFields(& (regdump->x87StatusWordFields), regdump->regcontext.x87fpu.StatusWord); return true; } diff --git a/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp b/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp index 9b6508dc6..5fa06a533 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUSideBar.cpp @@ -158,19 +158,19 @@ void CPUSideBar::paintEvent(QPaintEvent* event) const int_t cur_VA = CodePtr->getBase() + InstrBuffer->at(line).rva; #ifdef _WIN64 - if(cur_VA == regDump.titcontext.cax) drawLabel(&painter, line, "RAX"); - if(cur_VA == regDump.titcontext.cbx) drawLabel(&painter, line, "RBX"); - if(cur_VA == regDump.titcontext.ccx) drawLabel(&painter, line, "RCX"); - if(cur_VA == regDump.titcontext.cdx) drawLabel(&painter, line, "RDX"); - if(cur_VA == regDump.titcontext.csi) drawLabel(&painter, line, "RSI"); - if(cur_VA == regDump.titcontext.cdi) drawLabel(&painter, line, "RDI"); + if(cur_VA == regDump.regcontext.cax) drawLabel(&painter, line, "RAX"); + if(cur_VA == regDump.regcontext.cbx) drawLabel(&painter, line, "RBX"); + if(cur_VA == regDump.regcontext.ccx) drawLabel(&painter, line, "RCX"); + if(cur_VA == regDump.regcontext.cdx) drawLabel(&painter, line, "RDX"); + if(cur_VA == regDump.regcontext.csi) drawLabel(&painter, line, "RSI"); + if(cur_VA == regDump.regcontext.cdi) drawLabel(&painter, line, "RDI"); #else //x86 - if(cur_VA == regDump.titcontext.cax) drawLabel(&painter, line, "EAX"); - if(cur_VA == regDump.titcontext.cbx) drawLabel(&painter, line, "EBX"); - if(cur_VA == regDump.titcontext.ccx) drawLabel(&painter, line, "ECX"); - if(cur_VA == regDump.titcontext.cdx) drawLabel(&painter, line, "EDX"); - if(cur_VA == regDump.titcontext.csi) drawLabel(&painter, line, "ESI"); - if(cur_VA == regDump.titcontext.cdi) drawLabel(&painter, line, "EDI"); + if(cur_VA == regDump.regcontext.cax) drawLabel(&painter, line, "EAX"); + if(cur_VA == regDump.regcontext.cbx) drawLabel(&painter, line, "EBX"); + if(cur_VA == regDump.regcontext.ccx) drawLabel(&painter, line, "ECX"); + if(cur_VA == regDump.regcontext.cdx) drawLabel(&painter, line, "EDX"); + if(cur_VA == regDump.regcontext.csi) drawLabel(&painter, line, "ESI"); + if(cur_VA == regDump.regcontext.cdi) drawLabel(&painter, line, "EDI"); #endif } diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index a17bff8b9..221d0189e 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -5,7 +5,7 @@ #include "LineEditDialog.h" #include "SelectFields.h" #include -#include +#include void RegistersView::SetChangeButton(QPushButton* push_button) { @@ -1250,8 +1250,6 @@ QString RegistersView::getRegisterLabel(REGISTER_NAME register_selected) return newText; } -#include -#include double readFloat80(const uint8_t buffer[10]) { /* @@ -1643,7 +1641,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) if(mRegisterUpdates.contains(x87SW_TOP)) p->setPen(ConfigColor("RegistersModifiedColor")); - newText = QString("ST%1 ").arg(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->st_value); + newText = QString("ST%1 ").arg(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->st_value); width = newText.length() * mCharWidth; p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); @@ -1686,7 +1684,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) p->setPen(ConfigColor("RegistersModifiedColor")); } - newText += GetTagWordStateString(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->tag) + QString(" "); + newText += GetTagWordStateString(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->tag) + QString(" "); width = newText.length() * mCharWidth; p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); @@ -1700,7 +1698,7 @@ void RegistersView::drawRegister(QPainter* p, REGISTER_NAME reg, char* value) if(DbgIsDebugging() && mRegisterUpdates.contains(reg)) p->setPen(ConfigColor("RegistersModifiedColor")); - newText += QString::number(readFloat80(((x87FPURegister_t*) registerValue(&wRegDumpStruct, reg))->data)); + newText += QString::number(readFloat80(((X87FPUREGISTER*) registerValue(&wRegDumpStruct, reg))->data)); width = newText.length() * mCharWidth; p->drawText(x, y, width, mRowHeight, Qt::AlignVCenter, newText); } @@ -2146,26 +2144,26 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) static int null_value = 0; // this is probably the most efficient general method to access the values of the struct // TODO: add an array with something like: return array[reg].data, this is more fast :-) - if(reg == CAX) return (char*) & (regd->titcontext.cax); - if(reg == CBX) return (char*) & (regd->titcontext.cbx); - if(reg == CCX) return (char*) & (regd->titcontext.ccx); - if(reg == CDX) return (char*) & (regd->titcontext.cdx); - if(reg == CSI) return (char*) & (regd->titcontext.csi); - if(reg == CDI) return (char*) & (regd->titcontext.cdi); - if(reg == CBP) return (char*) & (regd->titcontext.cbp); - if(reg == CSP) return (char*) & (regd->titcontext.csp); + if(reg == CAX) return (char*) & (regd->regcontext.cax); + if(reg == CBX) return (char*) & (regd->regcontext.cbx); + if(reg == CCX) return (char*) & (regd->regcontext.ccx); + if(reg == CDX) return (char*) & (regd->regcontext.cdx); + if(reg == CSI) return (char*) & (regd->regcontext.csi); + if(reg == CDI) return (char*) & (regd->regcontext.cdi); + if(reg == CBP) return (char*) & (regd->regcontext.cbp); + if(reg == CSP) return (char*) & (regd->regcontext.csp); - if(reg == CIP) return (char*) & (regd->titcontext.cip); - if(reg == EFLAGS) return (char*) & (regd->titcontext.eflags); + if(reg == CIP) return (char*) & (regd->regcontext.cip); + if(reg == EFLAGS) return (char*) & (regd->regcontext.eflags); #ifdef _WIN64 - if(reg == R8) return (char*) & (regd->titcontext.r8); - if(reg == R9) return (char*) & (regd->titcontext.r9); - if(reg == R10) return (char*) & (regd->titcontext.r10); - if(reg == R11) return (char*) & (regd->titcontext.r11); - if(reg == R12) return (char*) & (regd->titcontext.r12); - if(reg == R13) return (char*) & (regd->titcontext.r13); - if(reg == R14) return (char*) & (regd->titcontext.r14); - if(reg == R15) return (char*) & (regd->titcontext.r15); + if(reg == R8) return (char*) & (regd->regcontext.r8); + if(reg == R9) return (char*) & (regd->regcontext.r9); + if(reg == R10) return (char*) & (regd->regcontext.r10); + if(reg == R11) return (char*) & (regd->regcontext.r11); + if(reg == R12) return (char*) & (regd->regcontext.r12); + if(reg == R13) return (char*) & (regd->regcontext.r13); + if(reg == R14) return (char*) & (regd->regcontext.r14); + if(reg == R15) return (char*) & (regd->regcontext.r15); #endif // CF,PF,AF,ZF,SF,TF,IF,DF,OF if(reg == CF) return (char*) & (regd->flags.c); @@ -2179,19 +2177,19 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == OF) return (char*) & (regd->flags.o); // GS,FS,ES,DS,CS,SS - if(reg == GS) return (char*) & (regd->titcontext.gs); - if(reg == FS) return (char*) & (regd->titcontext.fs); - if(reg == ES) return (char*) & (regd->titcontext.es); - if(reg == DS) return (char*) & (regd->titcontext.ds); - if(reg == CS) return (char*) & (regd->titcontext.cs); - if(reg == SS) return (char*) & (regd->titcontext.ss); + if(reg == GS) return (char*) & (regd->regcontext.gs); + if(reg == FS) return (char*) & (regd->regcontext.fs); + if(reg == ES) return (char*) & (regd->regcontext.es); + if(reg == DS) return (char*) & (regd->regcontext.ds); + if(reg == CS) return (char*) & (regd->regcontext.cs); + if(reg == SS) return (char*) & (regd->regcontext.ss); - if(reg == DR0) return (char*) & (regd->titcontext.dr0); - if(reg == DR1) return (char*) & (regd->titcontext.dr1); - if(reg == DR2) return (char*) & (regd->titcontext.dr2); - if(reg == DR3) return (char*) & (regd->titcontext.dr3); - if(reg == DR6) return (char*) & (regd->titcontext.dr6); - if(reg == DR7) return (char*) & (regd->titcontext.dr7); + if(reg == DR0) return (char*) & (regd->regcontext.dr0); + if(reg == DR1) return (char*) & (regd->regcontext.dr1); + if(reg == DR2) return (char*) & (regd->regcontext.dr2); + if(reg == DR3) return (char*) & (regd->regcontext.dr3); + if(reg == DR6) return (char*) & (regd->regcontext.dr6); + if(reg == DR7) return (char*) & (regd->regcontext.dr7); if(reg == MM0) return (char*) & (regd->mmx[0]); if(reg == MM1) return (char*) & (regd->mmx[1]); @@ -2211,9 +2209,9 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == x87r6) return (char*) & (regd->x87FPURegisters[6]); if(reg == x87r7) return (char*) & (regd->x87FPURegisters[7]); - if(reg == x87TagWord) return (char*) & (regd->titcontext.x87fpu.TagWord); + if(reg == x87TagWord) return (char*) & (regd->regcontext.x87fpu.TagWord); - if(reg == x87ControlWord) return (char*) & (regd->titcontext.x87fpu.ControlWord); + if(reg == x87ControlWord) return (char*) & (regd->regcontext.x87fpu.ControlWord); if(reg == x87TW_0) return (char*) & (regd->x87FPURegisters[0].tag); if(reg == x87TW_1) return (char*) & (regd->x87FPURegisters[1].tag); @@ -2235,7 +2233,7 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == x87CW_RC) return (char*) & (regd->x87ControlWordFields.RC); if(reg == x87CW_PC) return (char*) & (regd->x87ControlWordFields.PC); - if(reg == x87StatusWord) return (char*) & (regd->titcontext.x87fpu.StatusWord); + if(reg == x87StatusWord) return (char*) & (regd->regcontext.x87fpu.StatusWord); if(reg == x87SW_B) return (char*) & (regd->x87StatusWordFields.B); if(reg == x87SW_C3) return (char*) & (regd->x87StatusWordFields.C3); @@ -2252,7 +2250,7 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == x87SW_C0) return (char*) & (regd->x87StatusWordFields.C0); if(reg == x87SW_TOP) return (char*) & (regd->x87StatusWordFields.TOP); - if(reg == MxCsr) return (char*) & (regd->titcontext.MxCsr); + if(reg == MxCsr) return (char*) & (regd->regcontext.MxCsr); if(reg == MxCsr_FZ) return (char*) & (regd->MxCsrFields.FZ); if(reg == MxCsr_PM) return (char*) & (regd->MxCsrFields.PM); @@ -2270,22 +2268,22 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == MxCsr_IE) return (char*) & (regd->MxCsrFields.IE); if(reg == MxCsr_RC) return (char*) & (regd->MxCsrFields.RC); - if(reg == XMM0) return (char*) & (regd->titcontext.XmmRegisters[0]); - if(reg == XMM1) return (char*) & (regd->titcontext.XmmRegisters[1]); - if(reg == XMM2) return (char*) & (regd->titcontext.XmmRegisters[2]); - if(reg == XMM3) return (char*) & (regd->titcontext.XmmRegisters[3]); - if(reg == XMM4) return (char*) & (regd->titcontext.XmmRegisters[4]); - if(reg == XMM5) return (char*) & (regd->titcontext.XmmRegisters[5]); - if(reg == XMM6) return (char*) & (regd->titcontext.XmmRegisters[6]); - if(reg == XMM7) return (char*) & (regd->titcontext.XmmRegisters[7]); - if(reg == XMM8) return (char*) & (regd->titcontext.XmmRegisters[8]); - if(reg == XMM9) return (char*) & (regd->titcontext.XmmRegisters[9]); - if(reg == XMM10) return (char*) & (regd->titcontext.XmmRegisters[10]); - if(reg == XMM11) return (char*) & (regd->titcontext.XmmRegisters[11]); - if(reg == XMM12) return (char*) & (regd->titcontext.XmmRegisters[12]); - if(reg == XMM13) return (char*) & (regd->titcontext.XmmRegisters[13]); - if(reg == XMM14) return (char*) & (regd->titcontext.XmmRegisters[14]); - if(reg == XMM15) return (char*) & (regd->titcontext.XmmRegisters[15]); + if(reg == XMM0) return (char*) & (regd->regcontext.XmmRegisters[0]); + if(reg == XMM1) return (char*) & (regd->regcontext.XmmRegisters[1]); + if(reg == XMM2) return (char*) & (regd->regcontext.XmmRegisters[2]); + if(reg == XMM3) return (char*) & (regd->regcontext.XmmRegisters[3]); + if(reg == XMM4) return (char*) & (regd->regcontext.XmmRegisters[4]); + if(reg == XMM5) return (char*) & (regd->regcontext.XmmRegisters[5]); + if(reg == XMM6) return (char*) & (regd->regcontext.XmmRegisters[6]); + if(reg == XMM7) return (char*) & (regd->regcontext.XmmRegisters[7]); + if(reg == XMM8) return (char*) & (regd->regcontext.XmmRegisters[8]); + if(reg == XMM9) return (char*) & (regd->regcontext.XmmRegisters[9]); + if(reg == XMM10) return (char*) & (regd->regcontext.XmmRegisters[10]); + if(reg == XMM11) return (char*) & (regd->regcontext.XmmRegisters[11]); + if(reg == XMM12) return (char*) & (regd->regcontext.XmmRegisters[12]); + if(reg == XMM13) return (char*) & (regd->regcontext.XmmRegisters[13]); + if(reg == XMM14) return (char*) & (regd->regcontext.XmmRegisters[14]); + if(reg == XMM15) return (char*) & (regd->regcontext.XmmRegisters[15]); return (char*) & null_value; } @@ -2293,11 +2291,11 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) void RegistersView::setRegisters(REGDUMP* reg) { // tests if new-register-value == old-register-value holds - if(mCip != reg->titcontext.cip) //CIP changed + if(mCip != reg->regcontext.cip) //CIP changed { wCipRegDumpStruct = wRegDumpStruct; mRegisterUpdates.clear(); - mCip = reg->titcontext.cip; + mCip = reg->regcontext.cip; } QMap::const_iterator it = mRegisterMapping.begin(); @@ -2314,7 +2312,7 @@ void RegistersView::setRegisters(REGDUMP* reg) // now we can save the values wRegDumpStruct = (*reg); - if(mCip != reg->titcontext.cip) + if(mCip != reg->regcontext.cip) wCipRegDumpStruct = wRegDumpStruct; // force repaint From 676942ed80d9a63e56e8d447bdf6fba0a96569a4 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Mon, 10 Nov 2014 17:55:18 +0100 Subject: [PATCH 33/58] FIXED x87r7 access in TOP in stack inc and dec --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 221d0189e..3c870ef87 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -1871,13 +1871,13 @@ void RegistersView::displayEditDialog() void RegistersView::onIncrementx87StackAction() { if(mFPUx87_80BITSDISPLAY.contains(mSelected)) - setRegister(x87SW_TOP, ((* ((uint_t*) registerValue(&wRegDumpStruct, x87SW_TOP))) + 1) % 7); + setRegister(x87SW_TOP, ((* ((uint_t*) registerValue(&wRegDumpStruct, x87SW_TOP))) + 1) % 8); } void RegistersView::onDecrementx87StackAction() { if(mFPUx87_80BITSDISPLAY.contains(mSelected)) - setRegister(x87SW_TOP, ((* ((uint_t*) registerValue(&wRegDumpStruct, x87SW_TOP))) - 1) % 7); + setRegister(x87SW_TOP, ((* ((uint_t*) registerValue(&wRegDumpStruct, x87SW_TOP))) - 1) % 8); } void RegistersView::onIncrementAction() From 4c38c7c3485df7483ef937a8483383a54d26d661 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Tue, 11 Nov 2014 09:14:25 +0100 Subject: [PATCH 34/58] last ymm support --- x64_dbg_bridge/bridgemain.h | 2 + x64_dbg_dbg/TitanEngine/TitanEngine.h | 20 +++- x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 102168 -> 102362 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 105896 -> 106096 bytes x64_dbg_dbg/_exports.cpp | 1 + x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp | 2 +- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 110 +++++++++++++++++- x64_dbg_gui/Project/Src/Gui/RegistersView.h | 5 + 8 files changed, 137 insertions(+), 3 deletions(-) diff --git a/x64_dbg_bridge/bridgemain.h b/x64_dbg_bridge/bridgemain.h index 294a3650e..1745d8bff 100644 --- a/x64_dbg_bridge/bridgemain.h +++ b/x64_dbg_bridge/bridgemain.h @@ -481,8 +481,10 @@ typedef struct DWORD MxCsr; #ifdef _WIN64 M128A XmmRegisters[16]; + BYTE YmmRegisters[32 * 16]; #else // x86 M128A XmmRegisters[8]; + BYTE YmmRegisters[32 * 8]; #endif } REGISTERCONTEXT; diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index 94e21eeb6..974439a89 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -297,7 +297,22 @@ #define UE_x87_ST5 84 #define UE_x87_ST6 85 #define UE_x87_ST7 86 - +#define UE_YMM0 87 +#define UE_YMM1 88 +#define UE_YMM2 89 +#define UE_YMM3 90 +#define UE_YMM4 91 +#define UE_YMM5 92 +#define UE_YMM6 93 +#define UE_YMM7 94 +#define UE_YMM8 95 +#define UE_YMM9 96 +#define UE_YMM10 97 +#define UE_YMM11 98 +#define UE_YMM12 99 +#define UE_YMM13 100 +#define UE_YMM14 101 +#define UE_YMM15 102 #ifndef CONTEXT_EXTENDED_REGISTERS #define CONTEXT_EXTENDED_REGISTERS 0 @@ -361,8 +376,10 @@ typedef struct DWORD MxCsr; #ifdef _WIN64 M128A XmmRegisters[16]; + BYTE YmmRegisters[32 * 16]; #else // x86 M128A XmmRegisters[8]; + BYTE YmmRegisters[32 * 8]; #endif } TITAN_ENGINE_CONTEXT_t; @@ -817,6 +834,7 @@ __declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister); __declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); __declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); __declspec(dllexport) bool TITCALL SetContextData(DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); +__declspec(dllexport) bool TITCALL GetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) void TITCALL ClearExceptionNumber(); __declspec(dllexport) long TITCALL CurrentExceptionNumber(); __declspec(dllexport) bool TITCALL MatchPatternEx(HANDLE hProcess, void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard); diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib index f8c1d8a69ca381acd9f2ff6f003d22e1f39a97f9..efed60ef51080e340b345be13a87e21da1fe8e2d 100644 GIT binary patch delta 18454 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 BX)6E# diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib index bc5345d16cb69f9c816e90db65071da569e55f11..507a284ae1a9ce3998efcdf797954c8f386167eb 100644 GIT binary patch delta 18520 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 diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index ad9b717e3..47e878293 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -437,6 +437,7 @@ static void TranslateTitanContextToRegContext(const TITAN_ENGINE_CONTEXT_t* titc TranslateTitanFpu(&titcontext->x87fpu, ®context->x87fpu); regcontext->MxCsr = titcontext->MxCsr; memcpy(regcontext->XmmRegisters, titcontext->XmmRegisters, sizeof(regcontext->XmmRegisters)); + memcpy(regcontext->YmmRegisters, titcontext->YmmRegisters, sizeof(regcontext->YmmRegisters)); } static void TranslateTitanFpuRegister(const x87FPURegister_t* titanReg, X87FPUREGISTER* reg) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp b/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp index 0a167fe2d..4093a37a0 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUWidget.cpp @@ -33,7 +33,7 @@ CPUWidget::CPUWidget(QWidget* parent) : QWidget(parent), ui(new Ui::CPUWidget) mGeneralRegs = new RegistersView(0); mGeneralRegs->setFixedWidth(1000); - mGeneralRegs->setFixedHeight(1200); + mGeneralRegs->setFixedHeight(1400); mGeneralRegs->ShowFPU(true); QScrollArea* scrollArea = new QScrollArea; diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index 3c870ef87..a0842779e 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -346,6 +346,44 @@ void RegistersView::InitMappings() offset++; + mRegisterMapping.insert(YMM0, "YMM0"); + mRegisterPlaces.insert(YMM0, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM1, "YMM1"); + mRegisterPlaces.insert(YMM1, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM2, "YMM2"); + mRegisterPlaces.insert(YMM2, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM3, "YMM3"); + mRegisterPlaces.insert(YMM3, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM4, "YMM4"); + mRegisterPlaces.insert(YMM4, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM5, "YMM5"); + mRegisterPlaces.insert(YMM5, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM6, "YMM6"); + mRegisterPlaces.insert(YMM6, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM7, "YMM7"); + mRegisterPlaces.insert(YMM7, Register_Position(offset++, 0, 6, 32 * 2)); + +#ifdef _WIN64 + mRegisterMapping.insert(YMM8, "YMM8"); + mRegisterPlaces.insert(YMM8, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM9, "YMM9"); + mRegisterPlaces.insert(YMM9, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM10, "YMM10"); + mRegisterPlaces.insert(YMM10, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM11, "YMM11"); + mRegisterPlaces.insert(YMM11, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM12, "YMM12"); + mRegisterPlaces.insert(YMM12, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM13, "YMM13"); + mRegisterPlaces.insert(YMM13, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM14, "YMM14"); + mRegisterPlaces.insert(YMM14, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM15, "YMM15"); + mRegisterPlaces.insert(YMM15, Register_Position(offset++, 0, 6, 32 * 2)); +#endif + + offset++; + mRegisterMapping.insert(DR0, "DR0"); mRegisterPlaces.insert(DR0, Register_Position(offset++, 0, 4, sizeof(uint_t) * 2)); mRegisterMapping.insert(DR1, "DR1"); @@ -936,6 +974,57 @@ RegistersView::RegistersView(QWidget* parent) : QScrollArea(parent), mVScrollOff mFPU.insert(XMM15); #endif + mFPUYMM.insert(YMM0); + mMODIFYDISPLAY.insert(YMM0); + mFPU.insert(YMM0); + mFPUYMM.insert(YMM1); + mMODIFYDISPLAY.insert(YMM1); + mFPU.insert(YMM1); + mFPUYMM.insert(YMM2); + mMODIFYDISPLAY.insert(YMM2); + mFPU.insert(YMM2); + mFPUYMM.insert(YMM3); + mMODIFYDISPLAY.insert(YMM3); + mFPU.insert(YMM3); + mFPUYMM.insert(YMM4); + mMODIFYDISPLAY.insert(YMM4); + mFPU.insert(YMM4); + mFPUYMM.insert(YMM5); + mMODIFYDISPLAY.insert(YMM5); + mFPU.insert(YMM5); + mFPUYMM.insert(YMM6); + mMODIFYDISPLAY.insert(YMM6); + mFPU.insert(YMM6); + mFPUYMM.insert(YMM7); + mMODIFYDISPLAY.insert(YMM7); + mFPU.insert(YMM7); + +#ifdef _WIN64 + mFPUYMM.insert(YMM8); + mMODIFYDISPLAY.insert(YMM8); + mFPU.insert(YMM8); + mFPUYMM.insert(YMM9); + mMODIFYDISPLAY.insert(YMM9); + mFPU.insert(YMM9); + mFPUYMM.insert(YMM10); + mMODIFYDISPLAY.insert(YMM10); + mFPU.insert(YMM10); + mFPUYMM.insert(YMM11); + mMODIFYDISPLAY.insert(YMM11); + mFPU.insert(YMM11); + mFPUYMM.insert(YMM12); + mMODIFYDISPLAY.insert(YMM12); + mFPU.insert(YMM12); + mFPUYMM.insert(YMM13); + mMODIFYDISPLAY.insert(YMM13); + mFPU.insert(YMM13); + mFPUYMM.insert(YMM14); + mMODIFYDISPLAY.insert(YMM14); + mFPU.insert(YMM14); + mFPUYMM.insert(YMM15); + mMODIFYDISPLAY.insert(YMM15); + mFPU.insert(YMM15); +#endif //registers that should not be changed mNoChange.insert(GS); mUSHORTDISPLAY.insert(GS); @@ -1807,7 +1896,7 @@ void RegistersView::displayEditDialog() fpuvalue = (uint_t) mLineEdit.editText.toUShort(&ok, 16); else if(mDWORDDISPLAY.contains(mSelected)) fpuvalue = mLineEdit.editText.toUInt(&ok, 16); - else if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) + else if(mFPUMMX.contains(mSelected) || mFPUXMM.contains(mSelected) || mFPUYMM.contains(mSelected) || mFPUx87_80BITSDISPLAY.contains(mSelected)) { QByteArray pArray = mLineEdit.editText.toLocal8Bit(); if(pArray.size() == GetSizeRegister(mSelected) * 2) @@ -2121,6 +2210,8 @@ SIZE_T RegistersView::GetSizeRegister(const REGISTER_NAME reg_name) size = 8; else if(mFPUXMM.contains(reg_name)) size = 16; + else if(mFPUYMM.contains(reg_name)) + size = 32; else size = 0; @@ -2285,6 +2376,23 @@ char* RegistersView::registerValue(const REGDUMP* regd, const REGISTER_NAME reg) if(reg == XMM14) return (char*) & (regd->regcontext.XmmRegisters[14]); if(reg == XMM15) return (char*) & (regd->regcontext.XmmRegisters[15]); + if(reg == YMM0) return (char*) & (regd->regcontext.YmmRegisters[32 * 0]); + if(reg == YMM1) return (char*) & (regd->regcontext.YmmRegisters[32 * 1]); + if(reg == YMM2) return (char*) & (regd->regcontext.YmmRegisters[32 * 2]); + if(reg == YMM3) return (char*) & (regd->regcontext.YmmRegisters[32 * 3]); + if(reg == YMM4) return (char*) & (regd->regcontext.YmmRegisters[32 * 4]); + if(reg == YMM5) return (char*) & (regd->regcontext.YmmRegisters[32 * 5]); + if(reg == YMM6) return (char*) & (regd->regcontext.YmmRegisters[32 * 6]); + if(reg == YMM7) return (char*) & (regd->regcontext.YmmRegisters[32 * 7]); + if(reg == YMM8) return (char*) & (regd->regcontext.YmmRegisters[32 * 8]); + if(reg == YMM9) return (char*) & (regd->regcontext.YmmRegisters[32 * 9]); + if(reg == YMM10) return (char*) & (regd->regcontext.YmmRegisters[32 * 10]); + if(reg == YMM11) return (char*) & (regd->regcontext.YmmRegisters[32 * 11]); + if(reg == YMM12) return (char*) & (regd->regcontext.YmmRegisters[32 * 12]); + if(reg == YMM13) return (char*) & (regd->regcontext.YmmRegisters[32 * 13]); + if(reg == YMM14) return (char*) & (regd->regcontext.YmmRegisters[32 * 14]); + if(reg == YMM15) return (char*) & (regd->regcontext.YmmRegisters[32 * 15]); + return (char*) & null_value; } diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.h b/x64_dbg_gui/Project/Src/Gui/RegistersView.h index 26e72b3b0..95837065e 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.h +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.h @@ -56,6 +56,10 @@ public: MM0, MM1, MM2, MM3, MM4, MM5, MM6, MM7, XMM0, XMM1, XMM2, XMM3, XMM4, XMM5, XMM6, XMM7, XMM8, XMM9, XMM10, XMM11, XMM12, XMM13, XMM14, XMM15, + // YMM + YMM0, YMM1, YMM2, YMM3, YMM4, YMM5, YMM6, YMM7, YMM8, + YMM9, YMM10, YMM11, YMM12, YMM13, YMM14, YMM15, + UNKNOWN }; @@ -180,6 +184,7 @@ private: QSet mFPUx87; QSet mFPUMMX; QSet mFPUXMM; + QSet mFPUYMM; // contains all id's of registers if there occurs a change QSet mRegisterUpdates; // registers that do not allow changes From 48d20ee6f6d2d12ec914e8e28fd51e8cb97249cf Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 11 Nov 2014 16:24:14 +0100 Subject: [PATCH 35/58] PROJECT: fixed bugs in clean script --- clean.bat | 60 ++++++++++++++++++++++++------------------------------- 1 file changed, 26 insertions(+), 34 deletions(-) diff --git a/clean.bat b/clean.bat index 7a24b93cb..c6ae38ec3 100644 --- a/clean.bat +++ b/clean.bat @@ -46,42 +46,34 @@ del /Q Project\Src\Bridge\x32_bridge.lib del /Q Project\Src\Bridge\x64_bridge.lib cd .. echo cleaning bin\ -cd bin -del /Q *.pdb -del /Q *.exp -del /Q *.a -del /Q *.lib -del /Q *.def -del /Q x96_dbg.exe -cd.. +del /Q bin\*.pdb +del /Q bin\*.exp +del /Q bin\*.a +del /Q bin\*.lib +del /Q bin\*.def +del /Q bin\x96_dbg.exe echo cleaning bin\x32... -cd bin\x32 -rmdir /S /Q db -del /Q *.pdb -del /Q *.exp -del /Q *.a -del /Q *.lib -del /Q *.def -del /Q x32_dbg.exe -del /Q x32_dbg.dll -del /Q x32_gui.dll -del /Q x32_bridge.dll -cd .. -cd .. +rmdir /S /Q bin\x32\db +del /Q bin\x32\*.pdb +del /Q bin\x32\*.exp +del /Q bin\x32\*.a +del /Q bin\x32\*.lib +del /Q bin\x32\*.def +del /Q bin\x32\x32_dbg.exe +del /Q bin\x32\x32_dbg.dll +del /Q bin\x32\x32_gui.dll +del /Q bin\x32\x32_bridge.dll echo cleaning bin\x64... -cd bin\x64 -rmdir /S /Q db -del /Q *.pdb -del /Q *.exp -del /Q *.a -del /Q *.lib -del /Q *.def -del /Q x64_dbg.exe -del /Q x64_dbg.dll -del /Q x64_gui.dll -del /Q x64_bridge.dll -cd .. -cd .. +rmdir /S /Q bin\x64\db +del /Q bin\x64\*.pdb +del /Q bin\x64\*.exp +del /Q bin\x64\*.a +del /Q bin\x64\*.lib +del /Q bin\x64\*.def +del /Q bin\x64\x64_dbg.exe +del /Q bin\x64\x64_dbg.dll +del /Q bin\x64\x64_gui.dll +del /Q bin\x64\x64_bridge.dll echo cleaning help... cd help del /Q *.chm From 1d1dc8bab90fb25523750498573519c752d9c715 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 11 Nov 2014 17:13:21 +0100 Subject: [PATCH 36/58] PROJECT: some changes in release.bat --- release.bat | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/release.bat b/release.bat index 92f203258..0e3365ba2 100644 --- a/release.bat +++ b/release.bat @@ -111,12 +111,12 @@ del x64_dbg.def del x64_dbg.a copy bin\x64\x64_dbg.lib %RELEASEDIR%\pluginsdk\x64_dbg.lib -echo test +echo !upload -rmdir %RELEASEDIR%\test /S /Q -mkdir %RELEASEDIR%\test +rmdir %RELEASEDIR%\!upload /S /Q +mkdir %RELEASEDIR%\!upload -xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\test /S /Y -xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\test /S /Y -xcopy %RELEASEDIR%\release %RELEASEDIR%\test /S /Y -xcopy %RELEASEDIR%\help %RELEASEDIR%\test /S /Y \ No newline at end of file +xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\!upload /S /Y +xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\!upload /S /Y +xcopy %RELEASEDIR%\release %RELEASEDIR%\!upload /S /Y +xcopy %RELEASEDIR%\help %RELEASEDIR%\!upload /S /Y \ No newline at end of file From 2e2c0de8a15994b2fc2663ee26b5b04743067a31 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 11 Nov 2014 17:19:16 +0100 Subject: [PATCH 37/58] PROJECT: clean & release always exit gracefully :) --- clean.bat | 3 ++- release.bat | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/clean.bat b/clean.bat index c6ae38ec3..2a46ecc7e 100644 --- a/clean.bat +++ b/clean.bat @@ -77,4 +77,5 @@ del /Q bin\x64\x64_bridge.dll echo cleaning help... cd help del /Q *.chm -rmdir /S /Q output \ No newline at end of file +rmdir /S /Q output +exit 0 \ No newline at end of file diff --git a/release.bat b/release.bat index 0e3365ba2..1466658a6 100644 --- a/release.bat +++ b/release.bat @@ -119,4 +119,6 @@ mkdir %RELEASEDIR%\!upload xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\!upload /S /Y xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\!upload /S /Y xcopy %RELEASEDIR%\release %RELEASEDIR%\!upload /S /Y -xcopy %RELEASEDIR%\help %RELEASEDIR%\!upload /S /Y \ No newline at end of file +xcopy %RELEASEDIR%\help %RELEASEDIR%\!upload /S /Y + +exit 0 \ No newline at end of file From 849a61c91c30cdec8f5ae6d6391716a474bc7732 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 11 Nov 2014 18:33:21 +0100 Subject: [PATCH 38/58] PROJECT: renamed !upload to release in script --- release.bat | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/release.bat b/release.bat index 1466658a6..36184ada1 100644 --- a/release.bat +++ b/release.bat @@ -111,14 +111,14 @@ del x64_dbg.def del x64_dbg.a copy bin\x64\x64_dbg.lib %RELEASEDIR%\pluginsdk\x64_dbg.lib -echo !upload +echo release -rmdir %RELEASEDIR%\!upload /S /Q -mkdir %RELEASEDIR%\!upload +rmdir %RELEASEDIR%\release /S /Q +mkdir %RELEASEDIR%\release -xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\!upload /S /Y -xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\!upload /S /Y -xcopy %RELEASEDIR%\release %RELEASEDIR%\!upload /S /Y -xcopy %RELEASEDIR%\help %RELEASEDIR%\!upload /S /Y +xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\release /S /Y +xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\release /S /Y +xcopy %RELEASEDIR%\release %RELEASEDIR%\release /S /Y +xcopy %RELEASEDIR%\help %RELEASEDIR%\release /S /Y exit 0 \ No newline at end of file From b0717c946eb5c209ebcac2b49d61f94fee47039b Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 11 Nov 2014 18:40:15 +0100 Subject: [PATCH 39/58] PROJECT: final fix for release script --- release.bat | 30 +++++++++------------- x64_dbg_dbg/TitanEngine/TitanEngine_x64.a | Bin 0 -> 332442 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.a | Bin 0 -> 331524 bytes 3 files changed, 12 insertions(+), 18 deletions(-) create mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x64.a create mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x86.a diff --git a/release.bat b/release.bat index 36184ada1..daea1b063 100644 --- a/release.bat +++ b/release.bat @@ -41,22 +41,6 @@ copy bin\x64\lz4.dll %RELEASEDIR%\bin_base\x64\lz4.dll copy bin\x64\TitanEngine.dll %RELEASEDIR%\bin_base\x64\TitanEngine.dll copy bin\x64\XEDParse.dll %RELEASEDIR%\bin_base\x64\XEDParse.dll -echo release - -mkdir %RELEASEDIR%\release -mkdir %RELEASEDIR%\release\x32 -mkdir %RELEASEDIR%\release\x64 - -copy bin\x96_dbg.exe %RELEASEDIR%\release\x96_dbg.exe -copy bin\x32\x32_bridge.dll %RELEASEDIR%\release\x32\x32_bridge.dll -copy bin\x32\x32_dbg.dll %RELEASEDIR%\release\x32\x32_dbg.dll -copy bin\x32\x32_dbg.exe %RELEASEDIR%\release\x32\x32_dbg.exe -copy bin\x32\x32_gui.dll %RELEASEDIR%\release\x32\x32_gui.dll -copy bin\x64\x64_bridge.dll %RELEASEDIR%\release\x64\x64_bridge.dll -copy bin\x64\x64_dbg.dll %RELEASEDIR%\release\x64\x64_dbg.dll -copy bin\x64\x64_dbg.exe %RELEASEDIR%\release\x64\x64_dbg.exe -copy bin\x64\x64_gui.dll %RELEASEDIR%\release\x64\x64_gui.dll - echo help mkdir %RELEASEDIR%\help @@ -113,12 +97,22 @@ copy bin\x64\x64_dbg.lib %RELEASEDIR%\pluginsdk\x64_dbg.lib echo release -rmdir %RELEASEDIR%\release /S /Q mkdir %RELEASEDIR%\release +mkdir %RELEASEDIR%\release\x32 +mkdir %RELEASEDIR%\release\x64 + +copy bin\x96_dbg.exe %RELEASEDIR%\release\x96_dbg.exe +copy bin\x32\x32_bridge.dll %RELEASEDIR%\release\x32\x32_bridge.dll +copy bin\x32\x32_dbg.dll %RELEASEDIR%\release\x32\x32_dbg.dll +copy bin\x32\x32_dbg.exe %RELEASEDIR%\release\x32\x32_dbg.exe +copy bin\x32\x32_gui.dll %RELEASEDIR%\release\x32\x32_gui.dll +copy bin\x64\x64_bridge.dll %RELEASEDIR%\release\x64\x64_bridge.dll +copy bin\x64\x64_dbg.dll %RELEASEDIR%\release\x64\x64_dbg.dll +copy bin\x64\x64_dbg.exe %RELEASEDIR%\release\x64\x64_dbg.exe +copy bin\x64\x64_gui.dll %RELEASEDIR%\release\x64\x64_gui.dll xcopy %RELEASEDIR%\qt_base %RELEASEDIR%\release /S /Y xcopy %RELEASEDIR%\bin_base %RELEASEDIR%\release /S /Y -xcopy %RELEASEDIR%\release %RELEASEDIR%\release /S /Y xcopy %RELEASEDIR%\help %RELEASEDIR%\release /S /Y exit 0 \ No newline at end of file diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a new file mode 100644 index 0000000000000000000000000000000000000000..3ecf455ff242624b4582e6ebab215c5fcea3dfb4 GIT binary patch literal 332442 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 Date: Tue, 11 Nov 2014 19:46:52 +0100 Subject: [PATCH 40/58] PROJECT: updated developer list --- README.md | 7 ++++--- help/Special_Thanks.htm | 10 +++++++--- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a1fcd3703..b88f57d14 100644 --- a/README.md +++ b/README.md @@ -63,7 +63,8 @@ Releases of *x64_dbg* can be found on [here](http://download.x64dbg.com). - Nukem - ahmadmansoor -## Developers -- Mr. eXoDia +## Developers (in order of joining) +- [Mr. eXoDia](http://mrexodia.cf) - Sigma -- tr4ceflow \ No newline at end of file +- [tr4ceflow](http://blog.tr4ceflow.com) +- [Dreg](http://www.fr33project.org) \ No newline at end of file diff --git a/help/Special_Thanks.htm b/help/Special_Thanks.htm index bc57c6844..f7aadf56a 100644 --- a/help/Special_Thanks.htm +++ b/help/Special_Thanks.htm @@ -64,13 +64,17 @@ ahmadmansoor

    + +
  • +
    Dreg +  
  • From 4da5cdf955517492d3b15b6e7b960bfa6291687c Mon Sep 17 00:00:00 2001 From: Radical Raccoon Date: Tue, 11 Nov 2014 21:20:46 -0600 Subject: [PATCH 41/58] Find references via the right-click context menu in the CPU Dump view --- x64_dbg_gui/Project/Src/Gui/CPUDump.cpp | 12 ++++++++++++ x64_dbg_gui/Project/Src/Gui/CPUDump.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp index 06be7061e..55736c1fc 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp @@ -231,6 +231,11 @@ void CPUDump::setupContextMenu() this->addAction(mFindPatternAction); connect(mFindPatternAction, SIGNAL(triggered()), this, SLOT(findPattern())); + //Find References + mFindReferencesAction = new QAction("Find &References", this); + this->addAction(mFindReferencesAction); + connect(mFindReferencesAction, SIGNAL(triggered()), this, SLOT(findReferencesSlot())); + //Goto menu mGotoMenu = new QMenu("&Goto", this); //Goto->Expression @@ -1137,6 +1142,13 @@ void CPUDump::hardwareRemoveSlot() DbgCmdExec(QString("bphwc " + addr_text).toUtf8().constData()); } +void CPUDump::findReferencesSlot() +{ + QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + DbgCmdExec(QString("findref " + addrText + ", " + addrText).toUtf8().constData()); + emit displayReferencesWidget(); +} + void CPUDump::binaryEditSlot() { HexEditDialog hexEdit(this); diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.h b/x64_dbg_gui/Project/Src/Gui/CPUDump.h index 6397e67a7..8eeb0d70e 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.h @@ -74,6 +74,7 @@ public slots: void findPattern(); void undoSelectionSlot(); void followStackSlot(); + void findReferencesSlot(); private: QMenu* mBreakpointMenu; @@ -152,6 +153,7 @@ private: QAction* mBinaryPasteAction; QAction* mBinaryPasteIgnoreSizeAction; QAction* mFindPatternAction; + QAction* mFindReferencesAction; QAction* mUndoSelection; QMenu* mSpecialMenu; From 41108a22a03bbc2de37c8d3f83a57ba4678336be Mon Sep 17 00:00:00 2001 From: Radical Raccoon Date: Tue, 11 Nov 2014 22:08:29 -0600 Subject: [PATCH 42/58] GUI: Added shortcut for finding references in the CPU Dump --- x64_dbg_gui/Project/Src/Gui/CPUDump.cpp | 2 ++ x64_dbg_gui/Project/Src/Utils/Configuration.cpp | 1 + 2 files changed, 3 insertions(+) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp index 55736c1fc..6d7ca10e6 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp @@ -233,6 +233,7 @@ void CPUDump::setupContextMenu() //Find References mFindReferencesAction = new QAction("Find &References", this); + mFindReferencesAction->setShortcutContext(Qt::WidgetShortcut); this->addAction(mFindReferencesAction); connect(mFindReferencesAction, SIGNAL(triggered()), this, SLOT(findReferencesSlot())); @@ -349,6 +350,7 @@ void CPUDump::refreshShortcutsSlot() mUndoSelection->setShortcut(ConfigShortcut("ActionUndoSelection")); mSetLabelAction->setShortcut(ConfigShortcut("ActionSetLabel")); mFindPatternAction->setShortcut(ConfigShortcut("ActionFindPattern")); + mFindReferencesAction->setShortcut(ConfigShortcut("ActionFindReferences")); mGotoExpression->setShortcut(ConfigShortcut("ActionGotoExpression")); } diff --git a/x64_dbg_gui/Project/Src/Utils/Configuration.cpp b/x64_dbg_gui/Project/Src/Utils/Configuration.cpp index 22c8d4fbf..28b1bc1a0 100644 --- a/x64_dbg_gui/Project/Src/Utils/Configuration.cpp +++ b/x64_dbg_gui/Project/Src/Utils/Configuration.cpp @@ -241,6 +241,7 @@ Configuration::Configuration() : QObject() defaultShortcuts.insert("ActionGotoExpression", Shortcut(tr("Actions -> Goto Expression"), "Ctrl+G")); defaultShortcuts.insert("ActionFindReferencesToSelectedAddress", Shortcut(tr("Actions -> Find References to Selected Address"), "Ctrl+R")); defaultShortcuts.insert("ActionFindPattern", Shortcut(tr("Actions -> Find Pattern"), "Ctrl+B")); + defaultShortcuts.insert("ActionFindReferences", Shortcut(tr("Actions -> Find References"), "Ctrl+R")); defaultShortcuts.insert("ActionHighlightingMode", Shortcut(tr("Actions -> Highlighting Mode"), "Ctrl+H")); defaultShortcuts.insert("ActionFind", Shortcut(tr("Actions -> Find"), "Ctrl+F")); From 684dad577398c29c931bc6f4133d6bb7779f6298 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Wed, 12 Nov 2014 22:56:24 +0100 Subject: [PATCH 43/58] DBG: added command 'findrefrange' --- help/reffindrange_findrefrange_refrange.htm | 43 ++++++++++++++++++ help/x64_dbg.wcp | Bin 83242 -> 83876 bytes x64_dbg_dbg/instruction.cpp | 48 ++++++++++++++++---- x64_dbg_dbg/instruction.h | 1 + x64_dbg_dbg/x64_dbg.cpp | 7 +-- 5 files changed, 86 insertions(+), 13 deletions(-) create mode 100644 help/reffindrange_findrefrange_refrange.htm diff --git a/help/reffindrange_findrefrange_refrange.htm b/help/reffindrange_findrefrange_refrange.htm new file mode 100644 index 000000000..b5b832db6 --- /dev/null +++ b/help/reffindrange_findrefrange_refrange.htm @@ -0,0 +1,43 @@ + + + +reffindrange/findrefrange/refrange + + + + + + + +

    reffindrange[,findrefrange,refrange]
    Find references to a certain range of values.

    +

    + + +arguments + + +
    +
    +  arg1: Start of the range (will be +included in the results when found).

    +

    + +[arg2]: End of range (will be included in the results when +found). When not specified the first argument will be used.

    +

    + + +[arg3]: Address of/inside a memory page to look in. +When not specified CIP will be used. 

    +

    [arg4]: The size of the data to search in.

    +

    result
    The $result variable is set to the number of +references found.

    +

     

    + \ No newline at end of file diff --git a/help/x64_dbg.wcp b/help/x64_dbg.wcp index 98b168fa4ea96687abcd9999021049277943ebd4..390969236ae42b48217bf9738d94c61e9d3b73b9 100644 GIT binary patch delta 1137 zcmZ`&T}WGJ7(S0bAq$C%!N#9vF^Mt8s>wO=u2tqA5%wuZBf@=)bW7};U6Pz{O&ExY9DEn^7%xY*3N3P+6VIgv0&-fFo*GaWp~XU zqN3v+tawnPVyWcOjAm&=LjG^jiT@Ry*juwN`s7{@FCD;YwV|2ndauFhAQt$%0hZd* z!@TB(7kzy90EYQPBg)mfmQ~k%2f67(6X%*R&#Fe`c)S@YPBmhbH=0rAsU}#w)Pnii zf_6eX#_@yb;iL=k>WtRUFPcTICWKXWe=$WpfExZ8!V*gn1Q-dUj^(#-_Eq{9s{+tz zwPKlTF$7;xl8i*8_db^6N(8HPwIbt0VYS)Yz?)IbI7(rT#dbB{=07o^os0_YVVks- z^)YU@BFP)^UAYs~+l5kY6N)z>(bsW_HWE0@?Ko_fIs|*vE|{GZfk=mp{BuGCf}J8D zX^sn>LUAR9GII!PEOo-eXGx*F--RPiYICz|&(Hc?nqNi5h2OeG?MfFCw7Z15+#^Dg zo?<8^YKz^Xww*$S=X<33D2?NM)+4@`bg4c_IpY{oT}ew6%Sbh@OPjTfGl?PCcfAsY zb+|Z{5vN}o(&$4|#@Wa6d~C|Fr+dZjTUjh%g5R5nGG`*Gww@%bP0ip%6XSeo$thpR z$|?WRCwJf-3pq7YpJ2su4%3#OpDeiy@qVmusSoDm0by;}@bgO>c|IJFu_Ybh$w9dW zOFnrn{vf+^xXLR7vTOH{NY@RD;ol7HxMZn&i)ohfxXimbjH!+3-Db%0b`EVkJtT^Y z!zja0p9KugjtFxrj{)WjvYY35X+1S8oSOw1X>lb z*BY9xWjG#%!CQwh$-j$ep}z>fSQ;(jm})o|o81zZDEJpcdz delta 936 zcmX|9Ur1YL9KDAcaUt3otc|H&)A%Q`jmgbz)I?+ApBQWz#g#sct&=hKF#51{Ba|_u zxUs#Iv58;l8KsC6u@a<|S~@9gd+Sqa`ye8v47NfkKDj=Ou?N|?&h6n|&iTIc`W!O6t6X7nfF3s&zmvNnHJn`yVxM%Ep#?z3uSr zb}1YiLFT&}i@o=_tpn@^A9J4TXvp1Zv=oI8QCM^CdMp}2=q-u)(& zY0gCh|4d2ptXG-#=tqtWFC=AHnMraig?n6Z;b+2?%y!g7G|Owwex!?O+~vy*g683i zZk~1VrpF50aItFUZ|RCo;xS*!#w;+b zqdP-#n;llNg&|p9D#-GSJZ|toQKN8tSi`ekliPC_?}M diff --git a/x64_dbg_dbg/instruction.cpp b/x64_dbg_dbg/instruction.cpp index 879d4631a..6f8e82f30 100644 --- a/x64_dbg_dbg/instruction.cpp +++ b/x64_dbg_dbg/instruction.cpp @@ -741,6 +741,12 @@ CMDRESULT cbInstrRefadd(int argc, char* argv[]) return STATUS_CONTINUE; } +struct VALUERANGE +{ + uint start; + uint end; +}; + //reffind value[,page] static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO* refinfo) { @@ -753,20 +759,25 @@ static bool cbRefFind(DISASM* disasm, BASIC_INSTRUCTION_INFO* basicinfo, REFINFO return true; } bool found = false; - uint value = (uint)refinfo->userinfo; + VALUERANGE* range = (VALUERANGE*)refinfo->userinfo; + uint start = range->start; + uint end = range->end; if((basicinfo->type & TYPE_VALUE) == TYPE_VALUE) { - if(basicinfo->value.value == value) + uint value = basicinfo->value.value; + if(value >= start && value <= end) found = true; } if((basicinfo->type & TYPE_MEMORY) == TYPE_MEMORY) { - if(basicinfo->memory.value == value) + uint value = basicinfo->memory.value; + if(value >= start && value <= end) found = true; } if((basicinfo->type & TYPE_ADDR) == TYPE_ADDR) { - if(basicinfo->addr == value) + uint value = basicinfo->addr; + if(value >= start && value <= end) found = true; } if(found) @@ -791,18 +802,35 @@ CMDRESULT cbInstrRefFind(int argc, char* argv[]) dputs("not enough arguments!"); return STATUS_ERROR; } - uint value = 0; - if(!valfromstring(argv[1], &value, false)) + std::string newCommand = std::string("reffindrange ") + argv[1] + std::string(",") + argv[1]; + if(argc > 2) + newCommand += std::string(",") + argv[2]; + if(argc > 3) + newCommand += std::string(",") + argv[3]; + return cmddirectexec(dbggetcommandlist(), newCommand.c_str()); +} + +CMDRESULT cbInstrRefFindRange(int argc, char* argv[]) +{ + if(argc < 2) + { + dputs("not enough arguments!"); return STATUS_ERROR; + } + VALUERANGE range; + if(!valfromstring(argv[1], &range.start, false)) + return STATUS_ERROR; + if(argc < 3 or !valfromstring(argv[2], &range.end, false)) + range.end = range.start; uint addr = 0; - if(argc < 3 or !valfromstring(argv[2], &addr)) + if(argc < 4 or !valfromstring(argv[3], &addr)) addr = GetContextDataEx(hActiveThread, UE_CIP); uint size = 0; - if(argc >= 4) - if(!valfromstring(argv[3], &size)) + if(argc >= 5) + if(!valfromstring(argv[4], &size)) size = 0; uint ticks = GetTickCount(); - int found = reffind(addr, size, cbRefFind, (void*)value, false); + int found = reffind(addr, size, cbRefFind, &range, false); dprintf("%u reference(s) in %ums\n", found, GetTickCount() - ticks); varset("$result", found, false); return STATUS_CONTINUE; diff --git a/x64_dbg_dbg/instruction.h b/x64_dbg_dbg/instruction.h index 5a3d0e6ed..231f0fc84 100644 --- a/x64_dbg_dbg/instruction.h +++ b/x64_dbg_dbg/instruction.h @@ -46,6 +46,7 @@ CMDRESULT cbInstrRefinit(int argc, char* argv[]); CMDRESULT cbInstrRefadd(int argc, char* argv[]); CMDRESULT cbInstrRefFind(int argc, char* argv[]); CMDRESULT cbInstrRefStr(int argc, char* argv[]); +CMDRESULT cbInstrRefFindRange(int argc, char* argv[]); CMDRESULT cbInstrSetstr(int argc, char* argv[]); CMDRESULT cbInstrGetstr(int argc, char* argv[]); diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 36132121d..513560b40 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -170,12 +170,13 @@ static void registercommands() dbgcmdnew("msgyn", cbScriptMsgyn, false); //data - dbgcmdnew("reffind\1findref\1ref", cbInstrRefFind, true); - dbgcmdnew("refstr\1strref", cbInstrRefStr, true); + dbgcmdnew("reffind\1findref\1ref", cbInstrRefFind, true); //find references to a value + dbgcmdnew("refstr\1strref", cbInstrRefStr, true); //find string references dbgcmdnew("find", cbInstrFind, true); //find a pattern dbgcmdnew("findall", cbInstrFindAll, true); //find all patterns dbgcmdnew("modcallfind", cbInstrModCallFind, true); //find intermodular calls dbgcmdnew("findasm\1asmfind", cbInstrFindAsm, true); //find instruction + dbgcmdnew("reffindrange\1findrefrange\1refrange", cbInstrRefFindRange, true); //undocumented dbgcmdnew("bench", cbDebugBenchmark, true); //benchmark test (readmem etc) @@ -300,7 +301,7 @@ extern "C" DLL_EXPORT void _dbg_dbgexitsignal() if(memleaks()) { char msg[256] = ""; - sprintf(msg, "%d memory leak(s) found!\n\nPlease contact the authors of x64_dbg.", memleaks()); + sprintf(msg, "%d memory leak(s) found!\n\nPlease send contact the authors of x64_dbg.", memleaks()); MessageBoxA(0, msg, "error", MB_ICONERROR | MB_SYSTEMMODAL); } else From 011c54122553c17c303157f74f6bf48242485e40 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Wed, 12 Nov 2014 23:14:41 +0100 Subject: [PATCH 44/58] GUI: find references in dump will not search for references to a range of selected addresses in the disassembly selection page --- x64_dbg_gui/Project/Src/Gui/CPUDump.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp index 6d7ca10e6..7fc916d53 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp @@ -1146,8 +1146,12 @@ void CPUDump::hardwareRemoveSlot() void CPUDump::findReferencesSlot() { - QString addrText = QString("%1").arg(rvaToVa(getInitialSelection()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); - DbgCmdExec(QString("findref " + addrText + ", " + addrText).toUtf8().constData()); + SELECTIONDATA selection; + GuiSelectionGet(GUI_DISASSEMBLY, &selection); + QString addrStart = QString("%1").arg(rvaToVa(getSelectionStart()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + QString addrEnd = QString("%1").arg(rvaToVa(getSelectionEnd()), sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + QString addrDisasm = QString("%1").arg(selection.start, sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + DbgCmdExec(QString("findrefrange " + addrStart + ", " + addrEnd + ", " + addrDisasm).toUtf8().constData()); emit displayReferencesWidget(); } From 899247356d74c554bff4193141a02c627766c479 Mon Sep 17 00:00:00 2001 From: dreg_fr33project Date: Thu, 13 Nov 2014 02:37:12 +0100 Subject: [PATCH 45/58] first basic avx support --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 1 + x64_dbg_dbg/TitanEngine/TitanEngine_x64.a | Bin 332442 -> 0 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 102362 -> 102566 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.a | Bin 331524 -> 0 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 106096 -> 106306 bytes x64_dbg_dbg/value.cpp | 79 ++++++++++++++++++++ 6 files changed, 80 insertions(+) delete mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x64.a delete mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x86.a diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index 974439a89..74ddb9951 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -835,6 +835,7 @@ __declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, voi __declspec(dllexport) bool TITCALL SetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); __declspec(dllexport) bool TITCALL SetContextData(DWORD IndexOfRegister, ULONG_PTR NewRegisterValue); __declspec(dllexport) bool TITCALL GetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) bool TITCALL SetAVXContext(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) void TITCALL ClearExceptionNumber(); __declspec(dllexport) long TITCALL CurrentExceptionNumber(); __declspec(dllexport) bool TITCALL MatchPatternEx(HANDLE hProcess, void* MemoryToCheck, int SizeOfMemoryToCheck, void* PatternToMatch, int SizeOfPatternToMatch, PBYTE WildCard); diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a deleted file mode 100644 index 3ecf455ff242624b4582e6ebab215c5fcea3dfb4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 332442 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 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a deleted file mode 100644 index ce7128290220fa97669676609cf3e0f1b3719d11..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 331524 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 diff --git a/x64_dbg_dbg/value.cpp b/x64_dbg_dbg/value.cpp index c34cabe31..c97078ff5 100644 --- a/x64_dbg_dbg/value.cpp +++ b/x64_dbg_dbg/value.cpp @@ -1557,6 +1557,7 @@ bool startsWith(const char* pre, const char* str) #define x87TW_PRE_FIELD_STRING "x87TW_" #define MMX_PRE_FIELD_STRING "MM" #define XMM_PRE_FIELD_STRING "XMM" +#define YMM_PRE_FIELD_STRING "YMM" #define x8780BITFPU_PRE_FIELD_STRING "x87r" #define STRLEN_USING_SIZEOF(string) (sizeof(string) - 1) @@ -1861,6 +1862,84 @@ void fpustuff(const char* string, uint value) if(found) SetContextDataEx(hActiveThread, registerindex, value); } + else if(startsWith(YMM_PRE_FIELD_STRING, string)) + { + string += STRLEN_USING_SIZEOF(YMM_PRE_FIELD_STRING); + DWORD registerindex; + bool found = true; + switch(atoi(string)) + { + case 0: + registerindex = UE_YMM0; + break; + + case 1: + registerindex = UE_YMM1; + break; + + case 2: + registerindex = UE_YMM2; + break; + + case 3: + registerindex = UE_YMM3; + break; + + case 4: + registerindex = UE_YMM4; + break; + + case 5: + registerindex = UE_YMM5; + break; + + case 6: + registerindex = UE_YMM6; + break; + + case 7: + registerindex = UE_YMM7; + break; + + case 8: + registerindex = UE_YMM8; + break; + + case 9: + registerindex = UE_YMM9; + break; + + case 10: + registerindex = UE_YMM10; + break; + + case 11: + registerindex = UE_YMM11; + break; + + case 12: + registerindex = UE_YMM12; + break; + + case 13: + registerindex = UE_YMM13; + break; + + case 14: + registerindex = UE_YMM14; + break; + + case 15: + registerindex = UE_YMM15; + break; + + default: + found = false; + break; + } + if(found) + SetContextDataEx(hActiveThread, registerindex, value); + } } bool valtostring(const char* string, uint* value, bool silent) From 021bc4d77814b88ff71f03ee232ae2d1836a5ad6 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 15 Nov 2014 14:56:16 +0100 Subject: [PATCH 46/58] DBG: removed crappy UString class and moved string manipulation/conversion functions in a StringUtils class --- x64_dbg_dbg/UString/Exception.cpp | 50 -- x64_dbg_dbg/UString/Exception.h | 64 -- x64_dbg_dbg/UString/String.cpp | 883 ------------------------ x64_dbg_dbg/UString/String.h | 309 --------- x64_dbg_dbg/UString/UString.cpp | 29 - x64_dbg_dbg/UString/UString.h | 12 - x64_dbg_dbg/_dbgfunctions.cpp | 2 +- x64_dbg_dbg/_exports.cpp | 4 +- x64_dbg_dbg/_global.cpp | 8 +- x64_dbg_dbg/_global.h | 2 +- x64_dbg_dbg/addrinfo.cpp | 6 +- x64_dbg_dbg/argument.cpp | 1 - x64_dbg_dbg/debugger.cpp | 28 +- x64_dbg_dbg/debugger_commands.cpp | 6 +- x64_dbg_dbg/instruction.cpp | 2 +- x64_dbg_dbg/math.cpp | 4 +- x64_dbg_dbg/patches.cpp | 6 +- x64_dbg_dbg/plugin_loader.cpp | 8 +- x64_dbg_dbg/simplescript.cpp | 2 +- x64_dbg_dbg/stringutils.cpp | 81 +++ x64_dbg_dbg/stringutils.h | 27 + x64_dbg_dbg/symbolinfo.cpp | 2 +- x64_dbg_dbg/variable.cpp | 39 +- x64_dbg_dbg/variable.h | 8 +- x64_dbg_dbg/x64_dbg.cpp | 20 +- x64_dbg_dbg/x64_dbg_dbg.vcxproj | 8 +- x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters | 30 +- 27 files changed, 178 insertions(+), 1463 deletions(-) delete mode 100644 x64_dbg_dbg/UString/Exception.cpp delete mode 100644 x64_dbg_dbg/UString/Exception.h delete mode 100644 x64_dbg_dbg/UString/String.cpp delete mode 100644 x64_dbg_dbg/UString/String.h delete mode 100644 x64_dbg_dbg/UString/UString.cpp delete mode 100644 x64_dbg_dbg/UString/UString.h create mode 100644 x64_dbg_dbg/stringutils.cpp create mode 100644 x64_dbg_dbg/stringutils.h diff --git a/x64_dbg_dbg/UString/Exception.cpp b/x64_dbg_dbg/UString/Exception.cpp deleted file mode 100644 index 20e8c5b8c..000000000 --- a/x64_dbg_dbg/UString/Exception.cpp +++ /dev/null @@ -1,50 +0,0 @@ -/** - * UTF8 string library. - * - * Allows to use native UTF8 sequences as a string class. Has many overloaded - * operators that provides such features as concatenation, types converting and - * much more. - * - * Distributed under GPL v3 - * - * Author: - * Grigory Gorelov (gorelov@grigory.info) - * See more information on grigory.info - */ - -#include "Exception.h" - -UTF8::Exception::Exception(const std::string & error, const int & StatusCode) -{ - this->error = error; - this->StatusCode = StatusCode; -} - -UTF8::Exception::Exception(std::string error) -{ - this->error = error; - this->StatusCode = UnspecifiedException; -} - -UTF8::Exception::Exception(const UTF8::Exception & e) -{ - error = e.error; - StatusCode = e.StatusCode; -} - -std::string UTF8::Exception::GetErrorString() const -{ - return error; -} - -int UTF8::Exception::GetErrorCode() const -{ - return StatusCode; -} - -UTF8::Exception & UTF8::Exception::operator =(const UTF8::Exception & e) -{ - error = e.error; - error = e.StatusCode; - return *this; -} diff --git a/x64_dbg_dbg/UString/Exception.h b/x64_dbg_dbg/UString/Exception.h deleted file mode 100644 index c75b1e246..000000000 --- a/x64_dbg_dbg/UString/Exception.h +++ /dev/null @@ -1,64 +0,0 @@ -/** - * UTF8 string library. - * - * Allows to use native UTF8 sequences as a string class. Has many overloaded - * operators that provides such features as concatenation, types converting and - * much more. - * - * Distributed under GPL v3 - * - * Author: - * Grigory Gorelov (gorelov@grigory.info) - * See more information on grigory.info - */ - -#ifndef _UTF8_Exception_H -#define _UTF8_Exception_H - -#include - -namespace UTF8 -{ -/** - * Exception class. When something bad happens it is thowed by UTF8::String. - */ -class Exception -{ -public: - enum - { - UnspecifiedException = 1, - StringToIntConversionError = 2, - StringToDoubleConversionError = 3, - FileNotFound = 4, - StringIsNotACharacter = 5 - }; - - /** - * Just a constructor - */ - Exception(std::string error); - - /// Just a constructor - Exception(const std::string & error, const int & StatusCode); - - /// Copying constructor - Exception(const Exception & e); - - /// Returns error string - std::string GetErrorString() const; - - /// Returns error code - int GetErrorCode() const; - - /// Assing operator - Exception & operator =(const Exception &); - -private: - std::string error; - int StatusCode; - -}; -} - -#endif /* _EXCEPTION_H */ diff --git a/x64_dbg_dbg/UString/String.cpp b/x64_dbg_dbg/UString/String.cpp deleted file mode 100644 index 3a80cdaa4..000000000 --- a/x64_dbg_dbg/UString/String.cpp +++ /dev/null @@ -1,883 +0,0 @@ -/** - * UTF8 string library. - * - * Allows to use native UTF8 sequences as a string class. Has many overloaded - * operators that provides such features as concatenation, types converting and - * much more. - * - * Distributed under GPL v3 - * - * Author: - * Grigory Gorelov (gorelov@grigory.info) - * See more information on grigory.info - */ - -#include "String.h" -#include -#include -#include -#include -#include -#include -#include -#include "Exception.h" - -bool UTF8::String::HasThisString(const UTF8::String & Str) const -{ - return GetSubstringPosition(Str) != -1; -} - -bool UTF8::String::CharacterIsOneOfThese(const UTF8::String & Characters) const -{ - if(Length() == 1) - { - for(unsigned int i = 0; i < Characters.Length(); i++) - { - if(Characters[i] == *this) - { - return true; - } - } - return false; - } - else - { - throw Exception("[CharacterIsOneOfThese] String is more then one character length: \"" + ToString() + "\"", UTF8::Exception::StringIsNotACharacter); - } -} - -UTF8::String UTF8::String::FromFile(const UTF8::String & Path) -{ - UTF8::String s; - - std::ifstream File; - File.open(Path.ToConstCharPtr()); - - if(File.is_open()) - { - File.seekg(0, std::ios::end); - size_t Length = (size_t)File.tellg(); - File.seekg(0, std::ios::beg); - - char* buf = new char[Length + 1]; - memset(buf, 0, Length + 1); - - File.read(buf, Length); - s.AppendString(buf); - - delete[] buf; - } - else - { - throw Exception("Cannot open file \"" + Path.ToString() + "\"", UTF8::Exception::FileNotFound); - } - - File.close(); - - return s; -} - -long UTF8::String::Search(const UTF8::String & SubString, unsigned int StartPosition, int Direction) const -{ - unsigned int SubstringLength = SubString.Length(); - unsigned int n = StartPosition; - - if(n > Length() - SubstringLength) - { - if(Direction == SearchDirectionFromLeftToRight) - { - return -1; - } - else - { - n = Length() - SubstringLength; - } - } - - if((int)n < 0) - { - if(Direction == SearchDirectionFromRightToLeft) - { - return -1; - } - else - { - n = 0; - } - } - - while(((Direction == SearchDirectionFromLeftToRight) && (n < Length() - SubstringLength + 1)) || ((Direction == SearchDirectionFromRightToLeft) && ((int)n >= 0))) - { - - if(this->Substring(n, SubstringLength) == SubString) - { - return n; - } - - n += Direction == SearchDirectionFromLeftToRight ? 1 : -1; - } - - return -1; -} - -std::ostream & operator<<(std::ostream & os, const UTF8::String & s) -{ - os << s.ToString(); - - return os; -} - -bool operator==(const char* str, const UTF8::String & StringObj) -{ - return StringObj == str; -} - -bool operator==(const std::string & str, const UTF8::String & StringObj) -{ - return StringObj == str; -} - -bool operator!=(const char* str, const UTF8::String & StringObj) -{ - return StringObj != str; -} - -bool operator!=(const std::string & str, const UTF8::String & StringObj) -{ - return StringObj != str; -} - -UTF8::String UTF8::String::Quote() const -{ - return "\"" + (*this) + "\""; -} - -UTF8::String UTF8::String::Trim() const -{ - UTF8::String result = *this; - unsigned int i = 0; - - while((result[i] == " ") || (result[i] == "\n") || (result[i] == "\r") || (result[i] == "\t")) - { - i++; - } - - if(i == result.Length()) - { - return UTF8::String(); - } - - long j = result.Length(); - while((result[j - 1] == " ") || (result[j - 1] == "\n") || (result[j - 1] == "\r") || (result[j - 1] == "\t")) - { - j--; - } - - result = result.Substring(i, j - i); - - return result; -} - -UTF8::String UTF8::String::Replace(const UTF8::String & Search, const UTF8::String & Replace) const -{ - UTF8::String result = *this; - - // Long to cover unsigned int and -1 - long pos = 0; - while((pos = result.Search(Search, pos)) != -1) - { - result = result.SubstringReplace(pos, Search.Length(), Replace); - - // Next time we search after replacement - pos += Replace.Length(); - } - - return result; - -} - -UTF8::String UTF8::String::SubstringReplace(unsigned int Start, unsigned int Count, const UTF8::String & Replace) const -{ - if(Start < Length()) - { - return (Start ? Substring(0, Start) : UTF8::String()) + Replace + Substring(Start + Count); - } - else - { - return *this; - } -} - -UTF8::String UTF8::String::Implode(const std::vector & Strings, const UTF8::String & Separator) -{ - if(Strings.size()) - { - UTF8::String Result; - - for(unsigned int i = 0; i < Strings.size(); i++) - { - if(Result.Length()) - { - Result += Separator; - } - Result += Strings[i]; - } - return Result; - } - else - { - return UTF8::String(); - } -} - -std::vector UTF8::String::Explode(const String & Separator) const -{ - std::vector v; - - unsigned int prev = 0; - - unsigned int i = 0; - - while(i < Length() - Separator.Length() + 1) - { - if(Substring(i, Separator.Length()) == Separator) - { - if(i - prev > 0) - { - v.push_back(Substring(prev, i - prev)); - } - i += Separator.Length(); - prev = i; - } - else - { - i++; - } - } - - if(prev < Length()) - { - v.push_back(Substring(prev, Length() - prev)); - } - - return v; -} - -UTF8::String operator+(const char* CharPtr, const UTF8::String & StringObj) -{ - UTF8::String s(CharPtr); - s += StringObj; - - return s; -} - -UTF8::String operator+(const std::string & str, const UTF8::String & StringObj) -{ - UTF8::String s(str); - s += StringObj; - - return s; -} - -UTF8::String UTF8::String::operator+(const UTF8::String & s) const -{ - UTF8::String res(*this); - res.AppendString(s.Data); - - return res; -} - -UTF8::String & UTF8::String::operator+=(const UTF8::String & s) -{ - AppendString(s.Data); - - return *this; -} - -void UTF8::String::AppendString(const char* str) -{ - // The functions that can fill buffer directly: - // - // SetString AppendString - // - // Make sure all preparations are done there - - if(str && strlen(str)) - { - if(DataArrayLength) - { - CheckIfStringIsCorrect(str); - - unsigned int StrLength = (unsigned int)strlen(str); - - Data = (char*) realloc(Data, DataArrayLength + StrLength + 1); - - if(Data != NULL) - { - memcpy(Data + DataArrayLength, str, StrLength); - DataArrayLength += StrLength; - Data[DataArrayLength] = 0; - - CalculateStringLength(); - } - else - { - throw Exception("[AppendString] Cannot realloc any more memory"); - } - } - else - { - SetString(str); - } - } -} - -void UTF8::String::SetString(const char* str) -{ - // The functions that can fill buffer directly: - // - // SetString AppendString - // - // Make sure all preparations are done there - - if(str && strlen(str)) - { - CheckIfStringIsCorrect(str); - - Empty(); - - DataArrayLength = (unsigned int)strlen(str); - Data = new char[DataArrayLength + 1]; - Data[DataArrayLength] = 0; - - memcpy(Data, str, DataArrayLength); - - CalculateStringLength(); - } - else - { - Empty(); - } -} - -void UTF8::String::ConvertFromInt64(int64_t n) -{ - Empty(); - - if(n) - { - bool minus; - if(n < 0) - { - n = -n; - minus = true; - } - else - { - minus = false; - } - - char tmp[32] = "0"; - const char* num = "0123456789"; - memset(tmp, 0, 32); - - unsigned int i = 30; - - while(n) - { - tmp[i] = num[n % 10]; - n /= 10; - i--; - - if(((int)i < 0) || ((i < 1) && minus)) - { - throw Exception("[ConvertFromInt] Cycle terminated, buffer overflow."); - } - } - - if(minus) - { - tmp[i] = '-'; - i--; - } - - SetString(tmp + i + 1); - } - else - { - SetString("0"); - } - - CalculateStringLength(); -} - -void UTF8::String::InitString() -{ - Data = NULL; - DataArrayLength = 0; - StringLength = 0; -} - -UTF8::String::String() -{ - InitString(); -} - -UTF8::String::String(const std::string & s) -{ - InitString(); - CheckIfStringIsCorrect(s.c_str()); - AppendString(s.c_str()); - CalculateStringLength(); -} - -int UTF8::String::GetSymbolIndexInDataArray(unsigned int Position) const -{ - if(Position >= StringLength) - { - throw Exception(UTF8::String("[GetSymbolIndexInDataArray] trying to get position beyond the end of string.")); - } - - unsigned int n = 0; - for(unsigned int i = 0; i < Position; i++) - { - n += GetSequenceLength(Data + n); - } - return n; - -} - -long UTF8::String::GetSubstringPosition(const UTF8::String & SubString, unsigned int Start) const -{ - if(SubString.Length() > StringLength) - { - return -1; - } - - unsigned int ScansCount = StringLength - SubString.StringLength + 1 - Start; - for(unsigned int i = 0; i < ScansCount; i++) - { - if(this->Substring(i + Start, SubString.StringLength) == SubString) - { - return i + Start; - } - } - - return -1; -} - -UTF8::String UTF8::String::Substring(unsigned int Start, unsigned int Count) const -{ - if(Start >= StringLength) - { - return UTF8::String(); - } - - if((Start + Count > StringLength) || (Count == 0)) - { - Count = StringLength - Start; - } - - unsigned int StartIndex = GetSymbolIndexInDataArray(Start); - unsigned int CopyAmount = 0; - - for(unsigned int i = 0; i < Count; i++) - { - CopyAmount += GetSequenceLength(Data + StartIndex + CopyAmount); - } - - char* tmp = new char[CopyAmount + 1]; - memcpy(tmp, Data + StartIndex, CopyAmount); - tmp[CopyAmount] = 0; - - UTF8::String r(tmp); - delete[] tmp; - - return r; -} - -UTF8::String::String(const char* str) -{ - InitString(); - SetString(str); -} - -UTF8::String::String(const uint32_t* str) -{ - InitString(); - ConvertFromUTF32(str); -} - -void UTF8::String::ConvertFromUTF32(const uint32_t* s) -{ - if(s) - { - unsigned int WideStringLength = 0; - do - { - WideStringLength++; - if(WideStringLength == 4294967295UL) - { - throw Exception("[ConvertFromUTF32] Cannot find termination symbol in incoming string."); - } - } - while(s[WideStringLength]); - - char* tmp = new char[WideStringLength * 4 + 1]; - memset(tmp, 0, WideStringLength * 4 + 1); - unsigned int pos = 0; - - for(unsigned int i = 0; i < WideStringLength; i++) - { - uint32_t wc = s[i]; - - if(wc < 0x80) - { - tmp[pos++] = wc; - } - else if(wc < 0x800) - { - tmp[pos++] = (wc >> 6) | 0xC0 /* 0b11000000 */; - tmp[pos++] = (wc & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */; - } - else if(wc < 0x10000) - { - tmp[pos++] = (wc >> 12) | 0xE0 /* 0b11100000 */; - tmp[pos++] = ((wc >> 6) & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */; - tmp[pos++] = (wc & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */; - } - else - { - - tmp[pos++] = (wc >> 18) | 0xF0 /* 0b11110000 */; - tmp[pos++] = ((wc >> 12) & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */; - tmp[pos++] = ((wc >> 6) & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */; - tmp[pos++] = (wc & 0x3F /* 0b00111111 */) | 0x80 /* 0b10000000 */; - } - } - - SetString(tmp); - - delete[] tmp; - } -} - -void UTF8::String::CalculateStringLength() -{ - // We are not writing anything to memory so limits are not needed - if(Data) - { - unsigned int n = 0, count = 0; - do - { - // We do not need to check line end here, it is checked when string is changed - n += GetSequenceLength(Data + n); - count++; - } - while(Data[n]); - - StringLength = count; - } - else - { - StringLength = 0; - } -} - -void UTF8::String::CheckIfStringIsCorrect(const char* str) const -{ - if(str) - { - // We are not writing anything to memory so limits are not needed - unsigned int n = 0, i; - unsigned int SequenceLength; - while(str[n]) - { - SequenceLength = GetSequenceLength(str + n); - for(i = 1; i < SequenceLength; i++) - { - if((((unsigned char) str[n + i]) >> 6) != 0x2 /* 0b00000010 */) - { - std::string s(str); - throw Exception("[CheckIfStringIsCorrect] Incorrect byte in UTF8 sequence: \"" + s + "\""); - } - } - n += SequenceLength; - if(n >= 0xFFFFFFFF - 4) - { - - std::string s(str); - throw Exception("[CheckIfStringIsCorrect] termination char was not found in string: \"" + s + "\""); - } - } - } -} - -bool UTF8::String::operator>(const UTF8::String & s) const -{ - if(*this == s) - { - return false; - } - - if(*this < s) - { - return false; - } - - return true; -} - -bool UTF8::String::operator<(const UTF8::String & s) const -{ - unsigned int MinLength = StringLength < s.StringLength ? StringLength : s.StringLength; - - //std::cout << "MinLength=" << MinLength; - - unsigned int MyPos = 0, RemotePos = 0; - unsigned int MySequenceLength, RemoteSequenceLength; - for(unsigned int i = 0; i < MinLength; i++) - { - MySequenceLength = GetSequenceLength(Data + MyPos); - RemoteSequenceLength = GetSequenceLength(s.Data + RemotePos); - - if(MySequenceLength < RemoteSequenceLength) - { - return true; - } - - if(MySequenceLength > RemoteSequenceLength) - { - return false; - } - - for(unsigned int j = 0; j < MySequenceLength; j++) - { - if(Data[MyPos + j] < s.Data[RemotePos + j]) - { - return true; - } - - if(Data[MyPos + j] > s.Data[RemotePos + j]) - { - return false; - } - } - - MyPos += MySequenceLength; - RemotePos += RemoteSequenceLength; - } - - // If this string is substring of s (from left side) then it is lower - return StringLength < s.StringLength; -} - -UTF8::String UTF8::String::operator[](unsigned int const n) const -{ - if(n >= StringLength) - { - return UTF8::String(); - } - - if((int)n < 0) - { - return UTF8::String(); - } - - unsigned int pos = 0; - for(unsigned int i = 0; i < n; i++) - { - pos += GetSequenceLength(Data + pos); - } - - char t[5]; - memset(t, 0, 5); - memcpy(t, Data + pos, GetSequenceLength(Data + pos)); - - return UTF8::String(t); -} - -unsigned int UTF8::String::GetSequenceLength(const char* StartByte) const -{ - if(StartByte && strlen(StartByte)) - { - unsigned char Byte = StartByte[0]; - if(Byte < 128) - { - return 1; - } - - // Here we need back order due to mask operation - if((Byte >> 5) == 0x6 /* 0b00000110 */) - { - return 2; - } - - if((Byte >> 4) == 0xE /* 0b00001110 */) - { - return 3; - } - - if((Byte >> 3) == 0x1E /* 0b00011110 */) - { - return 4; - } - - throw Exception(std::string("[GetSequenceLength] Invalid UTF8 start byte. My own string is: [") + Data + "] Argument is: [" + StartByte + "]"); - } - else - { - if(StartByte == 0) - StartByte = "(null)"; - throw Exception(std::string("[GetSequenceLength] Invalid UTF8 start byte (it is empty). My own string is: [") + Data + "] Argument is: [" + StartByte + "]"); - } -} - -UTF8::String & UTF8::String::operator=(const String & Original) -{ - // Check if objects are not same - if((unsigned int long) &Original != (unsigned int long) this) - { - Empty(); - SetString(Original.Data); - } - - return *this; -} - -UTF8::String & UTF8::String::operator=(const char* str) -{ - Empty(); - SetString(str); - - return *this; -} - -UTF8::String & UTF8::String::operator=(const uint32_t* str) -{ - Empty(); - ConvertFromUTF32(str); - - return *this; -} - -UTF8::String::operator std::string() const -{ - return this->ToString(); -} - -void UTF8::String::Empty() -{ - if(DataArrayLength) - { - delete Data; - InitString(); - } -} - -std::string UTF8::String::ToString() const -{ - if(DataArrayLength) - { - return std::string(Data); - } - else - { - return std::string(); - } -} - -UTF8::String UTF8::String::operator+(const char* s) const -{ - UTF8::String res(*this); - res.AppendString(s); - - return res; -} - -bool UTF8::String::operator==(const UTF8::String & s) const -{ - if(DataArrayLength != s.DataArrayLength) - { - return false; - } - else - { - for(unsigned int i = 0; i < DataArrayLength; i++) - { - if(Data[i] != s.Data[i]) - { - return false; - } - } - return true; - } -} - -bool UTF8::String::operator!=(const UTF8::String & s) const -{ - return !(*this == s); -} - -bool UTF8::String::operator==(const char* str) const -{ - if(str && strlen(str)) - { - if(DataArrayLength != strlen(str)) - { - return false; - } - else - { - for(unsigned int i = 0; i < DataArrayLength; i++) - { - if(Data[i] != str[i]) - { - return false; - } - } - - return true; - } - } - else - { - return StringLength == 0; - } -} - -bool UTF8::String::operator!=(const char* str) const -{ - return !(*this == str); -} - -const char* UTF8::String::ToConstCharPtr() const -{ - return Data; -} - -const char* UTF8::String::c_str() const -{ - return Data; -} - -unsigned int UTF8::String::Length() const -{ - return StringLength; -} - -unsigned int UTF8::String::DataLength() const -{ - return DataArrayLength; -} - -UTF8::String::~String() -{ - Empty(); -} - -UTF8::String::String(const String & orig) -{ - InitString(); - SetString(orig.Data); -} diff --git a/x64_dbg_dbg/UString/String.h b/x64_dbg_dbg/UString/String.h deleted file mode 100644 index ce2aa582e..000000000 --- a/x64_dbg_dbg/UString/String.h +++ /dev/null @@ -1,309 +0,0 @@ -/** - * UTF8 string library. - * - * Allows to use native UTF8 sequences as a string class. Has many overloaded - * operators that provides such features as concatenation, types converting and - * much more. - * - * Distributed under GPL v3 - * - * Author: - * Grigory Gorelov (gorelov@grigory.info) - * See more information on grigory.info - */ - -#ifndef _UTF8_String_H -#define _UTF8_String_H - -#include "Exception.h" -#include -#include -#include -#include - -namespace UTF8 -{ -/** - * The only string class containing everything to work with UTF8 strings - */ -class String -{ -public: - static const int SearchDirectionFromLeftToRight = 1; - static const int SearchDirectionFromRightToLeft = 2; - - /** - * Search substring in string - * @param StartPosition Position to start search - * @param Direction Search forward or backward, uses SearchDirectionFromLeftToRight and SearchDirectionFromRightToLeft - * @return Returns position of substring if found. Otherwise returns -1 - */ - long Search(const UTF8::String & SubString, unsigned int StartPosition = 0, int Direction = SearchDirectionFromLeftToRight) const; - - /// Simple constructor only initiates buffers - String(); - - /** - * Create string object from UTF8 char * string - */ - String(const char* str); - - /** - * Create string object from UTF-32 string - */ - String(const uint32_t*); - - /** - * Create string object from UTF8 std::string - */ - String(const std::string &); - - /** - * Copying constructor. Feel free to such things UTF8::String s2=s1; - */ - String(const String & orig); - - /** - * Deconstructor. - */ - ~String(); - - /** - * Converts UTF8::String to std::string - */ - std::string ToString() const; - - /** - * Reads content from a file and returns as UTF8::String - */ - static String FromFile(const UTF8::String & Path); - - /** - * Converts UTF8::String to const char * - */ - const char* ToConstCharPtr() const; - - /** - * Converts UTF8::String to const char * - */ - const char* c_str() const; - - /** - * Separates string using given separator and returns vector - */ - std::vector Explode(const String & Separator) const; - - /** - * Creating String from array of String adding separator between them. - */ - static String Implode(const std::vector & Strings, const String & Separator); - - /** - * Sum operator. Provides String1+String2 exression. - */ - String operator+(const String &) const; - - /** - * Sum operator. Provides String1+"Str" exression. - */ - String operator+(const char*) const; - - /** - * Unary sum operator. Provides String1+=String2 expression. - */ - String & operator+=(const String &); - - /** - * Assign operator. Provides String1=String2 expression. - */ - String & operator=(const String &); - - /** - * Assign operator. Provides String1="New value" expression. - */ - String & operator=(const char*); - - /** - * Assign operator. Provides String1=(uint32_t*) UTF32_StringPointer expression. - * Automatically converts UNICODE to UTF-8 ans stores in itself - */ - String & operator=(const uint32_t*); - - /** - * Provides std::string test=String expression. - */ - operator std::string() const; - - /** - * Returns substring of current string. - * @param Start Start position of substring - * @param Count Number of sybmols after start position. If number==0 string from Start till end is returned. - */ - String Substring(unsigned int Start, unsigned int Count = 0) const; - - /** - * Replaces one text peace by another and returns result - * @param Search Search string - * @param Replace Replace string - * @return Returns result of replacement - */ - String Replace(const String & Search, const String & Replace) const; - - /** - * Returns trimmed string. Removes whitespaces from left and right - */ - String Trim() const; - - /** - * Returns string with nice quotes like this « ». - */ - String Quote() const; - - /** - * Replaces region of string by text peace and returns result. - * @param Search Search string - * @param Replace Replace string - * @return Returns result of replacement - */ - String SubstringReplace(unsigned int Start, unsigned int Count, const String & Replace) const; - - /** - * Returns position of substring in current string. - * @param Start Position to start search. Default is 0. - * @return If substring not found returns -1. - */ - long GetSubstringPosition(const UTF8::String & SubString, unsigned int Start = 0) const; - - /** - * Get one char operator. Provides UTF8::String c=String1[1]; - */ - String operator[](unsigned int const) const; - - /** - * Test operator. Provides String1==String2 expression. - */ - bool operator==(const UTF8::String &) const; - - /** - * Test operator. Provides String1!=String2 expression. - */ - bool operator!=(const UTF8::String &) const; - - /** - * Test operator. Provides String1=="Test" expression. - */ - bool operator==(const char*) const; - - /** - * Test operator. Provides String1!="Test" expression. - */ - bool operator!=(const char*) const; - - /** Test operator. Provides String1String2 expression. - * Operator compares left characters of two strings. - * If String1[0] value is greater then the String2[0] returns true. - * If they are equal then goes to second character and so on. - * Can be used to sort strings alphabetical. - */ - bool operator>(const UTF8::String &) const; - - /** - * Returns current string length. Also see DataLength to get buffer - * size - */ - unsigned int Length() const; - - /** - * Returns current char data array length, containig UTF8 string. - * As one character in UTF8 can be stored by more then one byte use - * this function to know how much memory allocated for the string. - */ - unsigned int DataLength() const; - - /** - * Clears current string as if it is just created - */ - void Empty(); - - /** - * If string is a one character check if it is one of given - */ - bool CharacterIsOneOfThese(const UTF8::String & Characters) const; - - /** - * Checks if this string contains given another string - */ - bool HasThisString(const UTF8::String & Str) const; - - /** - * Special function to convert from very big integers - * Normally it is ok to assing UTF8::String to number. Or construct from it. - * This function exists only for very very big integers conversion. - */ - void ConvertFromInt64(int64_t n); - -private: - char* Data; - unsigned int DataArrayLength; - unsigned int StringLength; - - unsigned int GetSequenceLength(const char* StartByte) const; - void CheckIfStringIsCorrect(const char* str) const; - void CalculateStringLength(); - - void InitString(); - void AppendString(const char* str); - void SetString(const char* str); - int GetSymbolIndexInDataArray(unsigned int Position) const; - - void ConvertFromUTF32(const uint32_t*); - -}; -} - -/** - * Not in class overloaded operator +. Provides "Sample"+String1 expression. - */ -UTF8::String operator+(const char*, const UTF8::String &); - -/** - * Not in class overloaded operator +. Provides std::string("123")+String1 expression. - */ -UTF8::String operator+(const std::string &, const UTF8::String &); - -/** - * Not in class overloaded operator ==. Provides "Test"==String1 expression. - */ -bool operator==(const char*, const UTF8::String &); - -/** - * Not in class overloaded operator ==. Provides std::string==String1 expression. - */ -bool operator==(const std::string &, const UTF8::String &); - -/** - * Not in class overloaded operator !=. Provides "Test"!=String1 expression. - */ -bool operator!=(const char*, const UTF8::String &); - -/** - * Not in class overloaded operator !=. Provides std::string!=String1 expression. - */ -bool operator!=(const std::string &, const UTF8::String &); - -/** - * Overloading for cout. Provides std::cout << (UTF8::String) operation; - */ -std::ostream & operator<<(std::ostream & os, const UTF8::String & s); - -#endif /* _UTF8STRING_H */ - - diff --git a/x64_dbg_dbg/UString/UString.cpp b/x64_dbg_dbg/UString/UString.cpp deleted file mode 100644 index da56843cd..000000000 --- a/x64_dbg_dbg/UString/UString.cpp +++ /dev/null @@ -1,29 +0,0 @@ -#include "UString.h" -#include - -//Functions taken from: http://www.nubaria.com/en/blog/?p=289 -UString ConvertUtf16ToUtf8(const std::wstring & wstr) -{ - std::string convertedString; - int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0); - if(requiredSize > 0) - { - std::vector buffer(requiredSize); - WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, 0, 0); - convertedString.assign(buffer.begin(), buffer.end() - 1); - } - return convertedString; -} - -std::wstring ConvertUtf8ToUtf16(const UString & str) -{ - std::wstring convertedString; - int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0); - if(requiredSize > 0) - { - std::vector buffer(requiredSize); - MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize); - convertedString.assign(buffer.begin(), buffer.end() - 1); - } - return convertedString; -} diff --git a/x64_dbg_dbg/UString/UString.h b/x64_dbg_dbg/UString/UString.h deleted file mode 100644 index 4e0328f4e..000000000 --- a/x64_dbg_dbg/UString/UString.h +++ /dev/null @@ -1,12 +0,0 @@ -#ifndef _USTRING_H -#define _USTRING_H - -#include "String.h" -#include - -typedef UTF8::String UString; - -UString ConvertUtf16ToUtf8(const std::wstring & wstr); -std::wstring ConvertUtf8ToUtf16(const UString & str); - -#endif // _USTRING_H diff --git a/x64_dbg_dbg/_dbgfunctions.cpp b/x64_dbg_dbg/_dbgfunctions.cpp index 5acad5970..65e0eecb0 100644 --- a/x64_dbg_dbg/_dbgfunctions.cpp +++ b/x64_dbg_dbg/_dbgfunctions.cpp @@ -100,7 +100,7 @@ static int _modpathfromaddr(duint addr, char* path, int size) *path = '\0'; return 0; } - strcpy_s(path, size, ConvertUtf16ToUtf8(wszModPath).c_str()); + strcpy_s(path, size, StringUtils::Utf16ToUtf8(wszModPath()).c_str()); return (int)strlen(path); } diff --git a/x64_dbg_dbg/_exports.cpp b/x64_dbg_dbg/_exports.cpp index 47e878293..4038e19ff 100644 --- a/x64_dbg_dbg/_exports.cpp +++ b/x64_dbg_dbg/_exports.cpp @@ -173,8 +173,8 @@ extern "C" DLL_EXPORT bool _dbg_addrinfoget(duint addr, SEGMENTREG segment, ADDR else if(!bOnlyCipAutoComments || addr == GetContextDataEx(hActiveThread, UE_CIP)) //no line number { DISASM_INSTR instr; - std::string temp_string; - std::string comment; + String temp_string; + String comment; ADDRINFO newinfo; char ascii[256 * 2] = ""; char unicode[256 * 2] = ""; diff --git a/x64_dbg_dbg/_global.cpp b/x64_dbg_dbg/_global.cpp index ede7387f2..b6d390530 100644 --- a/x64_dbg_dbg/_global.cpp +++ b/x64_dbg_dbg/_global.cpp @@ -141,13 +141,13 @@ void formatdec(char* string) bool FileExists(const char* file) { - DWORD attrib = GetFileAttributesW(ConvertUtf8ToUtf16(file).c_str()); + DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(file).c_str()); return (attrib != INVALID_FILE_ATTRIBUTES && !(attrib & FILE_ATTRIBUTE_DIRECTORY)); } bool DirExists(const char* dir) { - DWORD attrib = GetFileAttributesW(ConvertUtf8ToUtf16(dir).c_str()); + DWORD attrib = GetFileAttributesW(StringUtils::Utf8ToUtf16(dir).c_str()); return (attrib == FILE_ATTRIBUTE_DIRECTORY); } @@ -156,7 +156,7 @@ bool GetFileNameFromHandle(HANDLE hFile, char* szFileName) wchar_t wszFileName[MAX_PATH] = L""; if(!PathFromFileHandleW(hFile, wszFileName, sizeof(wszFileName))) return false; - strcpy_s(szFileName, MAX_PATH, ConvertUtf16ToUtf8(wszFileName).c_str()); + strcpy_s(szFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str()); return true; } @@ -173,7 +173,7 @@ bool settingboolget(const char* section, const char* name) arch GetFileArchitecture(const char* szFileName) { arch retval = notfound; - HANDLE hFile = CreateFileW(ConvertUtf8ToUtf16(szFileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + HANDLE hFile = CreateFileW(StringUtils::Utf8ToUtf16(szFileName).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(hFile != INVALID_HANDLE_VALUE) { unsigned char data[0x1000]; diff --git a/x64_dbg_dbg/_global.h b/x64_dbg_dbg/_global.h index c5f4c98da..5ac006066 100644 --- a/x64_dbg_dbg/_global.h +++ b/x64_dbg_dbg/_global.h @@ -21,7 +21,7 @@ #include "jansson\jansson.h" #include "DeviceNameResolver\DeviceNameResolver.h" #include "handle.h" -#include "UString\UString.h" +#include "stringutils.h" #ifdef __GNUC__ #include "dbghelp\dbghelp.h" diff --git a/x64_dbg_dbg/addrinfo.cpp b/x64_dbg_dbg/addrinfo.cpp index 131342d0f..91ec1025b 100644 --- a/x64_dbg_dbg/addrinfo.cpp +++ b/x64_dbg_dbg/addrinfo.cpp @@ -28,7 +28,7 @@ void dbsave() functioncachesave(root); loopcachesave(root); bpcachesave(root); - std::wstring wdbpath = ConvertUtf8ToUtf16(dbpath); + WString wdbpath = StringUtils::Utf8ToUtf16(dbpath); if(json_object_size(root)) { FILE* jsonFile = 0; @@ -59,7 +59,7 @@ void dbload() return; dprintf("loading database..."); DWORD ticks = GetTickCount(); - std::wstring wdbpath = ConvertUtf8ToUtf16(dbpath); + WString wdbpath = StringUtils::Utf8ToUtf16(dbpath); LZ4_STATUS status = LZ4_decompress_fileW(wdbpath.c_str(), wdbpath.c_str()); if(status != LZ4_SUCCESS && status != LZ4_INVALID_ARCHIVE) { @@ -139,7 +139,7 @@ bool modload(uint base, uint size, const char* fullpath) DWORD LoadedSize; HANDLE FileMap; ULONG_PTR FileMapVA; - std::wstring wszFullPath = ConvertUtf8ToUtf16(fullpath); + WString wszFullPath = StringUtils::Utf8ToUtf16(fullpath); if(StaticFileLoadW(wszFullPath.c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) { info.entry = GetPE32DataFromMappedFile(FileMapVA, 0, UE_OEP) + info.base; //get entry point diff --git a/x64_dbg_dbg/argument.cpp b/x64_dbg_dbg/argument.cpp index e26aaea28..a0b160a86 100644 --- a/x64_dbg_dbg/argument.cpp +++ b/x64_dbg_dbg/argument.cpp @@ -1,6 +1,5 @@ #include "argument.h" #include "console.h" -#include "UString/UString.h" /* formatarg: diff --git a/x64_dbg_dbg/debugger.cpp b/x64_dbg_dbg/debugger.cpp index d8e4c4796..9d4d00b1c 100644 --- a/x64_dbg_dbg/debugger.cpp +++ b/x64_dbg_dbg/debugger.cpp @@ -656,7 +656,7 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo) if(!DevicePathFromFileHandleW(CreateProcessInfo->hFile, wszFileName, sizeof(wszFileName))) strcpy(DebugFileName, "??? (GetFileNameFromHandle failed!)"); else - strcpy_s(DebugFileName, MAX_PATH, ConvertUtf16ToUtf8(wszFileName).c_str()); + strcpy_s(DebugFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str()); } dprintf("Process Started: "fhex" %s\n", base, DebugFileName); @@ -701,12 +701,12 @@ static void cbCreateProcess(CREATE_PROCESS_DEBUG_INFO* CreateProcessInfo) if(settingboolget("Events", "TlsCallbacks")) { DWORD NumberOfCallBacks = 0; - TLSGrabCallBackDataW(ConvertUtf8ToUtf16(DebugFileName).c_str(), 0, &NumberOfCallBacks); + TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), 0, &NumberOfCallBacks); if(NumberOfCallBacks) { dprintf("TLS Callbacks: %d\n", NumberOfCallBacks); Memory TLSCallBacks(NumberOfCallBacks * sizeof(uint), "cbCreateProcess:TLSCallBacks"); - if(!TLSGrabCallBackDataW(ConvertUtf8ToUtf16(DebugFileName).c_str(), TLSCallBacks, &NumberOfCallBacks)) + if(!TLSGrabCallBackDataW(StringUtils::Utf8ToUtf16(DebugFileName).c_str(), TLSCallBacks, &NumberOfCallBacks)) dputs("failed to get TLS callback addresses!"); else { @@ -858,7 +858,7 @@ static void cbLoadDll(LOAD_DLL_DEBUG_INFO* LoadDll) if(!DevicePathFromFileHandleW(LoadDll->hFile, wszFileName, sizeof(wszFileName))) strcpy(DLLDebugFileName, "??? (GetFileNameFromHandle failed!)"); else - strcpy_s(DLLDebugFileName, MAX_PATH, ConvertUtf16ToUtf8(wszFileName).c_str()); + strcpy_s(DLLDebugFileName, MAX_PATH, StringUtils::Utf16ToUtf8(wszFileName).c_str()); } SymLoadModuleEx(fdProcessInfo->hProcess, LoadDll->hFile, DLLDebugFileName, 0, (DWORD64)base, 0, 0, 0); IMAGEHLP_MODULE64 modInfo; @@ -1172,13 +1172,13 @@ DWORD WINAPI threadDebugLoop(void* lpParameter) bSkipExceptions = false; bBreakOnNextDll = false; INIT_STRUCT* init = (INIT_STRUCT*)lpParameter; - bFileIsDll = IsFileDLLW(ConvertUtf8ToUtf16(init->exe).c_str(), 0); - pDebuggedEntry = GetPE32DataW(ConvertUtf8ToUtf16(init->exe).c_str(), 0, UE_OEP); + bFileIsDll = IsFileDLLW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0); + pDebuggedEntry = GetPE32DataW(StringUtils::Utf8ToUtf16(init->exe).c_str(), 0, UE_OEP); strcpy_s(szFileName, init->exe); if(bFileIsDll) - fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(ConvertUtf8ToUtf16(init->exe).c_str(), false, ConvertUtf8ToUtf16(init->commandline).c_str(), ConvertUtf8ToUtf16(init->currentfolder).c_str(), 0); + fdProcessInfo = (PROCESS_INFORMATION*)InitDLLDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), false, StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str(), 0); else - fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(ConvertUtf8ToUtf16(init->exe).c_str(), ConvertUtf8ToUtf16(init->commandline).c_str(), ConvertUtf8ToUtf16(init->currentfolder).c_str()); + fdProcessInfo = (PROCESS_INFORMATION*)InitDebugW(StringUtils::Utf8ToUtf16(init->exe).c_str(), StringUtils::Utf8ToUtf16(init->commandline).c_str(), StringUtils::Utf8ToUtf16(init->currentfolder).c_str()); if(!fdProcessInfo) { fdProcessInfo = &g_pi; @@ -1560,7 +1560,7 @@ static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, ch if(lRv != ERROR_SUCCESS) return false; - lRv = RegSetValueExW(hKey, ConvertUtf8ToUtf16(key).c_str(), 0, REG_SZ, (BYTE*)jit_key_value, (DWORD)(*jit_key_vale_size) + 1); + lRv = RegSetValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, REG_SZ, (BYTE*)jit_key_value, (DWORD)(*jit_key_vale_size) + 1); } else { @@ -1572,7 +1572,7 @@ static bool readwritejitkey(wchar_t* jit_key_value, DWORD* jit_key_vale_size, ch return false; } - lRv = RegQueryValueExW(hKey, ConvertUtf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size); + lRv = RegQueryValueExW(hKey, StringUtils::Utf8ToUtf16(key).c_str(), 0, NULL, (LPBYTE)jit_key_value, jit_key_vale_size); if(lRv != ERROR_SUCCESS) { if(error != NULL) @@ -1755,7 +1755,7 @@ bool dbggetjit(char jit_entry[JIT_ENTRY_MAX_SIZE], arch arch_in, arch* arch_out, *rw_error_out = rw_error; return false; } - strcpy_s(jit_entry, JIT_ENTRY_MAX_SIZE, ConvertUtf16ToUtf8(wszJitEntry).c_str()); + strcpy_s(jit_entry, JIT_ENTRY_MAX_SIZE, StringUtils::Utf16ToUtf8(wszJitEntry).c_str()); return true; } @@ -1765,7 +1765,7 @@ bool dbggetdefjit(char* jit_entry) path[0] = '"'; wchar_t wszPath[MAX_PATH] = L""; GetModuleFileNameW(GetModuleHandleW(NULL), wszPath, MAX_PATH); - strcpy(&path[1], ConvertUtf16ToUtf8(wszPath).c_str()); + strcpy(&path[1], StringUtils::Utf16ToUtf8(wszPath).c_str()); strcat(path, ATTACH_CMD_LINE); strcpy(jit_entry, path); return true; @@ -1775,7 +1775,7 @@ bool dbgsetjit(char* jit_cmd, arch arch_in, arch* arch_out, readwritejitkey_erro { DWORD jit_cmd_size = (DWORD)strlen(jit_cmd) * sizeof(wchar_t); readwritejitkey_error_t rw_error; - if(!readwritejitkey((wchar_t*)ConvertUtf8ToUtf16(jit_cmd).c_str(), & jit_cmd_size, "Debugger", arch_in, arch_out, & rw_error, true)) + if(!readwritejitkey((wchar_t*)StringUtils::Utf8ToUtf16(jit_cmd).c_str(), & jit_cmd_size, "Debugger", arch_in, arch_out, & rw_error, true)) { if(rw_error_out != NULL) *rw_error_out = rw_error; @@ -1812,7 +1812,7 @@ bool dbglistprocesses(std::vector* list) continue; wchar_t szExePath[MAX_PATH] = L""; if(GetModuleFileNameExW(hProcess, 0, szExePath, MAX_PATH)) - strcpy_s(pe32.szExeFile, ConvertUtf16ToUtf8(szExePath).c_str()); + strcpy_s(pe32.szExeFile, StringUtils::Utf16ToUtf8(szExePath).c_str()); list->push_back(pe32); } while(Process32Next(hProcessSnap, &pe32)); diff --git a/x64_dbg_dbg/debugger_commands.cpp b/x64_dbg_dbg/debugger_commands.cpp index 256faec06..2dd466d26 100644 --- a/x64_dbg_dbg/debugger_commands.cpp +++ b/x64_dbg_dbg/debugger_commands.cpp @@ -25,7 +25,7 @@ CMDRESULT cbDebugInit(int argc, char* argv[]) dputs("file does not exist!"); return STATUS_ERROR; } - HANDLE hFile = CreateFileW(ConvertUtf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + HANDLE hFile = CreateFileW(StringUtils::Utf8ToUtf16(arg1).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(hFile == INVALID_HANDLE_VALUE) { dputs("could not open file!"); @@ -892,7 +892,7 @@ CMDRESULT cbDebugAttach(int argc, char* argv[]) dprintf("could not get module filename %X!\n", pid); return STATUS_ERROR; } - strcpy_s(szFileName, ConvertUtf16ToUtf8(wszFileName).c_str()); + strcpy_s(szFileName, StringUtils::Utf16ToUtf8(wszFileName).c_str()); CloseHandle(CreateThread(0, 0, threadAttachLoop, (void*)pid, 0, 0)); return STATUS_CONTINUE; } @@ -1358,7 +1358,7 @@ CMDRESULT cbDebugDownloadSymbol(int argc, char* argv[]) return STATUS_ERROR; } char szModulePath[MAX_PATH] = ""; - strcpy_s(szModulePath, ConvertUtf16ToUtf8(wszModulePath).c_str()); + strcpy_s(szModulePath, StringUtils::Utf16ToUtf8(wszModulePath).c_str()); char szOldSearchPath[MAX_PATH] = ""; if(!SymGetSearchPath(fdProcessInfo->hProcess, szOldSearchPath, MAX_PATH)) //backup current search path { diff --git a/x64_dbg_dbg/instruction.cpp b/x64_dbg_dbg/instruction.cpp index 6f8e82f30..7605a4e93 100644 --- a/x64_dbg_dbg/instruction.cpp +++ b/x64_dbg_dbg/instruction.cpp @@ -223,7 +223,7 @@ CMDRESULT cbInstrChd(int argc, char* argv[]) dputs("directory doesn't exist"); return STATUS_ERROR; } - SetCurrentDirectoryW(ConvertUtf8ToUtf16(argv[1]).c_str()); + SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(argv[1]).c_str()); dputs("current directory changed!"); return STATUS_CONTINUE; } diff --git a/x64_dbg_dbg/math.cpp b/x64_dbg_dbg/math.cpp index fe9c671f3..6b28e999f 100644 --- a/x64_dbg_dbg/math.cpp +++ b/x64_dbg_dbg/math.cpp @@ -383,8 +383,8 @@ bool mathfromstring(const char* string, uint* value, bool silent, bool baseonly, memset(strright, 0, len + 1); strncpy(strleft, string - negative, highestop_pos + negative); strcpy(strright, string + highestop_pos + 1); - strcpy(strleft, UString(strleft).Trim().c_str()); - strcpy(strright, UString(strright).Trim().c_str()); + strcpy(strleft, StringUtils::Trim(strleft).c_str()); + strcpy(strright, StringUtils::Trim(strright).c_str()); //dprintf("left: %s, right: %s, op: %c\n", strleft(), strright(), string[highestop_pos]); if(!*strright) return false; diff --git a/x64_dbg_dbg/patches.cpp b/x64_dbg_dbg/patches.cpp index b8ae0d33a..c116b4e78 100644 --- a/x64_dbg_dbg/patches.cpp +++ b/x64_dbg_dbg/patches.cpp @@ -160,7 +160,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha sprintf(error, "failed to get module path of module %s", modname); return -1; } - if(!CopyFileW(szOriginalName, ConvertUtf8ToUtf16(szFileName).c_str(), false)) + if(!CopyFileW(szOriginalName, StringUtils::Utf8ToUtf16(szFileName).c_str(), false)) { if(error) strcpy(error, "failed to make a copy of the original file (patch target is in use?)"); @@ -170,7 +170,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha DWORD LoadedSize; HANDLE FileMap; ULONG_PTR FileMapVA; - if(StaticFileLoadW(ConvertUtf8ToUtf16(szFileName).c_str(), UE_ACCESS_ALL, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) + if(StaticFileLoadW(StringUtils::Utf8ToUtf16(szFileName).c_str(), UE_ACCESS_ALL, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) { int patched = 0; for(int i = 0; i < count; i++) @@ -182,7 +182,7 @@ int patchfile(const PATCHINFO* patchlist, int count, const char* szFileName, cha *ptr = patchlist[i].newbyte; patched++; } - if(!StaticFileUnloadW(ConvertUtf8ToUtf16(szFileName).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA)) + if(!StaticFileUnloadW(StringUtils::Utf8ToUtf16(szFileName).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA)) { if(error) strcpy(error, "StaticFileUnload failed"); diff --git a/x64_dbg_dbg/plugin_loader.cpp b/x64_dbg_dbg/plugin_loader.cpp index 63e81edaa..3e3ad0975 100644 --- a/x64_dbg_dbg/plugin_loader.cpp +++ b/x64_dbg_dbg/plugin_loader.cpp @@ -16,7 +16,7 @@ void pluginload(const char* pluginDir) //load new plugins wchar_t currentDir[deflen] = L""; GetCurrentDirectoryW(deflen, currentDir); - SetCurrentDirectoryW(ConvertUtf8ToUtf16(pluginDir).c_str()); + SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(pluginDir).c_str()); char searchName[deflen] = ""; #ifdef _WIN64 sprintf(searchName, "%s\\*.dp64", pluginDir); @@ -24,7 +24,7 @@ void pluginload(const char* pluginDir) sprintf(searchName, "%s\\*.dp32", pluginDir); #endif // _WIN64 WIN32_FIND_DATAW foundData; - HANDLE hSearch = FindFirstFileW(ConvertUtf8ToUtf16(searchName).c_str(), &foundData); + HANDLE hSearch = FindFirstFileW(StringUtils::Utf8ToUtf16(searchName).c_str(), &foundData); if(hSearch == INVALID_HANDLE_VALUE) { SetCurrentDirectoryW(currentDir); @@ -36,8 +36,8 @@ void pluginload(const char* pluginDir) //set plugin data pluginData.initStruct.pluginHandle = curPluginHandle; char szPluginPath[MAX_PATH] = ""; - sprintf_s(szPluginPath, "%s\\%s", pluginDir, ConvertUtf16ToUtf8(foundData.cFileName).c_str()); - pluginData.hPlugin = LoadLibraryW(ConvertUtf8ToUtf16(szPluginPath).c_str()); //load the plugin library + sprintf_s(szPluginPath, "%s\\%s", pluginDir, StringUtils::Utf16ToUtf8(foundData.cFileName).c_str()); + pluginData.hPlugin = LoadLibraryW(StringUtils::Utf8ToUtf16(szPluginPath).c_str()); //load the plugin library if(!pluginData.hPlugin) { dprintf("[PLUGIN] Failed to load plugin: %s\n", foundData.cFileName); diff --git a/x64_dbg_dbg/simplescript.cpp b/x64_dbg_dbg/simplescript.cpp index 52df159f1..a722a2773 100644 --- a/x64_dbg_dbg/simplescript.cpp +++ b/x64_dbg_dbg/simplescript.cpp @@ -62,7 +62,7 @@ static int scriptinternalstep(int fromIp) //internal step routine static bool scriptcreatelinemap(const char* filename) { - HANDLE hFile = CreateFileW(ConvertUtf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); + HANDLE hFile = CreateFileW(StringUtils::Utf8ToUtf16(filename).c_str(), GENERIC_READ, FILE_SHARE_READ, 0, OPEN_EXISTING, 0, 0); if(hFile == INVALID_HANDLE_VALUE) { GuiScriptError(0, "CreateFile failed..."); diff --git a/x64_dbg_dbg/stringutils.cpp b/x64_dbg_dbg/stringutils.cpp new file mode 100644 index 000000000..6d101370c --- /dev/null +++ b/x64_dbg_dbg/stringutils.cpp @@ -0,0 +1,81 @@ +#include "stringutils.h" +#include +#include +#include + +std::vector StringUtils::Split(const String & s, char delim, std::vector & elems) +{ + std::stringstream ss(s); + String item; + while(std::getline(ss, item, delim)) + { + if(!item.length()) + continue; + elems.push_back(item); + } + return elems; +} + +std::vector StringUtils::Split(const String & s, char delim) +{ + std::vector elems; + Split(s, delim, elems); + return elems; +} + +//Trim functions taken from: http://stackoverflow.com/questions/216823/whats-the-best-way-to-trim-stdstring/16743707#16743707 +const String StringUtils::WHITESPACE = " \n\r\t"; + +String StringUtils::Trim(const String & s) +{ + return TrimRight(TrimLeft(s)); +} + +String StringUtils::TrimLeft(const String & s) +{ + size_t startpos = s.find_first_not_of(StringUtils::WHITESPACE); + return (startpos == String::npos) ? "" : s.substr(startpos); +} + +String StringUtils::TrimRight(const String & s) +{ + size_t endpos = s.find_last_not_of(StringUtils::WHITESPACE); + return (endpos == String::npos) ? "" : s.substr(0, endpos + 1); +} + +//Conversion functions taken from: http://www.nubaria.com/en/blog/?p=289 +String StringUtils::Utf16ToUtf8(const WString & wstr) +{ + String convertedString; + int requiredSize = WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, 0, 0, 0, 0); + if(requiredSize > 0) + { + std::vector buffer(requiredSize); + WideCharToMultiByte(CP_UTF8, 0, wstr.c_str(), -1, &buffer[0], requiredSize, 0, 0); + convertedString.assign(buffer.begin(), buffer.end() - 1); + } + return convertedString; +} + +String StringUtils::Utf16ToUtf8(const wchar_t* wstr) +{ + return Utf16ToUtf8(wstr ? WString(wstr) : WString()); +} + +WString StringUtils::Utf8ToUtf16(const String & str) +{ + WString convertedString; + int requiredSize = MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, 0, 0); + if(requiredSize > 0) + { + std::vector buffer(requiredSize); + MultiByteToWideChar(CP_UTF8, 0, str.c_str(), -1, &buffer[0], requiredSize); + convertedString.assign(buffer.begin(), buffer.end() - 1); + } + return convertedString; +} + +WString StringUtils::Utf8ToUtf16(const char* str) +{ + return Utf8ToUtf16(str ? String(str) : String()); +} \ No newline at end of file diff --git a/x64_dbg_dbg/stringutils.h b/x64_dbg_dbg/stringutils.h new file mode 100644 index 000000000..48a41bae5 --- /dev/null +++ b/x64_dbg_dbg/stringutils.h @@ -0,0 +1,27 @@ +#ifndef _STRINGUTILS_H +#define _STRINGUTILS_H + +#include +#include + +typedef std::string String; +typedef std::wstring WString; + +class StringUtils +{ +public: + static std::vector Split(const String & s, char delim, std::vector & elems); + static std::vector Split(const String & s, char delim); + static String Trim(const String & s); + static String TrimLeft(const String & s); + static String TrimRight(const String & s); + static String Utf16ToUtf8(const WString & wstr); + static String Utf16ToUtf8(const wchar_t* wstr); + static WString Utf8ToUtf16(const String & str); + static WString Utf8ToUtf16(const char* str); + +private: + static const String WHITESPACE; +}; + +#endif //_STRINGUTILS_H \ No newline at end of file diff --git a/x64_dbg_dbg/symbolinfo.cpp b/x64_dbg_dbg/symbolinfo.cpp index 256c81bf2..a06b73efb 100644 --- a/x64_dbg_dbg/symbolinfo.cpp +++ b/x64_dbg_dbg/symbolinfo.cpp @@ -112,7 +112,7 @@ void symdownloadallsymbols(const char* szSymbolStore) dprintf("SymUnloadModule64("fhex") failed!\n", modbase); continue; } - if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, ConvertUtf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0)) + if(!SymLoadModuleEx(fdProcessInfo->hProcess, 0, StringUtils::Utf16ToUtf8(szModulePath).c_str(), 0, (DWORD64)modbase, 0, 0, 0)) { dprintf("SymLoadModuleEx("fhex") failed!\n", modbase); continue; diff --git a/x64_dbg_dbg/variable.cpp b/x64_dbg_dbg/variable.cpp index f93e707ac..296b4d3a9 100644 --- a/x64_dbg_dbg/variable.cpp +++ b/x64_dbg_dbg/variable.cpp @@ -19,7 +19,7 @@ static void varsetvalue(VAR* var, VAR_VALUE* value) static bool varset(const char* name, VAR_VALUE* value, bool setreadonly) { - std::string name_; + String name_; if(*name != '$') name_ = "$"; name_ += name; @@ -64,38 +64,15 @@ VAR* vargetptr() return 0; } -#include -#include - -std::vector & split(const std::string & s, char delim, std::vector & elems) -{ - std::stringstream ss(s); - std::string item; - while(std::getline(ss, item, delim)) - { - if(!item.length()) - continue; - elems.push_back(item); - } - return elems; -} - -std::vector split(const std::string & s, char delim) -{ - std::vector elems; - split(s, delim, elems); - return elems; -} - bool varnew(const char* name, uint value, VAR_TYPE type) { if(!name) return false; - std::vector names = split(name, '\1'); - std::string firstName; + std::vector names = StringUtils::Split(name, '\1'); + String firstName; for(int i = 0; i < (int)names.size(); i++) { - std::string name_; + String name_; name = names.at(i).c_str(); if(*name != '$') name_ = "$"; @@ -119,7 +96,7 @@ bool varnew(const char* name, uint value, VAR_TYPE type) static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type) { - std::string name_; + String name_; if(*name != '$') name_ = "$"; name_ += name; @@ -202,7 +179,7 @@ bool varset(const char* name, const char* string, bool setreadonly) bool vardel(const char* name, bool delsystem) { - std::string name_; + String name_; if(*name != '$') name_ = "$"; name_ += name; @@ -218,7 +195,7 @@ bool vardel(const char* name, bool delsystem) { VariableMap::iterator del = found; found++; - if(found->second.name == std::string(name)) + if(found->second.name == String(name)) variables.erase(del); } return true; @@ -226,7 +203,7 @@ bool vardel(const char* name, bool delsystem) bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype) { - std::string name_; + String name_; if(*name != '$') name_ = "$"; name_ += name; diff --git a/x64_dbg_dbg/variable.h b/x64_dbg_dbg/variable.h index 2bd3f85cf..30a637a06 100644 --- a/x64_dbg_dbg/variable.h +++ b/x64_dbg_dbg/variable.h @@ -32,21 +32,21 @@ struct VAR_VALUE struct VAR { - std::string name; - std::string alias; + String name; + String alias; VAR_TYPE type; VAR_VALUE value; }; struct CaseInsensitiveCompare { - bool operator()(const std::string & str1, const std::string & str2) const + bool operator()(const String & str1, const String & str2) const { return _stricmp(str1.c_str(), str2.c_str()) < 0; } }; -typedef std::map VariableMap; +typedef std::map VariableMap; //functions void varinit(); diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 513560b40..9913f4d9d 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -235,21 +235,21 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit() if(!GetModuleFileNameW(hInst, wszDir, deflen)) return "GetModuleFileNameW failed!"; char dir[deflen] = ""; - strcpy_s(dir, ConvertUtf16ToUtf8(wszDir).c_str()); + strcpy_s(dir, StringUtils::Utf16ToUtf8(wszDir).c_str()); int len = (int)strlen(dir); while(dir[len] != '\\') len--; dir[len] = 0; strcpy(alloctrace, dir); PathAppendA(alloctrace, "\\alloctrace.txt"); - DeleteFileW(ConvertUtf8ToUtf16(alloctrace).c_str()); + DeleteFileW(StringUtils::Utf8ToUtf16(alloctrace).c_str()); setalloctrace(alloctrace); strcpy(dbbasepath, dir); //debug directory PathAppendA(dbbasepath, "db"); - CreateDirectoryW(ConvertUtf8ToUtf16(dbbasepath).c_str(), 0); //create database directory + CreateDirectoryW(StringUtils::Utf8ToUtf16(dbbasepath).c_str(), 0); //create database directory strcpy(szSymbolCachePath, dir); PathAppendA(szSymbolCachePath, "symbols"); - SetCurrentDirectoryW(ConvertUtf8ToUtf16(dir).c_str());; + SetCurrentDirectoryW(StringUtils::Utf8ToUtf16(dir).c_str());; gMsgStack = msgallocstack(); if(!gMsgStack) return "Could not allocate message stack!"; @@ -259,15 +259,15 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit() char plugindir[deflen] = ""; strcpy(plugindir, dir); PathAppendA(plugindir, "plugins"); - CreateDirectoryW(ConvertUtf8ToUtf16(plugindir).c_str(), 0); + CreateDirectoryW(StringUtils::Utf8ToUtf16(plugindir).c_str(), 0); pluginload(plugindir); //handle command line int argc = 0; wchar_t** argv = CommandLineToArgvW(GetCommandLineW(), &argc); if(argc == 2) //we have an argument { - UString str = "init \""; - str += ConvertUtf16ToUtf8(argv[1]); + String str = "init \""; + str += StringUtils::Utf16ToUtf8(argv[1]); str += "\""; DbgCmdExec(str.c_str()); } @@ -275,10 +275,10 @@ extern "C" DLL_EXPORT const char* _dbg_dbginit() { if(_wcsicmp(argv[1], L"-a") == 0 && !_wcsicmp(argv[3], L"-e")) { - UString str = "attach ."; - str += ConvertUtf16ToUtf8(argv[2]); + String str = "attach ."; + str += StringUtils::Utf16ToUtf8(argv[2]); str += ", ."; - str += ConvertUtf16ToUtf8(argv[4]); + str += StringUtils::Utf16ToUtf8(argv[4]); DbgCmdExec(str.c_str()); } } diff --git a/x64_dbg_dbg/x64_dbg_dbg.vcxproj b/x64_dbg_dbg/x64_dbg_dbg.vcxproj index 535b793e4..6b11c7c9b 100644 --- a/x64_dbg_dbg/x64_dbg_dbg.vcxproj +++ b/x64_dbg_dbg/x64_dbg_dbg.vcxproj @@ -33,12 +33,10 @@ + - - - @@ -82,14 +80,12 @@ + - - - diff --git a/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters b/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters index 090009caa..0c76fbf65 100644 --- a/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters +++ b/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters @@ -13,9 +13,6 @@ {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav - - {ee24febc-948e-4226-ba0e-68a9b449fb23} - {44fd9eb7-2017-49b8-8d9a-dec680632343} @@ -40,9 +37,6 @@ {23226861-3b20-42db-8dd6-c5d276ba7a83} - - {adf51b13-6f3b-4b04-9ba9-21fb7a38150d} - {6b85ff77-8866-4618-9d46-006d8c349f8f} @@ -81,15 +75,6 @@ Source Files - - Source Files\UString - - - Source Files\UString - - - Source Files\UString - Source Files\Interfaces/Exports @@ -180,6 +165,9 @@ Source Files + + Source Files\Utilities + @@ -224,15 +212,6 @@ Header Files\Third Party\lz4 - - Header Files\Third Party\UString - - - Header Files\Third Party\UString - - - Header Files\Third Party\UString - Header Files\Core @@ -335,5 +314,8 @@ Header Files\Debugger Core + + Header Files\Utilities + \ No newline at end of file From 4f7fe7b875bf31cf431fa12929141cd622cc7952 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Sat, 15 Nov 2014 15:01:38 +0100 Subject: [PATCH 47/58] DBG: added TitanEngine MinGW libraries again --- x64_dbg_dbg/TitanEngine/TitanEngine_x64.a | Bin 0 -> 333898 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.a | Bin 0 -> 332980 bytes 2 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x64.a create mode 100644 x64_dbg_dbg/TitanEngine/TitanEngine_x86.a diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a new file mode 100644 index 0000000000000000000000000000000000000000..372e2539a3ee5aa563b62cbd59e6755490d7ca82 GIT binary patch literal 333898 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 IU3bp^4{;s9KmY&$ literal 0 HcmV?d00001 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a new file mode 100644 index 0000000000000000000000000000000000000000..a29b07052e2d15091ddfbc1d1639bcfbdbae53e3 GIT binary patch literal 332980 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 literal 0 HcmV?d00001 From b150763bfb8d1a1397d5e893f963e869c01d0c0a Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Wed, 19 Nov 2014 11:04:01 +0100 Subject: [PATCH 48/58] modified license (clearer text, no actual change of license) --- LICENSE | 1368 ++++++++++++++++++++++++++++--------------------------- 1 file changed, 685 insertions(+), 683 deletions(-) diff --git a/LICENSE b/LICENSE index 6a0e232fd..bb49e61c5 100644 --- a/LICENSE +++ b/LICENSE @@ -1,683 +1,685 @@ - GNU GENERAL PUBLIC LICENSE - Version 3, 29 June 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU General Public License is a free, copyleft license for -software and other kinds of works. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -the GNU General Public License is intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. We, the Free Software Foundation, use the -GNU General Public License for most of our software; it applies also to -any other work released this way by its authors. You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - To protect your rights, we need to prevent others from denying you -these rights or asking you to surrender the rights. Therefore, you have -certain responsibilities if you distribute copies of the software, or if -you modify it: responsibilities to respect the freedom of others. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must pass on to the recipients the same -freedoms that you received. You must make sure that they, too, receive -or can get the source code. And you must show them these terms so they -know their rights. - - Developers that use the GNU GPL protect your rights with two steps: -(1) assert copyright on the software, and (2) offer you this License -giving you legal permission to copy, distribute and/or modify it. - - For the developers' and authors' protection, the GPL clearly explains -that there is no warranty for this free software. For both users' and -authors' sake, the GPL requires that modified versions be marked as -changed, so that their problems will not be attributed erroneously to -authors of previous versions. - - Some devices are designed to deny users access to install or run -modified versions of the software inside them, although the manufacturer -can do so. This is fundamentally incompatible with the aim of -protecting users' freedom to change the software. The systematic -pattern of such abuse occurs in the area of products for individuals to -use, which is precisely where it is most unacceptable. Therefore, we -have designed this version of the GPL to prohibit the practice for those -products. If such problems arise substantially in other domains, we -stand ready to extend this provision to those domains in future versions -of the GPL, as needed to protect the freedom of users. - - Finally, every program is threatened constantly by software patents. -States should not allow patents to restrict development and use of -software on general-purpose computers, but in those that do, we wish to -avoid the special danger that patents applied to a free program could -make it effectively proprietary. To prevent this, the GPL assures that -patents cannot be used to render the program non-free. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Treatment of plugins - - This license does not affect plugins, i.e., dynamically linked -libraries, that use the provided plugin interface mechanism of x64_dbg -for contibuting additional features to the x64_dbg project and can only -be run from x64dbg. In fact you are allowed to create and share -(non-)commercial, non-standalone closed-source plugins for x64dbg without -distributing the source of the specific plugin. - - 3. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 4. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 5. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 6. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 7. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 8. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 9. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 10. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 11. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 12. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 13. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 14. Use with the GNU Affero General Public License. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU Affero General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the special requirements of the GNU Affero General Public License, -section 13, concerning interaction through a network will apply to the -combination as such. - - 15. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 16. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 17. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 18. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If the program does terminal interaction, make it output a short -notice like this when it starts in an interactive mode: - - Copyright (C) - This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, your program's commands -might be different; for a GUI interface, you would use an "about box". - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU GPL, see -. - - The GNU General Public License does not permit incorporating your program -into proprietary programs. If your program is a subroutine library, you -may consider it more useful to permit linking proprietary applications with -the library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. But first, please read -. + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + THIS DOCUMENT HAS BEEN MODIFIED + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Treatment of plugins + + This license does not affect plugins, i.e., dynamically linked +libraries, that use the provided plugin interface mechanism of x64_dbg +for contibuting additional features to the x64_dbg project and can only +be run from x64dbg. In fact you are allowed to create and share +(non-)commercial, non-standalone closed-source plugins for x64dbg under +your own license. + + 3. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 4. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 5. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 6. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 7. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 8. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 9. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 10. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 11. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 12. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 13. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 14. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 15. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + + Each version is given a distinguishing version number. If the +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 16. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 17. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 18. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. From 22fd1207fa079485a0a50b7cfb5f8a9554193ac8 Mon Sep 17 00:00:00 2001 From: SmilingWolf Date: Mon, 1 Dec 2014 20:30:08 +0100 Subject: [PATCH 49/58] Add "Reload Script" option --- x64_dbg_gui/Project/Src/Gui/ScriptView.cpp | 17 ++++++++++++++++- x64_dbg_gui/Project/Src/Gui/ScriptView.h | 3 +++ x64_dbg_gui/Project/Src/Utils/Configuration.cpp | 1 + 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/x64_dbg_gui/Project/Src/Gui/ScriptView.cpp b/x64_dbg_gui/Project/Src/Gui/ScriptView.cpp index 1cdb0b118..19cb1423e 100644 --- a/x64_dbg_gui/Project/Src/Gui/ScriptView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/ScriptView.cpp @@ -281,6 +281,7 @@ void ScriptView::contextMenuSlot(const QPoint & pos) wMenu->addMenu(mLoadMenu); if(getRowCount()) { + wMenu->addAction(mScriptReload); wMenu->addAction(mScriptUnload); wMenu->addSeparator(); wMenu->addAction(mScriptBpToggle); @@ -350,6 +351,11 @@ void ScriptView::setupContextMenu() connect(mScriptLoad, SIGNAL(triggered()), this, SLOT(openFile())); mLoadMenu->addAction(mScriptLoad); + mScriptReload = new QAction("Reload Script", this); + mScriptReload->setShortcutContext(Qt::WidgetShortcut); + this->addAction(mScriptReload); + connect(mScriptReload, SIGNAL(triggered()), this, SLOT(reload())); + mScriptUnload = new QAction("Unload Script", this); mScriptUnload->setShortcutContext(Qt::WidgetShortcut); this->addAction(mScriptUnload); @@ -397,6 +403,7 @@ void ScriptView::setupContextMenu() void ScriptView::refreshShortcutsSlot() { mScriptLoad->setShortcut(ConfigShortcut("ActionLoadScript")); + mScriptReload->setShortcut(ConfigShortcut("ActionReloadScript")); mScriptUnload->setShortcut(ConfigShortcut("ActionUnloadScript")); mScriptRun->setShortcut(ConfigShortcut("ActionRunScript")); mScriptBpToggle->setShortcut(ConfigShortcut("ActionToggleBreakpointScript")); @@ -498,7 +505,7 @@ void ScriptView::setInfoLine(int line, QString info) void ScriptView::openFile() { - QString filename = QFileDialog::getOpenFileName(this, tr("Select script"), 0, tr("Script files (*.txt *.scr);;All files (*.*)")); + filename = QFileDialog::getOpenFileName(this, tr("Select script"), 0, tr("Script files (*.txt *.scr);;All files (*.*)")); if(!filename.length()) return; filename = QDir::toNativeSeparators(filename); //convert to native path format (with backlashes) @@ -506,6 +513,14 @@ void ScriptView::openFile() DbgScriptLoad(filename.toUtf8().constData()); } +void ScriptView::reload() +{ + if(!filename.length()) + return; + DbgScriptUnload(); + DbgScriptLoad(filename.toUtf8().constData()); +} + void ScriptView::unload() { DbgScriptUnload(); diff --git a/x64_dbg_gui/Project/Src/Gui/ScriptView.h b/x64_dbg_gui/Project/Src/Gui/ScriptView.h index 6615dfa31..d69d41173 100644 --- a/x64_dbg_gui/Project/Src/Gui/ScriptView.h +++ b/x64_dbg_gui/Project/Src/Gui/ScriptView.h @@ -25,6 +25,7 @@ public slots: void setTitle(QString title); void setInfoLine(int line, QString info); void openFile(); + void reload(); void unload(); void run(); void bpToggle(); @@ -46,9 +47,11 @@ private: //private variables int mIpLine; bool mEnableSyntaxHighlighting; + QString filename; QMenu* mLoadMenu; QAction* mScriptLoad; + QAction* mScriptReload; QAction* mScriptUnload; QAction* mScriptRun; QAction* mScriptRunCursor; diff --git a/x64_dbg_gui/Project/Src/Utils/Configuration.cpp b/x64_dbg_gui/Project/Src/Utils/Configuration.cpp index 28b1bc1a0..a35eb4bfd 100644 --- a/x64_dbg_gui/Project/Src/Utils/Configuration.cpp +++ b/x64_dbg_gui/Project/Src/Utils/Configuration.cpp @@ -253,6 +253,7 @@ Configuration::Configuration() : QObject() defaultShortcuts.insert("ActionCopy", Shortcut(tr("Actions -> Copy"), "Ctrl+C")); defaultShortcuts.insert("ActionCopySymbol", Shortcut(tr("Actions -> Copy Symbol"), "Ctrl+S")); defaultShortcuts.insert("ActionLoadScript", Shortcut(tr("Actions -> Load Script"), "Ctrl+O")); + defaultShortcuts.insert("ActionReloadScript", Shortcut(tr("Actions -> Reload Script"), "Ctrl+R")); defaultShortcuts.insert("ActionUnloadScript", Shortcut(tr("Actions -> Unload Script"), "Ctrl+U")); defaultShortcuts.insert("ActionRunScript", Shortcut(tr("Actions -> Run Script"), "Space")); defaultShortcuts.insert("ActionToggleBreakpointScript", Shortcut(tr("Actions -> Toggle Script Breakpoint"), "F2")); From 5db90c939f633f6e158944dd6ed8c60f3824afb6 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 1 Dec 2014 00:58:44 +0100 Subject: [PATCH 50/58] DBG: updated TitanEngine --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index 74ddb9951..a67881bee 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -10,6 +10,14 @@ #include #include +#ifdef __GNUC__ +typedef struct DECLSPEC_ALIGN(16) _M128A +{ + ULONGLONG Low; + LONGLONG High; +} M128A, *PM128A; +#endif //__GNUC__ + #pragma pack(push, 1) // Global.Constant.Structure.Declaration: From 1de5fb533f33779d533cfbf452ab9c43e7230e05 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Wed, 3 Dec 2014 10:48:14 +0100 Subject: [PATCH 51/58] DBG: added fileoffset<->va exports --- x64_dbg_dbg/_dbgfunctions.cpp | 44 ++++++++++++++++++++++++++++++++++- x64_dbg_dbg/_dbgfunctions.h | 4 ++++ 2 files changed, 47 insertions(+), 1 deletion(-) diff --git a/x64_dbg_dbg/_dbgfunctions.cpp b/x64_dbg_dbg/_dbgfunctions.cpp index 65e0eecb0..9b57420c6 100644 --- a/x64_dbg_dbg/_dbgfunctions.cpp +++ b/x64_dbg_dbg/_dbgfunctions.cpp @@ -95,7 +95,7 @@ static bool _patchrestore(duint addr) static int _modpathfromaddr(duint addr, char* path, int size) { Memory wszModPath(size * sizeof(wchar_t), "_modpathfromaddr:wszModPath"); - if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)addr, wszModPath, size)) + if(!GetModuleFileNameExW(fdProcessInfo->hProcess, (HMODULE)modbasefromaddr(addr), wszModPath, size)) { *path = '\0'; return 0; @@ -181,6 +181,46 @@ static void _memupdatemap() memupdatemap(fdProcessInfo->hProcess); } +static duint _fileoffsettova(const char* modname, duint offset) +{ + char modpath[MAX_PATH] = ""; + if(DbgFunctions()->ModPathFromName(modname, modpath, MAX_PATH)) + { + HANDLE FileHandle; + DWORD LoadedSize; + HANDLE FileMap; + ULONG_PTR FileMapVA; + if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) + { + ULONGLONG rva = ConvertFileOffsetToVA(FileMapVA, //FileMapVA + FileMapVA + (ULONG_PTR)offset, //Offset inside FileMapVA + false); //Return without ImageBase + StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); + return offset < LoadedSize ? rva + modbasefromname(modname) : 0; + } + } + return 0; +} + +static duint _vatofileoffset(duint va) +{ + char modpath[MAX_PATH] = ""; + if(DbgFunctions()->ModPathFromAddr(va, modpath, MAX_PATH)) + { + HANDLE FileHandle; + DWORD LoadedSize; + HANDLE FileMap; + ULONG_PTR FileMapVA; + if(StaticFileLoadW(StringUtils::Utf8ToUtf16(modpath).c_str(), UE_ACCESS_READ, false, &FileHandle, &LoadedSize, &FileMap, &FileMapVA)) + { + ULONGLONG offset = ConvertVAtoFileOffsetEx(FileMapVA, LoadedSize, 0, va - modbasefromaddr(va), true, false); + StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); + return offset; + } + } + return 0; +} + void dbgfunctionsinit() { _dbgfunctions.AssembleAtEx = _assembleatex; @@ -213,4 +253,6 @@ void dbgfunctionsinit() _dbgfunctions.IsProcessElevated = IsProcessElevated; _dbgfunctions.GetCmdline = _getcmdline; _dbgfunctions.SetCmdline = _setcmdline; + _dbgfunctions.FileOffsetToVa = _fileoffsettova; + _dbgfunctions.VaToFileOffset = _vatofileoffset; } diff --git a/x64_dbg_dbg/_dbgfunctions.h b/x64_dbg_dbg/_dbgfunctions.h index c41f3dc2e..084604477 100644 --- a/x64_dbg_dbg/_dbgfunctions.h +++ b/x64_dbg_dbg/_dbgfunctions.h @@ -63,6 +63,8 @@ typedef bool (*PAGERIGHTSTOSTRING)(DWORD protect, char* rights); typedef bool (*ISPROCESSELEVATED)(); typedef bool (*GETCMDLINE)(char* cmdline, size_t* cbsize); typedef bool (*SETCMDLINE)(const char* cmdline); +typedef duint (*FILEOFFSETTOVA)(const char* modname, duint offset); +typedef duint (*VATOFILEOFFSET)(duint va); typedef struct DBGFUNCTIONS_ { @@ -96,6 +98,8 @@ typedef struct DBGFUNCTIONS_ ISPROCESSELEVATED IsProcessElevated; GETCMDLINE GetCmdline; SETCMDLINE SetCmdline; + FILEOFFSETTOVA FileOffsetToVa; + VATOFILEOFFSET VaToFileOffset; } DBGFUNCTIONS; #ifdef BUILD_DBG From 7353c57278b4715e4ce303a88d8d5f8e59e356ee Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Wed, 3 Dec 2014 10:48:32 +0100 Subject: [PATCH 52/58] GUI: added Goto -> File offset --- .../Project/Src/Gui/CPUDisassembly.cpp | 28 +++++++++++++++++++ x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h | 2 ++ x64_dbg_gui/Project/Src/Gui/CPUDump.cpp | 26 +++++++++++++++++ x64_dbg_gui/Project/Src/Gui/CPUDump.h | 2 ++ x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp | 19 +++++++++++++ x64_dbg_gui/Project/Src/Gui/GotoDialog.h | 2 ++ 6 files changed, 79 insertions(+) diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp index d8e08ba32..f9caea27a 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.cpp @@ -262,6 +262,9 @@ void CPUDisassembly::contextMenuEvent(QContextMenuEvent* event) if(historyHasNext()) mGotoMenu->addAction(mGotoNext); mGotoMenu->addAction(mGotoExpression); + char modname[MAX_MODULE_SIZE] = ""; + if(DbgGetModuleAt(wVA, modname)) + mGotoMenu->addAction(mGotoFileOffset); wMenu->addMenu(mGotoMenu); wMenu->addSeparator(); @@ -436,6 +439,10 @@ void CPUDisassembly::setupRightClickContextMenu() this->addAction(mGotoExpression); connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpression())); + // File offset action + mGotoFileOffset = new QAction("File Offset", this); + connect(mGotoFileOffset, SIGNAL(triggered()), this, SLOT(gotoFileOffset())); + //-------------------- Follow in Dump ---------------------------- // Menu mFollowMenu = new QMenu("&Follow in Dump", this); @@ -889,6 +896,27 @@ void CPUDisassembly::gotoExpression() } } +void CPUDisassembly::gotoFileOffset() +{ + if(!DbgIsDebugging()) + return; + char modname[MAX_MODULE_SIZE] = ""; + if(!DbgFunctions()->ModNameFromAddr(rvaToVa(getInitialSelection()), modname, true)) + { + QMessageBox::critical(this, "Error!", "Not inside a module..."); + return; + } + GotoDialog mGotoDialog(this); + mGotoDialog.fileOffset = true; + mGotoDialog.modName = QString(modname); + mGotoDialog.setWindowTitle("Goto File Offset in " + QString(modname)); + if(mGotoDialog.exec() != QDialog::Accepted) + return; + uint_t value = DbgValFromString(mGotoDialog.expressionText.toUtf8().constData()); + value = DbgFunctions()->FileOffsetToVa(modname, value); + DbgCmdExec(QString().sprintf("disasm \"%p\"", value).toUtf8().constData()); +} + void CPUDisassembly::followActionSlot() { QAction* action = qobject_cast(sender()); diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h index 88cfe5e23..f29e486ef 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUDisassembly.h @@ -43,6 +43,7 @@ public slots: void toggleFunction(); void assembleAt(); void gotoExpression(); + void gotoFileOffset(); void followActionSlot(); void gotoPrevious(); void gotoNext(); @@ -102,6 +103,7 @@ private: QAction* msetHwBPOnSlot2Action; QAction* msetHwBPOnSlot3Action; QAction* mGotoExpression; + QAction* mGotoFileOffset; QAction* mGotoPrevious; QAction* mGotoNext; QAction* mReferenceSelectedAddress; diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp index 7fc916d53..670217659 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.cpp @@ -246,6 +246,11 @@ void CPUDump::setupContextMenu() connect(mGotoExpression, SIGNAL(triggered()), this, SLOT(gotoExpressionSlot())); mGotoMenu->addAction(mGotoExpression); + // Goto->File offset + mGotoFileOffset = new QAction("File Offset", this); + connect(mGotoFileOffset, SIGNAL(triggered()), this, SLOT(gotoFileOffsetSlot())); + mGotoMenu->addAction(mGotoFileOffset); + //Hex menu mHexMenu = new QMenu("&Hex", this); //Hex->Ascii @@ -559,6 +564,27 @@ void CPUDump::gotoExpressionSlot() } } +void CPUDump::gotoFileOffsetSlot() +{ + if(!DbgIsDebugging()) + return; + char modname[MAX_MODULE_SIZE] = ""; + if(!DbgFunctions()->ModNameFromAddr(rvaToVa(getInitialSelection()), modname, true)) + { + QMessageBox::critical(this, "Error!", "Not inside a module..."); + return; + } + GotoDialog mGotoDialog(this); + mGotoDialog.fileOffset = true; + mGotoDialog.modName = QString(modname); + mGotoDialog.setWindowTitle("Goto File Offset in " + QString(modname)); + if(mGotoDialog.exec() != QDialog::Accepted) + return; + uint_t value = DbgValFromString(mGotoDialog.expressionText.toUtf8().constData()); + value = DbgFunctions()->FileOffsetToVa(modname, value); + DbgCmdExec(QString().sprintf("dump \"%p\"", value).toUtf8().constData()); +} + void CPUDump::hexAsciiSlot() { Config()->setUint("HexDump", "DefaultView", (uint_t)ViewHexAscii); diff --git a/x64_dbg_gui/Project/Src/Gui/CPUDump.h b/x64_dbg_gui/Project/Src/Gui/CPUDump.h index 8eeb0d70e..4c315d954 100644 --- a/x64_dbg_gui/Project/Src/Gui/CPUDump.h +++ b/x64_dbg_gui/Project/Src/Gui/CPUDump.h @@ -39,6 +39,7 @@ public slots: void setLabelSlot(); void gotoExpressionSlot(); + void gotoFileOffsetSlot(); void hexAsciiSlot(); void hexUnicodeSlot(); @@ -110,6 +111,7 @@ private: QMenu* mGotoMenu; QAction* mGotoExpression; + QAction* mGotoFileOffset; QMenu* mHexMenu; QAction* mHexAsciiAction; diff --git a/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp b/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp index 57181ef8d..152f8b83a 100644 --- a/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp +++ b/x64_dbg_gui/Project/Src/Gui/GotoDialog.cpp @@ -19,6 +19,7 @@ GotoDialog::GotoDialog(QWidget* parent) : QDialog(parent), ui(new Ui::GotoDialog ui->editExpression->setFocus(); validRangeStart = 0; validRangeEnd = 0; + fileOffset = false; mValidateThread = new GotoDialogValidateThread(this); connect(this, SIGNAL(finished(int)), this, SLOT(finishedSlot(int))); } @@ -57,6 +58,24 @@ void GotoDialog::validateExpression() ui->buttonOk->setEnabled(false); expressionText.clear(); } + else if(fileOffset) + { + uint_t offset = DbgValFromString(expression.toUtf8().constData()); + uint_t va = DbgFunctions()->FileOffsetToVa(modName.toUtf8().constData(), offset); + if(va) + { + QString addrText = QString("%1").arg(va, sizeof(int_t) * 2, 16, QChar('0')).toUpper(); + ui->labelError->setText(QString("Correct expression! -> " + addrText)); + ui->buttonOk->setEnabled(true); + expressionText = expression; + } + else + { + ui->labelError->setText("Invalid file offset..."); + ui->buttonOk->setEnabled(false); + expressionText.clear(); + } + } else { uint_t addr = DbgValFromString(expression.toUtf8().constData()); diff --git a/x64_dbg_gui/Project/Src/Gui/GotoDialog.h b/x64_dbg_gui/Project/Src/Gui/GotoDialog.h index 83974c910..8362d13a6 100644 --- a/x64_dbg_gui/Project/Src/Gui/GotoDialog.h +++ b/x64_dbg_gui/Project/Src/Gui/GotoDialog.h @@ -20,6 +20,8 @@ public: QString expressionText; uint_t validRangeStart; uint_t validRangeEnd; + bool fileOffset; + QString modName; void showEvent(QShowEvent* event); void hideEvent(QHideEvent* event); void validateExpression(); From 8afd1d4bf423d187e938b142763806ffcdbb6aaf Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 8 Dec 2014 15:22:51 +0100 Subject: [PATCH 53/58] DBG: added struct alignment check for TitanEngine + updated TitanEngine --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 133 ++++++++++---------- x64_dbg_dbg/TitanEngine/TitanEngine_x64.a | Bin 333898 -> 331742 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib | Bin 102566 -> 101472 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.a | Bin 332980 -> 330868 bytes x64_dbg_dbg/TitanEngine/TitanEngine_x86.lib | Bin 106306 -> 105246 bytes x64_dbg_dbg/x64_dbg.cpp | 2 + 6 files changed, 70 insertions(+), 65 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index a67881bee..18bc25208 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -35,6 +35,9 @@ typedef struct DECLSPEC_ALIGN(16) _M128A #define UE_STRUCT_HOOK_ENTRY 11 #define UE_STRUCT_FILE_STATUS_INFO 12 #define UE_STRUCT_FILE_FIX_INFO 13 +#define UE_STRUCT_X87FPUREGISTER 14 +#define UE_STRUCT_X87FPU 15 +#define UE_STRUCT_TITAN_ENGINE_CONTEXT 16 #define UE_ACCESS_READ 0 #define UE_ACCESS_WRITE 1 @@ -326,71 +329,6 @@ typedef struct DECLSPEC_ALIGN(16) _M128A #define CONTEXT_EXTENDED_REGISTERS 0 #endif -typedef struct -{ - BYTE data[10]; - int st_value; - int tag; -} x87FPURegister_t; - -typedef struct -{ - WORD ControlWord; - WORD StatusWord; - WORD TagWord; - DWORD ErrorOffset; - DWORD ErrorSelector; - DWORD DataOffset; - DWORD DataSelector; - DWORD Cr0NpxState; -} x87FPU_t; - -typedef struct -{ - ULONG_PTR cax; - ULONG_PTR ccx; - ULONG_PTR cdx; - ULONG_PTR cbx; - ULONG_PTR csp; - ULONG_PTR cbp; - ULONG_PTR csi; - ULONG_PTR cdi; -#ifdef _WIN64 - ULONG_PTR r8; - ULONG_PTR r9; - ULONG_PTR r10; - ULONG_PTR r11; - ULONG_PTR r12; - ULONG_PTR r13; - ULONG_PTR r14; - ULONG_PTR r15; -#endif //_WIN64 - ULONG_PTR cip; - ULONG_PTR eflags; - unsigned short gs; - unsigned short fs; - unsigned short es; - unsigned short ds; - unsigned short cs; - unsigned short ss; - ULONG_PTR dr0; - ULONG_PTR dr1; - ULONG_PTR dr2; - ULONG_PTR dr3; - ULONG_PTR dr6; - ULONG_PTR dr7; - BYTE RegisterArea[80]; - x87FPU_t x87fpu; - DWORD MxCsr; -#ifdef _WIN64 - M128A XmmRegisters[16]; - BYTE YmmRegisters[32 * 16]; -#else // x86 - M128A XmmRegisters[8]; - BYTE YmmRegisters[32 * 8]; -#endif -} TITAN_ENGINE_CONTEXT_t; - typedef struct { DWORD PE32Offset; @@ -656,6 +594,71 @@ typedef struct DWORD OriginalCOMTableSize; } FILE_FIX_INFO, *PFILE_FIX_INFO; +typedef struct +{ + BYTE data[10]; + int st_value; + int tag; +} x87FPURegister_t; + +typedef struct +{ + WORD ControlWord; + WORD StatusWord; + WORD TagWord; + DWORD ErrorOffset; + DWORD ErrorSelector; + DWORD DataOffset; + DWORD DataSelector; + DWORD Cr0NpxState; +} x87FPU_t; + +typedef struct +{ + ULONG_PTR cax; + ULONG_PTR ccx; + ULONG_PTR cdx; + ULONG_PTR cbx; + ULONG_PTR csp; + ULONG_PTR cbp; + ULONG_PTR csi; + ULONG_PTR cdi; +#ifdef _WIN64 + ULONG_PTR r8; + ULONG_PTR r9; + ULONG_PTR r10; + ULONG_PTR r11; + ULONG_PTR r12; + ULONG_PTR r13; + ULONG_PTR r14; + ULONG_PTR r15; +#endif //_WIN64 + ULONG_PTR cip; + ULONG_PTR eflags; + unsigned short gs; + unsigned short fs; + unsigned short es; + unsigned short ds; + unsigned short cs; + unsigned short ss; + ULONG_PTR dr0; + ULONG_PTR dr1; + ULONG_PTR dr2; + ULONG_PTR dr3; + ULONG_PTR dr6; + ULONG_PTR dr7; + BYTE RegisterArea[80]; + x87FPU_t x87fpu; + DWORD MxCsr; +#ifdef _WIN64 + M128A XmmRegisters[16]; + BYTE YmmRegisters[32 * 16]; +#else // x86 + M128A XmmRegisters[8]; + BYTE YmmRegisters[32 * 8]; +#endif +} TITAN_ENGINE_CONTEXT_t; + #ifdef __cplusplus extern "C" { diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.a index 372e2539a3ee5aa563b62cbd59e6755490d7ca82..a2efaa2f8d1e1ad9cf8bd09f5239cb630f58cbf3 100644 GIT binary patch delta 22812 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 Pi_b7bY;>q!J^cRw#*#KG delta 24002 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 diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib b/x64_dbg_dbg/TitanEngine/TitanEngine_x64.lib index 3574dc3552a196d25a54141f2bcb6d6b322b8d7d..19b99ff2f23c5b57bd93493df45e220b55423ccb 100644 GIT binary patch literal 101472 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 L28Uw@;m`R0#`ZbM diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a b/x64_dbg_dbg/TitanEngine/TitanEngine_x86.a index a29b07052e2d15091ddfbc1d1639bcfbdbae53e3..d6a784b4137602f08b58e9c9c9a6070b27f62c52 100644 GIT binary patch delta 22949 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 rCR81N-|cp50$rt1u6%I#$8C}M_y_xw5f1ZVHF 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 Zl(mlTU|ATw^|aAh*09`3b^at9{4aZtPl5md literal 106306 zcmeHw3z%J1b^qQ35F=tlL`1}h5g{UvkQa!M*MtmACgWrh5Rq^*bCS7a=FWKMPBK9R zL_|bHL_|cS)LM&{TH0D_sZvUjB2xM0zeh4S~=vl*MU zjj_)@#@OeNX6y^+F!sayB>iYUV?+<0qUbhULHCbI`oXP?5#9e)Nk3SPFz83uN_yx4 z#suw&E75jI56okX=!XqS4_t{b(G!CB+U-oz1GvJ*?}0A}*uTGx@w4uiwCQxliTGSa zSKxXDV~>w2Lb@IYeRZ>j# zGfp(QkEDqM7$<5hRdf@spoyy_tvriyL5Q;w^d6?Dfh%a;VTzEhb)bRWB=yW=T+p?+ zf;h^HXt$;!q-i(MtTQDo`wZhmE08XtpcloQdG4+>)6o`ZOE7%x5{X^(3d zC)#sQMKid9Mv)IeXh)-<`iX+r*Dpo=fxdaWAim=UCTR8Ej0?IDSJ3P4mDF6pIEa1! zaYa|)dIjnnH7|?=y zCB1Tg#syuCE9kfzB`rogK_A5xv;g=-$M#8DbRz777TzW4g#8#7bOo-USIt(0w7&{8 zAG$;@KU&g!q>bpXuS+@{?SSa8Es_q0U7{sO57BX`7ow#fQgkq`pyLlxbRDjsm)|7m z2$P}H6E730{ozy^o2fYIILUhFSlI8)6=%pwZqC;+xH1{^f1uerBbjU(UFJ8>J zppWAUddY_+%|qIVUV?HYdf`2i4qnYT(F>7Rq8H(}pxbc;9elT>Loa8X=%px2qC@wV zw9g5Q3%VIs(6hHF`ZBJdgT5!}>MI#1+IXU*SAU0bqJc?C>wzr@WxO6Vv`W#PxPmq; zQ-m~a0B!u3q|**%oM>=R(dTdl4LmIA)kqJ~X*WnZ9rYs!b#wZ4j6F76(l61^iGDRE z>CxjE6NLWyDCqw#SF|6lpkJVK2)YSZ&@XYXCwgo~5&HgPkK!IXB&io|oakhvi>UW3 zNo$ZcK`5s+pw*8_IvM3cbPn19(VJU}9>f)N@tKP5!4>qTBNQQ@ZvtJkucAwFC3-^A z`43_I0$p&1q_>>NIMD^DXQB)7TM*jLg`g2d1=V#+*btz~KuAr-cN%U^mCOQatCVE%DBG`Es=qj`aqDxU0M3>wo>C$-! zgWka;T`|fy(L2wPbom^{iQchY(&d*S40^{SlHP)LM0Ck~NpCxtaY4X%8|aE}NxJM> z#);m3m7)W21zmQKq_@sxT+oMb1x?*3sReAJ=@CU=#ue1MND;osTQ%yt^gM8~{1!ydgegHDi?;cVF{_jWz9?{QWo9GeTAc%gBc>~cSw@LaL(gEVT zBR@o2_mi~OotVem$=H|9mh?r~Ao|i1g7|X~hiEq1F3}r5D(M6FGfs5F8Is-~D|!r9(EG1eG!IwMH7IMM4>Tmb2jxz5 zO~0h;FG4)f4WA?0w5fOPz`DVqO{;p=uN>?h7+N>DX{g?+HF_Fb>y3hK+SI?HuP;<$ z7g$i2MqvV?c_*D&=l6q=HU`4n=H;Gz`?HTE#%mnxZyR zG<7mOrV})Vd~VN7t63XvtuKaKC|zyJ=el8IEMN~7QxnbB>iSrr44UeSNkX2n92Kpu zH%8WNFPdXD(-a++6)=Weo=UK1#OJzUV=7=TAMul8bIRYwg2P%lF}c%Ah{Li1#(>Kk zM6cXlcs4wy6Et>w?%LY6V)@vZuC&3^dUQ*ONkX1692Ftk{lyNiiFr&XXw3OsCtP-* zfbB8j_C!xYL#v-#^r1g_>5B*gma!X?tS?&YM{CW(ZzCb!=NPjQ!O01$A>Zd1s}aGf zVytMzN+BW$SjKQn67b4ei;5!5w0%*7$j(5|u?tl7^-qs)E}E;G6XP3kAC=>CPGjXn z10zanYK+88jmCyQZzmf3JvR=`+ydA(Cq zxs!-(c2}cA0 z%eL)Wfuy%lZ>=gePjA&0Er$7NEZ7|LyUeY_vI1dz(Ncv*Utb7sc(#UXM5%zezBMuF zn6Mb=3o8arUpGm!Uo%1ot9j};@P5FDP2pk+F=sy;<=5LruXjx=ZqErz@c zS~8141GN>Dw>Xa}=XaRVt!NgtZ37eaM$2R_E<>8-&ANO zEt989DCEn$MwO$YvM8c)l49IJaI_aoNi0X0vFtQgIT}^{rZ~KHOI{wzfv8 zKTJ&(77Z6G$0nwXA)5pJei}$NZ>26>Z%h}|G^WiMoR*8M^-WAn>awsH=4V-k4r_g@ znCxw|CUn#?OuuNIz?R7H`g&t4R%;+PGK+(BuBkOgcHl8KI#kDm(Kuy_lVViFhQ{<% zF%lZ3MY$=oeVxQzQk6G{(3m!omM?F$YQv+VXt$Q2K6h0S)AG4)xGaW{k4!1Z5lpUE z)TRooVl=H4;EaMLqUmcsa-f0ObbrP(V5^DB*98=?!B{=r5DSF^wPtM`O9pn8L}Z9@ z3YKP96;tR0qK8_>14*b|mRDTXJ4HrL#{6dM&_vHnF+AO}2AGsI#@FeJ%g|^|PaCR_ z7we|Y8bMSf7Wa{4wT9o@*fP-^ck-Xp$VN;EwLOe8&DJ!Afh1x~14d(PvwRX0E}w2q zh(akV$zfRmGck90^4V}jf!fn8zpMt)N?j3(x~JL1Q!|Edb0hMYz2lQufi9YI1#ne) z!-@!87G{eE-7z8ruI{?#2-@>lGKwwNF?(hxWxdOXd=yI%=$2(06-Ah)tm87nMUO;_ zEJoI2`7=n7E7Wn&N>HrD2ugM3#B{@SfwbJ0pun;*OSz6o^AT{xT2$Y}u+xX~I<~Z| zkG6)As?VypA>JVA_$U?%pk%Zb| zqotN3Es@NPp$go6;K-_2LV4eUZSP*0RmljWN%uj#JW#Wwp&*@vK*LIbsy|w56oX)q zsY*vFYa>&^mXT;(Tk=SwQq|}vSt)_osZU2w-cEK^+tNcB^)^O|nP~0U!bqG*9&`++ zCCW;Mh$c^wNS@q6awO3t1{&$uv5NDeTeXHe=tL8ecs(BWhesoK zBTpEO6C~1!WTnsHheZ>JZ8WS>B6;yhr7RXBnmirFOPyr_@}H;{bHh<7GrAY9Uc3Wpt^a zABYq2g6j7oT5X_jqBbI}4ADxkUuc0?BYJ`WF_i0=Ysn)ZoyS0& zh!-Gw5v@G-G^WSpw9tAxsLgsp%{B|Seu-FuH4_utrf9Wxs99@F)ou5bs3^iL2akkM zuzROeOB^gl>P3%rY^HDPB-G^?V8(IG7%)a(`0^)UtLj0b6XN>YvkIgPZ; zw2iEa7Sgkh{2fhpAWp;!K)r~N_tiHyYt4GCfhH8b?o3GyU(Q-H5kmzN7Y#!G-brt6 zbR$fP69SXRv^*gxt2CpK6t%+@zFa0YJrl}6JhOp36*GkOqC$aQ4~b84Hd4)6&)^Zk zP~Uo4MJsD#W1DN`KpGJQER&d+#PFOZ>~r04Xi!838+xKMV@BlL^Z34IShNu$H`l7KQ+mY$ZtA5DCoq{FtR=B0FW&9&ESrx6xSB3X8A z(NI)0@g$_Jhv^A5v~Dwq9Z7>9J&PVITi*cbm=w^9R~-nF?h3V9(`JVW_N38Rk!0G@ zNQ@OXbO!tJ(&otDeZ}@->=>PFm$#-iHR^KI+C{*ZT3DRJnqXwHBq^2xygxX#F|nhO zj2Trhajj?@>oqK#4i>`$W7Al?cC!U5In|+23@P|XP_DcVPB$9lDmFXBm%5g9eDG=*;0v^uQ zGHf0*lVUB9sYpi*z8**vGmX%z`(K%pChFpMJ zRSY+GPMWp8s3^iLJ841~VXvPohU>M`5m3~qlM16DW2;X@qe=8-9v&7Ko0cnXN-Ft- zwH-1U^kUen5MLIF;a0R0LAMEq>6cv~j9`f8H#zS~Nu&Jo6+%*+5ai0CXJ+w2(?V%} zCX3H42%9f4h(kTtGi|Y5z0e-T7BkAm)EI7k{TLIrib`Yhmz|}!EXFmNN(dF(JgZQ$B+m@!Sry-`{~BC=gMmVm zibkyBi9t!uRwPH)Z(43kFb~7)xNVX(<>yrx4^&iqlVi((2Od|+#P<^rGXNcBLAp*8 zyydJQ%gYr-^nD~dLWvM5056MC4L^s}Cf33$f2PQ`38SLoqtZ=G$@0Ks3dy*Bj>E`h zz9G|I`y;1~)`v&soOeW|Fib>Fw@go3E0VOVvTW}(XHiS2I!O^hz%pPliR6hT9kC8> z_E?Ds0+wglvI2?Jra83Anww@vKu`PYdIs#rdxxb0Cl`&PSs$*AjhSS|Bq7fvG%7;n z%K_Tdflg{n67r1osEE3>GF(iZR&R}ZRhX8GuREwicm){p zu{0zXV@)#JXr-)3?;G<_)K<+`Q2tBqYE>Jhgcx^VX~x_=c0tisk@?9d$JL2jXrCBq z#n$sJ$%ngqT3nsD1sg-oJC7|G#FVQu9m``P&!LXTM3mLj^lg^e#h`pNjLJ?Tx3nP2vSqJXzNvp;`RN18Hw^U-E$`pd z(|>Yrf6u0s>-vX!P9NITTDEN287iF}nK%g<=n%dG3n$Ub;Xev~Q@@q}&WxY}W|l6& zHVpb3XEV^nB;c)GdwNXOWsC2q>j(%-KH8`VeaePggaa&V!98FWK7)r`glNm6hixNzgpMeFO%IBCYId+LY$E0r- zb`}3DV@H3Uv2(tF6El9u*!&+cb_#YOz6~^XKV!H404IRpx*FGOA$tHj4(|!t4w{FZ zh8u`;C9Y3^wy)*v0njPGM|{xzXK{A=CeG$^&aMEBJ`P);%{XD?UeNdMV{G7?uzeI6D`F6DQa`-<2nUY{d1B zXL9z)Hy9g*-6y_|^x*f^eVpx%G|henXM>QRzBgwx`28U0i}-!_IA{C7<^dC&Ep2di z6X+`ZK5HdpAod>48lc10adtImw*k)P^>B7A=yBw!xf^VO&YZ>BXO_X%3eFZR=j=w% zgC}ve5xn!y=j`FFNHb&?<9f*V85{aBW0!oJu?1Uz^;*~&<2d02X~ORhf;R`UPZXS8 zvj=B;?uj&m&KyMqEJo%Gud} zz;4pm!TBoC5un@qkuK1cDAz+lKZWfz`*Jq47iS-b?av`E11Oip-(u{8pk;65Y(L~- zGwffujk8~aJ_-Ftk;W6g203=7z6EsV(>VJo=$dDtET7KV$3Tb7=IrKGumw8w9M0~4 zCuavke)g5XMIGLZ_y-~{529@5!0yb;P+y>jLF`D*TA+tOm%f6t{)H%?V^K~=arUjF zVFTB*aJ_XAXY-eEHgXK`LH91;Z2woHzCbq~2iaoIJ__mwzYp15^Eo^E<*_KNfuJ^o~_%I2w#3E(g_=T<9fnAC^OKOXLI&t(Dx2PJzkBpZ$!Dg8vSGd@z*2GpjAVh-3eN@ z0k%LNgU+F+p&tyQjzJGYcMIa&0Nz2TBR`hkAj9yL7Df$*2$;~T(_)2nm~`CJx+pmJ?gymX7mNnnHM9Epd;P{Owhg; zq1-`FfF3%ZvokJ0KHh>n)Ad4>577w9s^IK+T<@x(TtI!BQOBDQJ{w~V=yM3)IgB<8 zy89~VzZ=*nm;QG_2eb;j>n}xJU4p)gD|-jVqANH%2W@fA<(zFt_%d7{!S!RnpAWr* z--bA#Z$aH>5Tem@GD5B?{bsFxY^-JR(F zpu5k*7=!Q-uD?Zi@?6gDdjrY^*Uh*du>hZ$S(6UIIbx&!0YDuf^WEn{1VevR=PZDjN} zxF_KEL%+js&;tm6`e*14kH9wU-G=K5grCa46Of<%wj%$LzdQHBxbY>V@r$@e;7Wfh zP;S@GF7-e9#`3q+_|yMCmB61$;7=v+rxN)8tpx7>0Ol1p;C}gD+$%x*Ux$14`*3f^ z^%`8Sxfb_&(Cq6mX8~RPe#{X-cU*&c9OB;h9?T=~`y$9b2RqyF%=EAPc76vxlpV$n zXD?$1vlp>}+-=JDM$E$FgJCRqWmDEVhGf zXM3^P>>2FoY!2I(J%>G;?auaOPh)$qz1cqOS?rl?6MH+qoL|b{#xLV<<(Kg5_%-~! z{C)gdelg#RKb`N*pUL;(d-7-S*?bTFEIx-njbF*%$*{LQ@1&SBfwMeJ(!9(FPN6n`(f zmc5VtJAWlRk)6a|#g<{Fu#o+P{gmCnu3<;Aqu7n?XY3L7X7)~YCvWiy-r$q`^?Zy^ z^HDy|&*9tncD{qp@SVKLr+A$&;Xh{&u>08$*pJu`*@Ntx>^}Bw_8s;u_6_!Z_FeWp z_BHl(_G9)idx(9Q{U!S=_FwEj*|^Zj z*x#~`vwvitWVf^Y{V$IsCbNf4(2z zmp_}&V=rYp*$g|59nbb-&t(^|^VzAakF8~x9&^rr$(~?;V2`n1v0t;_u-~%Zv0t#q z+3(qId=}rGpU=Kelb_CC!_VMn@lCwOH}kXk>-cN=W$ZKj z?d%Np5@wxoP{1AR1e*r&;zmUI__wd#H1m4fr@mKLz@{{=*zLuZD z`}nDRIbX?7_rTjR4JYU2Y^DTTUf0XsIQ!wM)?N5E^Pkrc5 zeW-&z)H~~xStrkW<*XBCt(diZ)`_#0&3e_WlV+`+)iZ15tW#&Lnzd%uakGw})i-Nb z^=7e7-t%D`*gz#9sOBg3@Ot~jy?GWDAT-X^oO<&@b@(+WT} zvHP|>xrAQd$Wu$?X(D+0M+cg?Y)Y#V_$Qr2*;3y+pGa(RB=bQDN^I>d(l0kJHb2Rf z+11DXI94*ncJuOQY^z==agOH+SS5m`CmdV@RivG~2<^>%-LSA_ZQD<-3}%CJDQCc5+hCH`(p)kJS8&`RaoJvL(L?(3h0<7 z=;|UQof$+0$v53-zxpk25wv^VCxv)sUhtWrayC+1C9)p+bKwH zV)p^@C9m^Iy*B1csF9>)lu5CHLD4juGiZjlLxE=F1vZlAZG51G(&CvI0t3%fzk764R&K_HkE9k!MGiFj-ZtuHQM~O_*5$M|ia}v>T?+Rfr>xQYAMx zvkg1g(l1$WdJl$oUZ2mANx?TI!4B)twD!{ym{wS&LVr&Rw@p*&?N2;_>A*oqIhN-f z@FOxL-;OAAFF8g+_Z#umy7Og&iWU==Mvc_@48)IWy!y!-SqYKF$Y(L7Q2z2i|3EA$ zkRP}B>clM*2W5jSHEncH7<8Lyt4h<9FjDouSa)|~6FbzY zyIXY6JSDTf6NgdSUNaQz;$D3sw!BY;Rs()ulHgpe?0ogMXNSEiY>^ zVFW!7DUgGyj#%>SERB14+=<8tANX5qlYAETs=Q(Bu`*f zmbb}uY0DE(6gm|%bqb{r$|Ez)Pmv#el%~vp4v{(MI7vAv@D9e2Okk2WJqh5ah#4M% zL>eJiq#!)vGj*vqz_SPxNR;jT%0n|)LNfW1jLQ}7ci7e@Wid6SiSrFt4X|cEB>HMlo*!$z9~3{Z8c)#X5Ovzc)a>0sL~iA+9`gPTeSM*l{$3rm5xgaP>b`j2B)-(_%9rP^tC7l{%cL$SKMj=+ zgsMcvNEzW%;nv3|H<1xDwf8xtlIOsr6m2)AfMp`bU7Do6@<^gb0Nb%CBP{c&;`&Zb zPFz=L$F&@ubPU5Plb&#Xk}=FIRF|b;lt9rLwT?c99xA5FHX}AkwdKxJRYKt7TXC!g zA=75bOuk)5sWN-EJC%iDIZ>$u*^|qFWyLh!QU=3tVp?|MjbfQI7lgK#BwInaov5l)cbSW<0`AD9mC>Evgfup zCiU{RP-eEPSsXBMILoV1ftK4%ws$^@TXS8|jE?1aRyMqr#kDF(u+8+)F`>9d8M6qp zLood=8!auPX(amXN?a#3ThEnPK$a7mOcGi3=1~^QiWzvYm3V>3j^?|#Y1q)wO-U?w zH_4%{WjVc-OyBh_B{9i?C1)wmM6kGJ5trK5vYv@zImWrXh=CnFaKFqG|P!zGVM~=T;IViFz+fvE&Fy=Z;~(Z zDgH+6a<^y{XY3KyM3T!S+7-{Roh3^P+2PxXjy($-YnDr%Wy|6^>DABT z#$C_YY45aWR0G#NDN&AN5hp#Ju(XEBuB{@=PjWmH<|T*Y(&wZjrsBgG9a^xJKv)oo zn=$@$<(8u=v1kVoS3k!JRHU+T_=}6BQ$kwiX8?9hx}pUYDnv}^RvdE&^wW~o^$p7x z`cy&X{Z*BiEefMaCAo&K;eBU8#g85EYWV>APHrlerC}`snTn5#ZI?I8j-0n-fTThS zCy*v!r~w7eg;p{k$I6uNVrVHOTnU{_Cv?hDHRE(>L$x`3TrM?dicBh`iY$;Oip=#s zbTaCSy!<5`5M2Z5Ly@h5AWN>Rq7-VU9r-@5WGvJkQ!&D%(xgAjT4;%)S-rLMSC+g_bhM(a=q+ zRPuZR+p4rN=(<#f)?CNRK#sEOmF|^EQ8c%Rmnb78$tOEh3fc%tOKHVKwufLMA+}1p zLN~gAOqGYNlYqqi-gV6k3N_-OnbAqW$hje!DSC6$I>g3mslH0I5~UKdEFCw4ggEl{ z7OZt!of6D-99K>kf|ehorn8=-BYWbY8F)UN{&44s%jk}yr%I8*}QXc4xLPO1%(oW zX}g`4>aF2XIF7c8W~0oXbV`A{=m<^dj4qPels7}0?K!8)GuX1T4R*VrR*Rn>Gorq2Z&0c0V*|5D|1G}~`EFWz{woc_B>lHM;{V((9 z4E;KK%$3#x3tVP3g6Ab$Cf*Zxw&+fy#uzt>C2*pI4z*qJU9IYTyop#M1bOswRT!%g5r918gZ z^4)? zqjqhp&N{r6Fo$18upEvRuy6x*+>R3hD=EfxSh*nEF{pQ71}9ok?08e^K_;EX5OK>? z8n(TxDm`z>JaHq++D+L{jd51C1=>Z~O^W7v)`=~fjH@0@r(Lm(V!JZiDKOGDr?vX! z?!+_B&9-I72iZ-MBl0bK!tz~A+UYq7Yt4cpvAyzDFS(2xw6?09q06v!hDzxet;NPY zS~AFG*?2|kVsMxy8N{WLbzMXIiQ4+Eq%5^CmX&J~+Ro9oL7VTIb0v2AeE(_7o-eYa z$w^D;U~P)V6@*coX&y2o^##{ewj8gOapjU6bH8qSu`xP7aH)LXR% zT8@5?Xghzq8tK>Gp(D78nQ{lW#ZjklPr-Wi6u5@ls`jHJUcbQ?UAu`JtH`FSRUiLax9jKtd6{?m51=i=q2BE9aa3);XfnrELC-7+$2;KOXQ;$Sn*QJn&Lnu zCkaJxN|Phrf+rCfm)3q0uQgN>O5Nxi4NFUAdeT z;3`eOxoCFKP?Vso_GpC$T3#Jm@=UX^v~mr?sHvtyn{08~RV(v}*a#a%Rbn92pxs>X?PcELys7!J?(d%ys^b zR-r{lAE$nuJ-d(3V$XfX$Pf+*!LIG%j~_WguMFm`*Sq2O;K$`UpsvfoB8bMM#<*Zr|;JpDb(%hb!* zbLKn^e6mS@vq2Nv_gz~bZca>1Y-!CsZ1C{8eZBps3aR&RZ-gl#8DQ9qo_yd=7>yEj9HqqkaWN(brzKz;?JXh z>W^$OY)D`J?S@Uu8HTJs@{^-%!g(Mm?^*Q^` z>T?Sm5!k-2}l zHTxo@Zx-%W?w5vs<*>@-vFO-%ZBdimJ;1}0dgnRR!>LyThX8Sp2;yl0q?d%YBlw~P z@jT82;+_Fw=XeX3#_lK$@N9`}zOU{) zpNlfRW?v7j^Io$!fp!?$(Q^b^{5$bZ`_00{tmXy4-H&k1YtPP0G*^Gmb+Ee8S{5a8 z_EO|*e~CsP$Gh*L{o<@V*5=Cdc_k{n(C!#(apJBuA2~dr#0p<22hd(p+K=&z;xmDl z0QvbPvi04609mD04S^K?1e&(O^;HIf#}Q4vM070W;B><^uDD64TzB zA*j&GZ74HeJ~+gSRAyDg-2C-L0!n5t?wrvl|jdgQ1mfjrA2dmyU60;C`x_YsP z7AeTec)5~1MBve`7{VLWFF8Nlwj^`+;g`5rk*s+|+a4`blJk7Du+vp9$;2#?kErK z$*#Mj1H8^lGj}&Q#>49zEjOEAKxpzK;;zi*mn7~y^kU^$iACER;UfmU7f`VAQpc@l zabiw(1k$juOha@}Cm-Akx9ydS6C>&|z+Plw!+|ZnTa*V_z3(hZj0^Nqbnz~vp!4>Y zEB_^a3fyMk-=F<(N9Dh?#7=LX)p7YRPCT(6h4MeHOhIa2uFml@E%5jfUza<4@4YR* zI!{63PDoGmuMAUQ?Iz|!d*SxApLk#Lav-0OLk=5#<@TNDl+AC~ye-k=CpMJP~zBBjOl{w_dbj_>z_Sl&+UzNx1 zLO;*FlkKt5_3^J>_Nw>m+*_g5Hlq7wWyiRSGv$1;jSF{NbSif*!j92%bL2HPx^SZP z;kpz#O$q4^2$ z!foq6*8b|c-nm)B#t<(Y+$)c9xg4HmA?ht- zy%yx>xNVEdOw4o-0LmE}r3wIB&Uk>u1F=yU_|0_Y&c(ZJ|b|sg-+mZXNz? zgNDP2#%eo*0w%WF*{|q8x&5}EK`-3C{Un~@$bVofVbODHxv{rrzPsf) zs`0!%!+lUM+&+(qnKSu=)#I39B~~8?5_j6UKs`sHTAP#vow9N+6Zc&5Lf;nRb>n`O zDc3ON(A=s=QvI1)s2V-eWR%v8F+7U^JR&4AijGGn_`7 zouejJ5y-=DN}+mt|96g=$!RN&*^Tib(Rb)eoN0yXoMg~(JIb}%?FvzEYZMe}^$|XE z@7&>`MT)aJUgnN66X1onFt2#qjsdx`Z>NVx`|eu%L3vQsM}*uu`ng%`u9S4<9`gnd zy$j`>xO0>5#d#K5><|sVpuKS0I?kPjD8m?T-uGORjAWS{ESvd%#`h$6r!`CT98RE z3GHh$^F(%03^D91)pMDt&o^t#@FY_&Yt=`jTu-@J;aW$)bY8ZZ+I&lh*NvW%nVDRo z5sT(HykDq`i0%CSV)eppThNk3FQHH4->NX%9+TsN{t0{Kb2%SD&C`oOA=k#o=0SH+OU$qzoP7jE0qa=th3 zPN9YkyzW!SMIyH5&TAz2I<(-GcCO&P zLTKBzb6!OsOyg#Xy=n?_^YOnhDZtz)I1SN5@*82>yyxosLpE}F&Y}-py}lFAeB{md zmj*j=JfojeKiod&i4}SBW&3bD^vDvYR~+r}6VKiB)yH3j__+pOz2pyH>@xkva@Ilg?0B}=#lJKZEd+{zgrx9xzlc9 ztBA^_z9{kZLB2tMN4Roh>7psWWWwG*e$iH+G37A-KE$M>Wxe98j+whx|3iqWzMYC? z*Go#VGh2US}+x4HfE{yB*osov_ynVJ4=N#wAotG4D`j{n8R^^RKZLRn{KT%XJ!cb@0m z82Kq1*&HO+d2Vy}pxbRsTILrY;YD9%Rc==~+<$d&^&b1{>*p3-$ZzJ}cZY*(&eQgq zZuR?6Zcg`aQOs`i+}tYLoe9*=+i-49_3t(+_63NYFYXt%7jAp!&Am7JbOhf$dBH>T zn_GMI#66gvRR6BOG_2jkppLQzf6_Ps0z0;iM zTKipb%t$BmQqjJ?6SEN7i{roIsP>`j9$fX2CFl8dcZjcQynlLpbHq8bay>6e)bmp0 z{=eIx=Ze8AmiD!fxntksr-QyDN280suIwiA|HP2-T+%$g?xde@i{JU3JlDd$5XTQetLHi~ zKO=9OFM6mr=WR!=Df@G@$}6Mi-VT2$gPtE)D~~FPag|ovznn@%vXfUv&(y$IGU(l@ zf!zDVuX^ZkII4|dEXQL>6CSDlY|Rh1zmH_f{c9d}Kh7Y-IdR=Y&#bq9J&E3>QqR=+ zH#}_VWR}TzxnhY`+eFEx9{T_pMme%xU>(3TnB#&_Tl+n201M3$~B$I^Y?A! zwG-Qmb&GCYRZBRxpX>uZ zT9~=YBW7;L)gKx>I@2)7T6L_%oS*g|c+kO$3`&*Ja`pBj4=pUns`Zxpdi)^=t#hng z&VDSgrm#b<^w;TpACBDY{b7kFK7%dljjf^&;G5how3Wnq2%VGilM)sEt_xU+wKm$N z{ihCA7wRs7Meo*rCb8%<)RQMrnnM%ngz_MZRa<86^*T}(N#F_qI+jhBzg$#ukgz# zW;aSVH^coufm+|(tTpSk2EFF#6M>!dgyf691ipEIro5-pB(OuUkPAuU^}k zXPL(xY`rOS9Jp#}=T=33Pq=Gq+Y0Qcr@n=r8a%Bh$ZTcI%=q<095bxk$|aneJN-eT zwuVOsYAtL!5jyQx&SRn#&&3$cxG2{WEz)JXiN^(=I3sAVsEv^0U*~n0=qt3>#BL>? zcquUvb3P8;;F!Yh}1;yIn( zP44HQpWLi%E=xVWh+Y{zu?|E2RnKjQ9x42)__=l7{T=-7?8ch&l6;sbdn=%>{ui>|lr%t-!%cIaWzSFZEi zs^38ppEh8kjSRbYhGJqQr4_grmYA!XMWNPbf=aHQ&%_8uD~$(7F~h>G+Ol$G`=Sz) z-Z?%c`J5ZY>_R>h<1?+3zgS~#r!|Rk{iX9cP;O`VLrPRNRCMD^@!WmjB_-mzuI-bZ zd7hmY;B{V)x#!H6O1#Oj+HklOQMotfo-+@%kRmtl%2>Hx_%ew#g^vundmejcv^gw_ z*?H~d)&&n&m=nzwJ?`nH!C+XeJi;aJUi4mLejGE*XyqEsd5gVVqfR%6i>BG7YOt7^ zAWp|Q&dnB%$YVzubJgDb&qGL{Usgs8+wY!c>e@S9Qq_YT* z+LaV^p$>ApfE>LmY3M>tVg zEb7WVE|cShE-p=1#W70Jrd~bAiShAPAGBKP0}VB;bTbUUXt7O_Eie+sXE2t#1Jns_*O2_%q;ID7qOeCSY+1pmub}L zsn*1}+_|j_=MH4@xm+O%uerX7iOHe*c(HD}3w{K-=aUr*wWmSH+ixUaoz0PHRP{ES zxU12d*_9fz*_>!%3zDJ>dvfIFE2|XV8hq4)4||Ht5LY>$xp!ebN!&=6sf?U^-?&;K zrn*C z5s)w3X(3)0`bX|5;dB=qL)h~3C#rlp=) zVy>x8jYgM&x>=8}3-P*hI=e)c`CL^D!iaJ?2jdRA>)xso0!u?K5A zWF^zaa>2k<{l1+k=^}yJm6A?8*VFp^mLzWEV5G`9&OH%s%^-&ZR@EBL_2JPZa_6|Y zy{GC4+$R_HoDx;N;l+>@9XhI(@xsLW>;uuRwn@}tvbWLd{L8VN55ky6>dLxXE>GhI z3BDY`a8SAQ66=ceeQZM_O-#l=Nw3@wbF2Cjgf-N+eno9~+w^3Yc67|lhb9BOF0}td zOC&$8*K53HQQNkzv9bn-BV@JX`pfn7W*jpzm{)Bzxi!Z6%w`k4f3nAythH}iD1 zQ=!VQGAXy4V;!}6+s%v)=SDHRkk8Br_yz~FOT8ttc5z;a7iO?}sb+HcMuUhqam^yy zV5_#A-1EZu0&f%}{7BJUiAxJE+2o--BzPT<^*R5p3-Z`q7?pB!*$ZuSa%_`1?#lQ2 zIlrnmIk+>$FpeBt*BHY_0p}FMtztwbqw_aAxt$L$veSTd$MWDsyp`xu&FAj7Z}#vr zMPIphElxZulAq7THm=;4YH+&Ip#4TfbB}hn>M2N!n)G$gTbvY#Dqr5f-XEeFti;>l z&U;+q?nGbrT+$A`8+|S@p3*mEZ*}memN$0Fa+gP723fCO@|n87)Wzp9`syjj_|?75O+hy6mB;u@o4YKAyS`N)8&i!xDEP|gnRSx4+vo$e=_&efLFPRi z9s8pmwcoCFTwEcKHe$6<&)tO*m7`mGhhESG3ak&Ja0O z%w4VBD?{8wL08S~l0)qn@493vdbSsl7kQOSAh(u(m7SI$ zbxe9{;#M6w@!U$gYQ9?_*ITs)CJ*|AS8R0D9Ir)>(yCemxf$!#Ha5IqnyqOpm30q0 z=U?z1gH1E0R5P!f+sx>BjX;F+f6>Gl&6ptO4r;4j$C-QedrRci^_f!}6FVAR#m=3w zaIJ%F!EUVAFl`$wh6l!`;ldZ(xGI-G&d=g~Wh$Z{B3G^FoS)2fC01Xty%;+t$XaEz z%-YEN6|LgRxZ!n{rLI>YWPT9Ij@O3<6MkYA0X5XjWyjouQ%s4 zcLU+kr_Jh}K~Ry^%QP{kJQ%tAGY_o`WtkZFY449432kb4=h#?nQ*A`;>>FgTa_wah z|J+5CNBBLdh##~N@oX-i5<5rC^v1ui5J#{9rn;{z4?wH8oDAxR;;3N*s*akNKhbRQ zFD=vpi!N$&XngC_d2Vxar4QS<`Y~yIXn9 zjN-Rgxb^W#e2_jRb`uVoQ}q(gp#GhO+QbIwcza3Sc~9~k>+j>J-MC|AW+4Ayp-$nv LlHt+VrvCpAx6>-w diff --git a/x64_dbg_dbg/x64_dbg.cpp b/x64_dbg_dbg/x64_dbg.cpp index 9913f4d9d..2ff645c83 100644 --- a/x64_dbg_dbg/x64_dbg.cpp +++ b/x64_dbg_dbg/x64_dbg.cpp @@ -228,6 +228,8 @@ static void efree_json(void* ptr) extern "C" DLL_EXPORT const char* _dbg_dbginit() { + if(!EngineCheckStructAlignment(UE_STRUCT_TITAN_ENGINE_CONTEXT, sizeof(TITAN_ENGINE_CONTEXT_t))) + return "Invalid TITAN_ENGINE_CONTEXT_t alignment!"; dbginit(); dbgfunctionsinit(); json_set_alloc_funcs(emalloc_json, efree_json); From 67b7fcb79f4a7e39d4981f6f8d79ae94ed38c4dd Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 8 Dec 2014 16:37:52 +0100 Subject: [PATCH 54/58] DBG: updated TitanEngine + fixed a warning in _dbgfunctions.cpp --- x64_dbg_dbg/TitanEngine/TitanEngine.h | 11 +++++++++-- x64_dbg_dbg/_dbgfunctions.cpp | 4 ++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/x64_dbg_dbg/TitanEngine/TitanEngine.h b/x64_dbg_dbg/TitanEngine/TitanEngine.h index 18bc25208..0576db7cc 100644 --- a/x64_dbg_dbg/TitanEngine/TitanEngine.h +++ b/x64_dbg_dbg/TitanEngine/TitanEngine.h @@ -594,6 +594,12 @@ typedef struct DWORD OriginalCOMTableSize; } FILE_FIX_INFO, *PFILE_FIX_INFO; +typedef struct +{ + M128A Low; //XMM/SSE part + M128A High; //AVX part +} YmmRegister_t; + typedef struct { BYTE data[10]; @@ -652,10 +658,10 @@ typedef struct DWORD MxCsr; #ifdef _WIN64 M128A XmmRegisters[16]; - BYTE YmmRegisters[32 * 16]; + YmmRegister_t YmmRegisters[16]; #else // x86 M128A XmmRegisters[8]; - BYTE YmmRegisters[32 * 8]; + YmmRegister_t YmmRegisters[8]; #endif } TITAN_ENGINE_CONTEXT_t; @@ -840,6 +846,7 @@ __declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, voi __declspec(dllexport) void TITCALL Getx87FPURegisters(x87FPURegister_t x87FPURegisters[8], TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) void TITCALL GetMMXRegisters(uint64_t mmx[8], TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); +__declspec(dllexport) bool TITCALL SetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext); __declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister); __declspec(dllexport) ULONG_PTR TITCALL GetContextData(DWORD IndexOfRegister); __declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, void* FPUSaveArea); diff --git a/x64_dbg_dbg/_dbgfunctions.cpp b/x64_dbg_dbg/_dbgfunctions.cpp index 9b57420c6..44b7a4f52 100644 --- a/x64_dbg_dbg/_dbgfunctions.cpp +++ b/x64_dbg_dbg/_dbgfunctions.cpp @@ -196,7 +196,7 @@ static duint _fileoffsettova(const char* modname, duint offset) FileMapVA + (ULONG_PTR)offset, //Offset inside FileMapVA false); //Return without ImageBase StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); - return offset < LoadedSize ? rva + modbasefromname(modname) : 0; + return offset < LoadedSize ? (duint)rva + modbasefromname(modname) : 0; } } return 0; @@ -215,7 +215,7 @@ static duint _vatofileoffset(duint va) { ULONGLONG offset = ConvertVAtoFileOffsetEx(FileMapVA, LoadedSize, 0, va - modbasefromaddr(va), true, false); StaticFileUnloadW(StringUtils::Utf8ToUtf16(modpath).c_str(), true, FileHandle, LoadedSize, FileMap, FileMapVA); - return offset; + return (duint)offset; } } return 0; From 4d469f374295e4c4552625fbcb66d66cc2cf4da4 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Mon, 8 Dec 2014 22:22:38 +0100 Subject: [PATCH 55/58] GUI: YMM registers inside the FPU section --- x64_dbg_gui/Project/Src/Gui/RegistersView.cpp | 69 +++++++++---------- 1 file changed, 34 insertions(+), 35 deletions(-) diff --git a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp index a0842779e..d8ea8f618 100644 --- a/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp +++ b/x64_dbg_gui/Project/Src/Gui/RegistersView.cpp @@ -342,45 +342,44 @@ void RegistersView::InitMappings() mRegisterMapping.insert(XMM15, "XMM15"); mRegisterPlaces.insert(XMM15, Register_Position(offset++, 0, 6, 16 * 2)); #endif - } - offset++; - - mRegisterMapping.insert(YMM0, "YMM0"); - mRegisterPlaces.insert(YMM0, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM1, "YMM1"); - mRegisterPlaces.insert(YMM1, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM2, "YMM2"); - mRegisterPlaces.insert(YMM2, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM3, "YMM3"); - mRegisterPlaces.insert(YMM3, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM4, "YMM4"); - mRegisterPlaces.insert(YMM4, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM5, "YMM5"); - mRegisterPlaces.insert(YMM5, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM6, "YMM6"); - mRegisterPlaces.insert(YMM6, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM7, "YMM7"); - mRegisterPlaces.insert(YMM7, Register_Position(offset++, 0, 6, 32 * 2)); + offset++; + mRegisterMapping.insert(YMM0, "YMM0"); + mRegisterPlaces.insert(YMM0, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM1, "YMM1"); + mRegisterPlaces.insert(YMM1, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM2, "YMM2"); + mRegisterPlaces.insert(YMM2, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM3, "YMM3"); + mRegisterPlaces.insert(YMM3, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM4, "YMM4"); + mRegisterPlaces.insert(YMM4, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM5, "YMM5"); + mRegisterPlaces.insert(YMM5, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM6, "YMM6"); + mRegisterPlaces.insert(YMM6, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM7, "YMM7"); + mRegisterPlaces.insert(YMM7, Register_Position(offset++, 0, 6, 32 * 2)); #ifdef _WIN64 - mRegisterMapping.insert(YMM8, "YMM8"); - mRegisterPlaces.insert(YMM8, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM9, "YMM9"); - mRegisterPlaces.insert(YMM9, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM10, "YMM10"); - mRegisterPlaces.insert(YMM10, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM11, "YMM11"); - mRegisterPlaces.insert(YMM11, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM12, "YMM12"); - mRegisterPlaces.insert(YMM12, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM13, "YMM13"); - mRegisterPlaces.insert(YMM13, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM14, "YMM14"); - mRegisterPlaces.insert(YMM14, Register_Position(offset++, 0, 6, 32 * 2)); - mRegisterMapping.insert(YMM15, "YMM15"); - mRegisterPlaces.insert(YMM15, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM8, "YMM8"); + mRegisterPlaces.insert(YMM8, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM9, "YMM9"); + mRegisterPlaces.insert(YMM9, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM10, "YMM10"); + mRegisterPlaces.insert(YMM10, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM11, "YMM11"); + mRegisterPlaces.insert(YMM11, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM12, "YMM12"); + mRegisterPlaces.insert(YMM12, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM13, "YMM13"); + mRegisterPlaces.insert(YMM13, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM14, "YMM14"); + mRegisterPlaces.insert(YMM14, Register_Position(offset++, 0, 6, 32 * 2)); + mRegisterMapping.insert(YMM15, "YMM15"); + mRegisterPlaces.insert(YMM15, Register_Position(offset++, 0, 6, 32 * 2)); #endif + } offset++; From a883544e52301c59ff92b3acab8c85fe932fd4f5 Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 9 Dec 2014 01:29:08 +0100 Subject: [PATCH 56/58] DBG: resolved issue #221 (crashes because of race conditions) --- x64_dbg_dbg/addrinfo.cpp | 57 +++++++++++++++++++++++++ x64_dbg_dbg/breakpoint.cpp | 12 ++++++ x64_dbg_dbg/patches.cpp | 9 +++- x64_dbg_dbg/thread.cpp | 12 ++++++ x64_dbg_dbg/threading.h | 10 +++++ x64_dbg_dbg/variable.cpp | 10 ++++- x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters | 24 +++++------ 7 files changed, 120 insertions(+), 14 deletions(-) diff --git a/x64_dbg_dbg/addrinfo.cpp b/x64_dbg_dbg/addrinfo.cpp index 91ec1025b..cd500fa4b 100644 --- a/x64_dbg_dbg/addrinfo.cpp +++ b/x64_dbg_dbg/addrinfo.cpp @@ -94,11 +94,21 @@ void dbload() void dbclose() { dbsave(); + CriticalSectionLocker commentLocker(LockComments); CommentsInfo().swap(comments); + + CriticalSectionLocker labelLocker(LockLabels); LabelsInfo().swap(labels); + + CriticalSectionLocker bookmarkLocker(LockBookmarks); BookmarksInfo().swap(bookmarks); + + CriticalSectionLocker functionLocker(LockFunctions); FunctionsInfo().swap(functions); + + CriticalSectionLocker loopLocker(LockLoops); LoopsInfo().swap(loops); + bpclear(); patchclear(); } @@ -201,6 +211,7 @@ bool modload(uint base, uint size, const char* fullpath) } //add module to list + CriticalSectionLocker locker(LockModules); modinfo.insert(std::make_pair(Range(base, base + size - 1), info)); symupdatemodulelist(); return true; @@ -208,6 +219,7 @@ bool modload(uint base, uint size, const char* fullpath) bool modunload(uint base) { + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(base, base)); if(found == modinfo.end()) //not found return false; @@ -218,6 +230,7 @@ bool modunload(uint base) void modclear() { + CriticalSectionLocker locker(LockModules); ModulesInfo().swap(modinfo); symupdatemodulelist(); } @@ -227,6 +240,7 @@ bool modnamefromaddr(uint addr, char* modname, bool extension) if(!modname) return false; *modname = '\0'; + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); if(found == modinfo.end()) //not found return false; @@ -238,6 +252,7 @@ bool modnamefromaddr(uint addr, char* modname, bool extension) uint modbasefromaddr(uint addr) { + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); if(found == modinfo.end()) //not found return 0; @@ -246,6 +261,7 @@ uint modbasefromaddr(uint addr) uint modhashfromva(uint va) //return a unique hash from a VA { + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(va, va)); if(found == modinfo.end()) //not found return va; @@ -264,6 +280,7 @@ uint modbasefromname(const char* modname) { if(!modname or strlen(modname) >= MAX_MODULE_SIZE) return 0; + CriticalSectionLocker locker(LockModules); for(ModulesInfo::iterator i = modinfo.begin(); i != modinfo.end(); ++i) { MODINFO* curMod = &i->second; @@ -279,6 +296,7 @@ uint modbasefromname(const char* modname) uint modsizefromaddr(uint addr) { + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); if(found == modinfo.end()) //not found return 0; @@ -287,6 +305,7 @@ uint modsizefromaddr(uint addr) bool modsectionsfromaddr(uint addr, std::vector* sections) { + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); if(found == modinfo.end()) //not found return false; @@ -296,6 +315,7 @@ bool modsectionsfromaddr(uint addr, std::vector* sections) uint modentryfromaddr(uint addr) { + CriticalSectionLocker locker(LockModules); const ModulesInfo::iterator found = modinfo.find(Range(addr, addr)); if(found == modinfo.end()) //not found return 0; @@ -390,6 +410,7 @@ bool commentset(uint addr, const char* text, bool manual) modnamefromaddr(addr, comment.mod, true); comment.addr = addr - modbasefromaddr(addr); const uint key = modhashfromva(addr); + CriticalSectionLocker locker(LockComments); if(!comments.insert(std::make_pair(key, comment)).second) //key already present comments[key] = comment; return true; @@ -399,6 +420,7 @@ bool commentget(uint addr, char* text) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockComments); const CommentsInfo::iterator found = comments.find(modhashfromva(addr)); if(found == comments.end()) //not found return false; @@ -410,6 +432,7 @@ bool commentdel(uint addr) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockComments); return (comments.erase(modhashfromva(addr)) == 1); } @@ -423,6 +446,7 @@ void commentdelrange(uint start, uint end) return; start -= modbase; end -= modbase; + CriticalSectionLocker locker(LockComments); CommentsInfo::iterator i = comments.begin(); while(i != comments.end()) { @@ -440,6 +464,7 @@ void commentdelrange(uint start, uint end) void commentcachesave(JSON root) { + CriticalSectionLocker locker(LockComments); const JSON jsoncomments = json_array(); const JSON jsonautocomments = json_array(); for(CommentsInfo::iterator i = comments.begin(); i != comments.end(); ++i) @@ -464,6 +489,7 @@ void commentcachesave(JSON root) void commentcacheload(JSON root) { + CriticalSectionLocker locker(LockComments); comments.clear(); const JSON jsoncomments = json_object_get(root, "comments"); if(jsoncomments) @@ -521,6 +547,7 @@ bool commentenum(COMMENTSINFO* commentlist, size_t* cbsize) return false; if(!commentlist && !cbsize) return false; + CriticalSectionLocker locker(LockComments); if(!commentlist && cbsize) { *cbsize = comments.size() * sizeof(COMMENTSINFO); @@ -551,6 +578,7 @@ bool labelset(uint addr, const char* text, bool manual) modnamefromaddr(addr, label.mod, true); label.addr = addr - modbasefromaddr(addr); uint key = modhashfromva(addr); + CriticalSectionLocker locker(LockLabels); if(!labels.insert(std::make_pair(modhashfromva(key), label)).second) //already present labels[key] = label; return true; @@ -560,6 +588,7 @@ bool labelfromstring(const char* text, uint* addr) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockLabels); for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i) { if(!strcmp(i->second.text, text)) @@ -576,6 +605,7 @@ bool labelget(uint addr, char* text) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockLabels); const LabelsInfo::iterator found = labels.find(modhashfromva(addr)); if(found == labels.end()) //not found return false; @@ -588,6 +618,7 @@ bool labeldel(uint addr) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockLabels); return (labels.erase(modhashfromva(addr)) > 0); } @@ -601,6 +632,7 @@ void labeldelrange(uint start, uint end) return; start -= modbase; end -= modbase; + CriticalSectionLocker locker(LockLabels); LabelsInfo::iterator i = labels.begin(); while(i != labels.end()) { @@ -618,6 +650,7 @@ void labeldelrange(uint start, uint end) void labelcachesave(JSON root) { + CriticalSectionLocker locker(LockLabels); const JSON jsonlabels = json_array(); const JSON jsonautolabels = json_array(); for(LabelsInfo::iterator i = labels.begin(); i != labels.end(); ++i) @@ -642,6 +675,7 @@ void labelcachesave(JSON root) void labelcacheload(JSON root) { + CriticalSectionLocker locker(LockLabels); labels.clear(); const JSON jsonlabels = json_object_get(root, "labels"); if(jsonlabels) @@ -703,6 +737,7 @@ bool labelenum(LABELSINFO* labellist, size_t* cbsize) return false; if(!labellist && !cbsize) return false; + CriticalSectionLocker locker(LockLabels); if(!labellist && cbsize) { *cbsize = labels.size() * sizeof(LABELSINFO); @@ -726,6 +761,7 @@ bool bookmarkset(uint addr, bool manual) modnamefromaddr(addr, bookmark.mod, true); bookmark.addr = addr - modbasefromaddr(addr); bookmark.manual = manual; + CriticalSectionLocker locker(LockBookmarks); if(!bookmarks.insert(std::make_pair(modhashfromva(addr), bookmark)).second) return bookmarkdel(addr); return true; @@ -735,6 +771,7 @@ bool bookmarkget(uint addr) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockBookmarks); if(bookmarks.count(modhashfromva(addr))) return true; return false; @@ -744,6 +781,7 @@ bool bookmarkdel(uint addr) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockBookmarks); return (bookmarks.erase(modhashfromva(addr)) > 0); } @@ -757,6 +795,7 @@ void bookmarkdelrange(uint start, uint end) return; start -= modbase; end -= modbase; + CriticalSectionLocker locker(LockBookmarks); BookmarksInfo::iterator i = bookmarks.begin(); while(i != bookmarks.end()) { @@ -774,6 +813,7 @@ void bookmarkdelrange(uint start, uint end) void bookmarkcachesave(JSON root) { + CriticalSectionLocker locker(LockBookmarks); const JSON jsonbookmarks = json_array(); const JSON jsonautobookmarks = json_array(); for(BookmarksInfo::iterator i = bookmarks.begin(); i != bookmarks.end(); ++i) @@ -797,6 +837,7 @@ void bookmarkcachesave(JSON root) void bookmarkcacheload(JSON root) { + CriticalSectionLocker locker(LockBookmarks); bookmarks.clear(); const JSON jsonbookmarks = json_object_get(root, "bookmarks"); if(jsonbookmarks) @@ -844,6 +885,7 @@ bool bookmarkenum(BOOKMARKSINFO* bookmarklist, size_t* cbsize) return false; if(!bookmarklist && !cbsize) return false; + CriticalSectionLocker locker(LockBookmarks); if(!bookmarklist && cbsize) { *cbsize = bookmarks.size() * sizeof(BOOKMARKSINFO); @@ -873,6 +915,7 @@ bool functionadd(uint start, uint end, bool manual) function.start = start - modbase; function.end = end - modbase; function.manual = manual; + CriticalSectionLocker locker(LockFunctions); functions.insert(std::make_pair(ModuleRange(modhashfromva(modbase), Range(function.start, function.end)), function)); return true; } @@ -882,6 +925,7 @@ bool functionget(uint addr, uint* start, uint* end) if(!DbgIsDebugging()) return false; uint modbase = modbasefromaddr(addr); + CriticalSectionLocker locker(LockFunctions); const FunctionsInfo::iterator found = functions.find(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))); if(found == functions.end()) //not found return false; @@ -897,6 +941,7 @@ bool functionoverlaps(uint start, uint end) if(!DbgIsDebugging() or end < start) return false; const uint modbase = modbasefromaddr(start); + CriticalSectionLocker locker(LockFunctions); return (functions.count(ModuleRange(modhashfromva(modbase), Range(start - modbase, end - modbase))) > 0); } @@ -905,6 +950,7 @@ bool functiondel(uint addr) if(!DbgIsDebugging()) return false; const uint modbase = modbasefromaddr(addr); + CriticalSectionLocker locker(LockFunctions); return (functions.erase(ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase))) > 0); } @@ -918,6 +964,7 @@ void functiondelrange(uint start, uint end) return; start -= modbase; end -= modbase; + CriticalSectionLocker locker(LockFunctions); FunctionsInfo::iterator i = functions.begin(); while(i != functions.end()) { @@ -935,6 +982,7 @@ void functiondelrange(uint start, uint end) void functioncachesave(JSON root) { + CriticalSectionLocker locker(LockFunctions); const JSON jsonfunctions = json_array(); const JSON jsonautofunctions = json_array(); for(FunctionsInfo::iterator i = functions.begin(); i != functions.end(); ++i) @@ -959,6 +1007,7 @@ void functioncachesave(JSON root) void functioncacheload(JSON root) { + CriticalSectionLocker locker(LockFunctions); functions.clear(); const JSON jsonfunctions = json_object_get(root, "functions"); if(jsonfunctions) @@ -1012,6 +1061,7 @@ bool functionenum(FUNCTIONSINFO* functionlist, size_t* cbsize) return false; if(!functionlist && !cbsize) return false; + CriticalSectionLocker locker(LockFunctions); if(!functionlist && cbsize) { *cbsize = functions.size() * sizeof(FUNCTIONSINFO); @@ -1049,6 +1099,7 @@ bool loopadd(uint start, uint end, bool manual) else loop.parent = 0; loop.manual = manual; + CriticalSectionLocker locker(LockLoops); loops.insert(std::make_pair(DepthModuleRange(finaldepth, ModuleRange(modhashfromva(modbase), Range(loop.start, loop.end))), loop)); return true; } @@ -1059,6 +1110,7 @@ bool loopget(int depth, uint addr, uint* start, uint* end) if(!DbgIsDebugging()) return false; const uint modbase = modbasefromaddr(addr); + CriticalSectionLocker locker(LockLoops); LoopsInfo::iterator found = loops.find(DepthModuleRange(depth, ModuleRange(modhashfromva(modbase), Range(addr - modbase, addr - modbase)))); if(found == loops.end()) //not found return false; @@ -1080,6 +1132,8 @@ bool loopoverlaps(int depth, uint start, uint end, int* finaldepth) uint curEnd = end - modbase; const uint key = modhashfromva(modbase); + CriticalSectionLocker locker(LockLoops); + //check if the new loop fits in the old loop for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i) { @@ -1113,6 +1167,7 @@ bool loopdel(int depth, uint addr) void loopcachesave(JSON root) { + CriticalSectionLocker locker(LockLoops); const JSON jsonloops = json_array(); const JSON jsonautoloops = json_array(); for(LoopsInfo::iterator i = loops.begin(); i != loops.end(); ++i) @@ -1139,6 +1194,7 @@ void loopcachesave(JSON root) void loopcacheload(JSON root) { + CriticalSectionLocker locker(LockLoops); loops.clear(); const JSON jsonloops = json_object_get(root, "loops"); if(jsonloops) @@ -1194,6 +1250,7 @@ bool loopenum(LOOPSINFO* looplist, size_t* cbsize) return false; if(!looplist && !cbsize) return false; + CriticalSectionLocker locker(LockLoops); if(!looplist && cbsize) { *cbsize = loops.size() * sizeof(LOOPSINFO); diff --git a/x64_dbg_dbg/breakpoint.cpp b/x64_dbg_dbg/breakpoint.cpp index 1cae05f07..5966ccee3 100644 --- a/x64_dbg_dbg/breakpoint.cpp +++ b/x64_dbg_dbg/breakpoint.cpp @@ -13,6 +13,7 @@ int bpgetlist(std::vector* list) return false; BREAKPOINT curBp; int count = 0; + CriticalSectionLocker locker(LockBreakpoints); for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i) { curBp = i->second; @@ -43,6 +44,7 @@ bool bpnew(uint addr, bool enabled, bool singleshoot, short oldbytes, BP_TYPE ty bp.singleshoot = singleshoot; bp.titantype = titantype; bp.type = type; + CriticalSectionLocker locker(LockBreakpoints); breakpoints.insert(std::make_pair(BreakpointKey(type, modhashfromva(addr)), bp)); return true; } @@ -52,6 +54,7 @@ bool bpget(uint addr, BP_TYPE type, const char* name, BREAKPOINT* bp) if(!DbgIsDebugging()) return false; BREAKPOINT curBp; + CriticalSectionLocker locker(LockBreakpoints); if(!name) { BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr))); @@ -89,6 +92,7 @@ bool bpdel(uint addr, BP_TYPE type) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockBreakpoints); return (breakpoints.erase(BreakpointKey(type, modhashfromva(addr))) > 0); } @@ -96,6 +100,7 @@ bool bpenable(uint addr, BP_TYPE type, bool enable) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockBreakpoints); BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr))); if(found == breakpoints.end()) //not found return false; @@ -107,6 +112,7 @@ bool bpsetname(uint addr, BP_TYPE type, const char* name) { if(!DbgIsDebugging() or !name or !*name) return false; + CriticalSectionLocker locker(LockBreakpoints); BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr))); if(found == breakpoints.end()) //not found return false; @@ -118,6 +124,7 @@ bool bpsettitantype(uint addr, BP_TYPE type, int titantype) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockBreakpoints); BreakpointsInfo::iterator found = breakpoints.find(BreakpointKey(type, modhashfromva(addr))); if(found == breakpoints.end()) //not found return false; @@ -131,6 +138,7 @@ bool bpenumall(BPENUMCALLBACK cbEnum, const char* module) return false; bool retval = true; BREAKPOINT curBp; + CriticalSectionLocker locker(LockBreakpoints); BreakpointsInfo::iterator i = breakpoints.begin(); while(i != breakpoints.end()) { @@ -164,6 +172,7 @@ bool bpenumall(BPENUMCALLBACK cbEnum) int bpgetcount(BP_TYPE type, bool enabledonly) { int count = 0; + CriticalSectionLocker locker(LockBreakpoints); for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i) { if(i->first.first == type && (!enabledonly || i->second.enabled)) @@ -202,6 +211,7 @@ void bptobridge(const BREAKPOINT* bp, BRIDGEBP* bridge) void bpcachesave(JSON root) { + CriticalSectionLocker locker(LockBreakpoints); const JSON jsonbreakpoints = json_array(); for(BreakpointsInfo::iterator i = breakpoints.begin(); i != breakpoints.end(); ++i) { @@ -226,6 +236,7 @@ void bpcachesave(JSON root) void bpcacheload(JSON root) { + CriticalSectionLocker locker(LockBreakpoints); breakpoints.clear(); const JSON jsonbreakpoints = json_object_get(root, "breakpoints"); if(jsonbreakpoints) @@ -256,5 +267,6 @@ void bpcacheload(JSON root) void bpclear() { + CriticalSectionLocker locker(LockBreakpoints); BreakpointsInfo().swap(breakpoints); } \ No newline at end of file diff --git a/x64_dbg_dbg/patches.cpp b/x64_dbg_dbg/patches.cpp index c116b4e78..5cceca683 100644 --- a/x64_dbg_dbg/patches.cpp +++ b/x64_dbg_dbg/patches.cpp @@ -3,8 +3,9 @@ #include "memory.h" #include "debugger.h" #include "console.h" +#include "threading.h" -PatchesInfo patches; +static PatchesInfo patches; bool patchset(uint addr, unsigned char oldbyte, unsigned char newbyte) { @@ -18,6 +19,7 @@ bool patchset(uint addr, unsigned char oldbyte, unsigned char newbyte) newPatch.oldbyte = oldbyte; newPatch.newbyte = newbyte; uint key = modhashfromva(addr); + CriticalSectionLocker locker(LockPatches); PatchesInfo::iterator found = patches.find(key); if(found != patches.end()) //we found a patch on the specified address { @@ -41,6 +43,7 @@ bool patchget(uint addr, PATCHINFO* patch) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockPatches); PatchesInfo::iterator found = patches.find(modhashfromva(addr)); if(found == patches.end()) //not found return false; @@ -57,6 +60,7 @@ bool patchdel(uint addr, bool restore) { if(!DbgIsDebugging()) return false; + CriticalSectionLocker locker(LockPatches); PatchesInfo::iterator found = patches.find(modhashfromva(addr)); if(found == patches.end()) //not found return false; @@ -76,6 +80,7 @@ void patchdelrange(uint start, uint end, bool restore) return; start -= modbase; end -= modbase; + CriticalSectionLocker locker(LockPatches); PatchesInfo::iterator i = patches.begin(); while(i != patches.end()) { @@ -92,6 +97,7 @@ void patchdelrange(uint start, uint end, bool restore) void patchclear(const char* mod) { + CriticalSectionLocker locker(LockPatches); if(!mod or !*mod) patches.clear(); else @@ -113,6 +119,7 @@ bool patchenum(PATCHINFO* patcheslist, size_t* cbsize) return false; if(!patcheslist && !cbsize) return false; + CriticalSectionLocker locker(LockPatches); if(!patcheslist && cbsize) { *cbsize = patches.size() * sizeof(LOOPSINFO); diff --git a/x64_dbg_dbg/thread.cpp b/x64_dbg_dbg/thread.cpp index cc820f068..fa183b22a 100644 --- a/x64_dbg_dbg/thread.cpp +++ b/x64_dbg_dbg/thread.cpp @@ -2,6 +2,7 @@ #include "console.h" #include "undocumented.h" #include "memory.h" +#include "threading.h" static std::vector threadList; static int threadNum; @@ -18,26 +19,32 @@ void threadcreate(CREATE_THREAD_DEBUG_INFO* CreateThread) *curInfo.threadName = '\0'; if(!threadNum) strcpy(curInfo.threadName, "Main Thread"); + CriticalSectionLocker locker(LockThreads); threadList.push_back(curInfo); threadNum++; + locker.unlock(); //prevent possible deadlocks GuiUpdateThreadView(); } void threadexit(DWORD dwThreadId) { + CriticalSectionLocker locker(LockThreads); for(unsigned int i = 0; i < threadList.size(); i++) if(threadList.at(i).dwThreadId == dwThreadId) { threadList.erase(threadList.begin() + i); break; } + locker.unlock(); //prevent possible deadlocks GuiUpdateThreadView(); } void threadclear() { threadNum = 0; + CriticalSectionLocker locker(LockThreads); std::vector().swap(threadList); + locker.unlock(); //prevent possible deadlocks GuiUpdateThreadView(); } @@ -57,6 +64,7 @@ static DWORD GetThreadLastError(uint tebAddress) void threadgetlist(THREADLIST* list) { + CriticalSectionLocker locker(LockThreads); int count = (int)threadList.size(); list->count = count; if(!count) @@ -81,6 +89,7 @@ void threadgetlist(THREADLIST* list) bool threadisvalid(DWORD dwThreadId) { + CriticalSectionLocker locker(LockThreads); for(unsigned int i = 0; i < threadList.size(); i++) if(threadList.at(i).dwThreadId == dwThreadId) return true; @@ -89,6 +98,7 @@ bool threadisvalid(DWORD dwThreadId) bool threadsetname(DWORD dwThreadId, const char* name) { + CriticalSectionLocker locker(LockThreads); for(unsigned int i = 0; i < threadList.size(); i++) if(threadList.at(i).dwThreadId == dwThreadId) { @@ -102,6 +112,7 @@ bool threadsetname(DWORD dwThreadId, const char* name) HANDLE threadgethandle(DWORD dwThreadId) { + CriticalSectionLocker locker(LockThreads); for(unsigned int i = 0; i < threadList.size(); i++) if(threadList.at(i).dwThreadId == dwThreadId) return threadList.at(i).hThread; @@ -110,6 +121,7 @@ HANDLE threadgethandle(DWORD dwThreadId) DWORD threadgetid(HANDLE hThread) { + CriticalSectionLocker locker(LockThreads); for(unsigned int i = 0; i < threadList.size(); i++) if(threadList.at(i).hThread == hThread) return threadList.at(i).dwThreadId; diff --git a/x64_dbg_dbg/threading.h b/x64_dbg_dbg/threading.h index 0d4414a9a..cc3c15578 100644 --- a/x64_dbg_dbg/threading.h +++ b/x64_dbg_dbg/threading.h @@ -21,6 +21,16 @@ bool waitislocked(WAIT_ID id); enum CriticalSectionLock { LockMemoryPages, + LockVariables, + LockModules, + LockComments, + LockLabels, + LockBookmarks, + LockFunctions, + LockLoops, + LockBreakpoints, + LockPatches, + LockThreads, LockLast }; diff --git a/x64_dbg_dbg/variable.cpp b/x64_dbg_dbg/variable.cpp index 296b4d3a9..f71905a08 100644 --- a/x64_dbg_dbg/variable.cpp +++ b/x64_dbg_dbg/variable.cpp @@ -1,4 +1,5 @@ #include "variable.h" +#include "threading.h" static VariableMap variables; static VAR* vars; @@ -19,6 +20,7 @@ static void varsetvalue(VAR* var, VAR_VALUE* value) static bool varset(const char* name, VAR_VALUE* value, bool setreadonly) { + CriticalSectionLocker locker(LockVariables); String name_; if(*name != '$') name_ = "$"; @@ -36,7 +38,7 @@ static bool varset(const char* name, VAR_VALUE* value, bool setreadonly) void varinit() { - variables.clear(); + varfree(); //General variables varnew("$result\1$res", 0, VAR_SYSTEM); varnew("$result1\1$res1", 0, VAR_SYSTEM); @@ -56,6 +58,7 @@ void varinit() void varfree() { + CriticalSectionLocker locker(LockVariables); variables.clear(); } @@ -66,6 +69,7 @@ VAR* vargetptr() bool varnew(const char* name, uint value, VAR_TYPE type) { + CriticalSectionLocker locker(LockVariables); if(!name) return false; std::vector names = StringUtils::Split(name, '\1'); @@ -96,6 +100,7 @@ bool varnew(const char* name, uint value, VAR_TYPE type) static bool varget(const char* name, VAR_VALUE* value, int* size, VAR_TYPE* type) { + CriticalSectionLocker locker(LockVariables); String name_; if(*name != '$') name_ = "$"; @@ -179,6 +184,7 @@ bool varset(const char* name, const char* string, bool setreadonly) bool vardel(const char* name, bool delsystem) { + CriticalSectionLocker locker(LockVariables); String name_; if(*name != '$') name_ = "$"; @@ -203,6 +209,7 @@ bool vardel(const char* name, bool delsystem) bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype) { + CriticalSectionLocker locker(LockVariables); String name_; if(*name != '$') name_ = "$"; @@ -221,6 +228,7 @@ bool vargettype(const char* name, VAR_TYPE* type, VAR_VALUE_TYPE* valtype) bool varenum(VAR* entries, size_t* cbsize) { + CriticalSectionLocker locker(LockVariables); if(!entries && !cbsize || !variables.size()) return false; if(!entries && cbsize) diff --git a/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters b/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters index 0c76fbf65..5f0ef7ad9 100644 --- a/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters +++ b/x64_dbg_dbg/x64_dbg_dbg.vcxproj.filters @@ -99,12 +99,6 @@ Source Files\Core - - Source Files\Core - - - Source Files\Core - Source Files\Core @@ -168,6 +162,12 @@ Source Files\Utilities + + Source Files\Utilities + + + Source Files\Utilities + @@ -227,9 +227,6 @@ Header Files\Core - - Header Files\Core - Header Files\Core @@ -242,9 +239,6 @@ Header Files\Core - - Header Files\Core - Header Files\Debugger Core @@ -317,5 +311,11 @@ Header Files\Utilities + + Header Files\Utilities + + + Header Files\Utilities + \ No newline at end of file From 5a78857ab8f68e0f6138823bd044f4c1862a88fb Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 9 Dec 2014 01:30:28 +0100 Subject: [PATCH 57/58] GUI: build date in about dialog --- x64_dbg_gui/Project/Src/Gui/MainWindow.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp index f2af2055e..9fd64d461 100644 --- a/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp +++ b/x64_dbg_gui/Project/Src/Gui/MainWindow.cpp @@ -477,7 +477,7 @@ void MainWindow::displayAboutWidget() QString title = "About x32_dbg"; #endif title += QString().sprintf(" v%d", BridgeGetDbgVersion()); - QMessageBox msg(QMessageBox::Information, title, "Website:\nhttp://x64dbg.com\n\nAttribution:\nIcons8 (http://icons8.com)\nYusuke Kamiyamane (http://p.yusukekamiyamane.com)"); + QMessageBox msg(QMessageBox::Information, title, "Website:\nhttp://x64dbg.com\n\nAttribution:\nIcons8 (http://icons8.com)\nYusuke Kamiyamane (http://p.yusukekamiyamane.com)\n\nCompiled on:\n"__DATE__", "__TIME__); msg.setWindowIcon(QIcon(":/icons/images/information.png")); msg.setParent(this, Qt::Dialog); msg.setWindowFlags(msg.windowFlags() & (~Qt::WindowContextHelpButtonHint)); From 52512b8af533e30089ee614fd461ee93fc22df0e Mon Sep 17 00:00:00 2001 From: "Mr. eXoDia" Date: Tue, 9 Dec 2014 11:02:14 +0100 Subject: [PATCH 58/58] DBG: removed some useless functions --- x64_dbg_dbg/_global.cpp | 15 --------------- x64_dbg_dbg/_global.h | 9 +++------ 2 files changed, 3 insertions(+), 21 deletions(-) diff --git a/x64_dbg_dbg/_global.cpp b/x64_dbg_dbg/_global.cpp index b6d390530..fc47cee8d 100644 --- a/x64_dbg_dbg/_global.cpp +++ b/x64_dbg_dbg/_global.cpp @@ -5,21 +5,6 @@ HINSTANCE hInst; char dbbasepath[deflen] = ""; char dbpath[3 * deflen] = ""; -void* emalloc(size_t size) -{ - return emalloc(size, "emalloc:???"); -} - -void* erealloc(void* ptr, size_t size) -{ - return erealloc(ptr, size, "erealloc:???"); -} - -void efree(void* ptr) -{ - efree(ptr, "efree:???"); -} - static int emalloc_count = 0; static char alloctrace[MAX_PATH] = ""; diff --git a/x64_dbg_dbg/_global.h b/x64_dbg_dbg/_global.h index 5ac006066..1f8beea5a 100644 --- a/x64_dbg_dbg/_global.h +++ b/x64_dbg_dbg/_global.h @@ -107,12 +107,9 @@ extern char dbbasepath[deflen]; extern char dbpath[3 * deflen]; //functions -void* emalloc(size_t size); -void* erealloc(void* ptr, size_t size); -void efree(void* ptr); -void* emalloc(size_t size, const char* reason); -void* erealloc(void* ptr, size_t size, const char* reason); -void efree(void* ptr, const char* reason); +void* emalloc(size_t size, const char* reason = "emalloc:???"); +void* erealloc(void* ptr, size_t size, const char* reason = "erealloc:???"); +void efree(void* ptr, const char* reason = "efree:???"); int memleaks(); void setalloctrace(const char* file); bool arraycontains(const char* cmd_list, const char* cmd);