diff --git a/SDK/C/TitanEngine.h b/SDK/C/TitanEngine.h index 58cf38a..c760205 100644 --- a/SDK/C/TitanEngine.h +++ b/SDK/C/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/TitanEngine/TitanEngine.Debugger.Context.cpp b/TitanEngine/TitanEngine.Debugger.Context.cpp index c4850d1..7408102 100644 --- a/TitanEngine/TitanEngine.Debugger.Context.cpp +++ b/TitanEngine/TitanEngine.Debugger.Context.cpp @@ -11,7 +11,7 @@ __declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, voi { CONTEXT DBGContext; memset(&DBGContext, 0, sizeof(CONTEXT)); - DBGContext.ContextFlags = CONTEXT_ALL; + DBGContext.ContextFlags = CONTEXT_ALL | CONTEXT_FLOATING_POINT; if(SuspendThread(hActiveThread) == (DWORD) - 1) return false; @@ -32,6 +32,135 @@ __declspec(dllexport) bool TITCALL GetContextFPUDataEx(HANDLE hActiveThread, voi return false; } +__declspec(dllexport) bool TITCALL GetFullContextDataEx(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_t* titcontext) +{ + ULONG_PTR retValue = 0; + CONTEXT DBGContext; + memset(&DBGContext, 0, sizeof(CONTEXT)); + DBGContext.ContextFlags = CONTEXT_ALL | CONTEXT_FLOATING_POINT | CONTEXT_EXTENDED_REGISTERS; + int i; + + if(SuspendThread(hActiveThread) == (DWORD) - 1) + return false; + + if(!GetThreadContext(hActiveThread, &DBGContext)) + { + ResumeThread(hActiveThread); + return false; + } + ResumeThread(hActiveThread); + + titcontext->eflags = DBGContext.EFlags; + titcontext->dr0 = DBGContext.Dr0; + titcontext->dr1 = DBGContext.Dr1; + titcontext->dr2 = DBGContext.Dr2; + titcontext->dr3 = DBGContext.Dr3; + titcontext->dr6 = DBGContext.Dr6; + titcontext->dr7 = DBGContext.Dr7; + titcontext->gs = (unsigned short) DBGContext.SegGs; + titcontext->fs = (unsigned short) DBGContext.SegFs; + titcontext->es = (unsigned short) DBGContext.SegEs; + titcontext->ds = (unsigned short) DBGContext.SegDs; + titcontext->cs = (unsigned short) DBGContext.SegCs; + titcontext->ss = (unsigned short) DBGContext.SegSs; + +#ifdef _WIN64 //x64 + titcontext->cax = DBGContext.Rax; + titcontext->cbx = DBGContext.Rbx; + titcontext->ccx = DBGContext.Rcx; + titcontext->cdx = DBGContext.Rdx; + titcontext->cdi = DBGContext.Rdi; + titcontext->csi = DBGContext.Rsi; + titcontext->cbp = DBGContext.Rbp; + titcontext->csp = DBGContext.Rsp; + titcontext->cip = DBGContext.Rip; + titcontext->r8 = DBGContext.R8; + titcontext->r9 = DBGContext.R9; + titcontext->r10 = DBGContext.R10; + titcontext->r11 = DBGContext.R11; + titcontext->r12 = DBGContext.R12; + titcontext->r13 = DBGContext.R13; + titcontext->r14 = DBGContext.R14; + titcontext->r15 = DBGContext.R15; + + titcontext->x87fpu.ControlWord = DBGContext.FltSave.ControlWord; + titcontext->x87fpu.StatusWord = DBGContext.FltSave.StatusWord; + titcontext->x87fpu.TagWord = DBGContext.FltSave.TagWord; + titcontext->x87fpu.ErrorSelector = DBGContext.FltSave.ErrorSelector; + titcontext->x87fpu.ErrorOffset = DBGContext.FltSave.ErrorOffset; + titcontext->x87fpu.DataSelector = DBGContext.FltSave.DataSelector; + titcontext->x87fpu.DataOffset = DBGContext.FltSave.DataOffset; + // Skip titcontext->x87fpu.Cr0NpxState + titcontext->MxCsr = DBGContext.FltSave.MxCsr; + + for(i = 0; i < 8; i++) + memcpy(&(titcontext->RegisterArea[i * 10]), & DBGContext.FltSave.FloatRegisters[i], 10); + + for(i = 0; i < 16; i++) + memcpy(& (titcontext->XmmRegisters[i]), & (DBGContext.FltSave.XmmRegisters[i]), sizeof(*titcontext->XmmRegisters)); + +#else //x86 + titcontext->cax = DBGContext.Eax; + titcontext->cbx = DBGContext.Ebx; + titcontext->ccx = DBGContext.Ecx; + titcontext->cdx = DBGContext.Edx; + titcontext->cdi = DBGContext.Edi; + titcontext->csi = DBGContext.Esi; + titcontext->cbp = DBGContext.Ebp; + titcontext->csp = DBGContext.Esp; + titcontext->cip = DBGContext.Eip; + + titcontext->x87fpu.ControlWord = DBGContext.FloatSave.ControlWord; + titcontext->x87fpu.StatusWord = DBGContext.FloatSave.StatusWord; + titcontext->x87fpu.TagWord = DBGContext.FloatSave.TagWord; + titcontext->x87fpu.ErrorSelector = DBGContext.FloatSave.ErrorSelector; + titcontext->x87fpu.ErrorOffset = DBGContext.FloatSave.ErrorOffset; + titcontext->x87fpu.DataSelector = DBGContext.FloatSave.DataSelector; + titcontext->x87fpu.DataOffset = DBGContext.FloatSave.DataOffset; + titcontext->x87fpu.Cr0NpxState = DBGContext.FloatSave.Cr0NpxState; + + memcpy(titcontext->RegisterArea, DBGContext.FloatSave.RegisterArea, 80); + + // MXCSR ExtendedRegisters[24] + titcontext->MxCsr = DBGContext.ExtendedRegisters[24]; + + // for x86 copy the 8 Xmm Registers from ExtendedRegisters[(10+n)*16]; (n is the index of the xmm register) to the XMM register + for(i = 0; i < 8; i++) + memcpy(& (titcontext->XmmRegisters[i]), & DBGContext.ExtendedRegisters[(10 + i) * 16], sizeof(*titcontext->XmmRegisters)); +#endif + +#define GetSTInTOPStackFromStatusWord(StatusWord) ((StatusWord & 0x3800) >> 11) +#define Getx87r0PositionInRegisterArea(STInTopStack) ((8 - STInTopStack) % 8) +#define Calculatex87registerPositionInRegisterArea(x87r0_position, index) (((x87r0_position + index) % 8)) +#define GetRegisterAreaOf87register(register_area, x87r0_position, index) (((char *) register_area) + 10 * Calculatex87registerPositionInRegisterArea(x87r0_position, i) ) +#define GetSTValueFromIndex(x87r0_position, index) ((x87r0_position + index) % 8) + + int STInTopStack = GetSTInTOPStackFromStatusWord(titcontext->x87fpu.StatusWord); + DWORD x87r0_position = Getx87r0PositionInRegisterArea(STInTopStack); + for(i = 0; i < 8; i++) + titcontext->mmx[i] = * ((int64_t*) GetRegisterAreaOf87register(titcontext->RegisterArea, x87r0_position, i)); + + + /* + GET Actual TOP register from StatusWord to order the FPUx87registers like in the FPU internal order. + The TOP field (bits 13-11) is where the FPU keeps track of which of its 80-bit registers is at the TOP. + The register number for the FPU's internal numbering system of the 80-bit registers would be displayed in that field. + When the programmer specifies one of the FPU 80-bit registers ST(x) in an instruction, the FPU adds (modulo 8) the ST number + supplied to the value in this TOP field to determine in which of its registers the required data is located. + */ + /* + int STInTopStack = GetSTInTOPStackFromStatusWord(titcontext->x87fpu.StatusWord); + DWORD x87r0_position = Getx87r0PositionInRegisterArea(STInTopStack); + */ + for(i = 0; i < 8; i++) + { + memcpy(titcontext->x87fpu.x87FPURegister[i].data, GetRegisterAreaOf87register(titcontext->RegisterArea, x87r0_position, i), 10); + titcontext->x87fpu.x87FPURegister[i].st_value = GetSTValueFromIndex(x87r0_position, i); + } + + return true; +} + __declspec(dllexport) ULONG_PTR TITCALL GetContextDataEx(HANDLE hActiveThread, DWORD IndexOfRegister) { ULONG_PTR retValue = 0; @@ -285,7 +414,7 @@ __declspec(dllexport) bool TITCALL SetContextFPUDataEx(HANDLE hActiveThread, voi { CONTEXT DBGContext; memset(&DBGContext, 0, sizeof(CONTEXT)); - DBGContext.ContextFlags = CONTEXT_ALL; + DBGContext.ContextFlags = CONTEXT_ALL | CONTEXT_FLOATING_POINT; if(SuspendThread(hActiveThread) == (DWORD) - 1) return false; diff --git a/TitanEngine/definitions.h b/TitanEngine/definitions.h index 68c12fb..608d039 100644 --- a/TitanEngine/definitions.h +++ b/TitanEngine/definitions.h @@ -179,6 +179,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/TitanEngine/stdafx.h b/TitanEngine/stdafx.h index b2fec93..d5bb54a 100644 --- a/TitanEngine/stdafx.h +++ b/TitanEngine/stdafx.h @@ -27,6 +27,7 @@ #include #include #include +#include //#include #include "ntdll.h" @@ -85,6 +86,74 @@ #define UE_STRUCT_FILE_STATUS_INFO 12 #define UE_STRUCT_FILE_FIX_INFO 13 +#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 { ULONG_PTR BreakPointAddress;