Fix crash with AVX-512 on 32-bit

Closes #25
This commit is contained in:
Duncan Ogilvie 2025-07-04 17:17:01 +02:00
parent f23d23a5f5
commit 02d0be742a
9 changed files with 200 additions and 192 deletions

View File

@ -46,18 +46,18 @@ CRITICAL_SECTION engineStepActiveCr;
DWORD ContextControlFlags = [] DWORD ContextControlFlags = []
{ {
DWORD flags = CONTEXT_CONTROL; DWORD flags = CONTEXT_CONTROL;
typedef BOOL(WINAPI *type_IsWow64Process2)(HANDLE, USHORT*, USHORT*); typedef BOOL(WINAPI * type_IsWow64Process2)(HANDLE, USHORT*, USHORT*);
auto p_IsWow64Process2 = (type_IsWow64Process2)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process2"); auto p_IsWow64Process2 = (type_IsWow64Process2)GetProcAddress(GetModuleHandleW(L"kernel32.dll"), "IsWow64Process2");
if (p_IsWow64Process2) if(p_IsWow64Process2)
{ {
USHORT processMachine = 0; USHORT processMachine = 0;
USHORT nativeMachine = 0; USHORT nativeMachine = 0;
if (p_IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine)) if(p_IsWow64Process2(GetCurrentProcess(), &processMachine, &nativeMachine))
{ {
#ifndef IMAGE_FILE_MACHINE_ARM64 #ifndef IMAGE_FILE_MACHINE_ARM64
#define IMAGE_FILE_MACHINE_ARM64 0xAA64 #define IMAGE_FILE_MACHINE_ARM64 0xAA64
#endif // IMAGE_FILE_MACHINE_ARM64 #endif // IMAGE_FILE_MACHINE_ARM64
if (nativeMachine == IMAGE_FILE_MACHINE_ARM || nativeMachine == IMAGE_FILE_MACHINE_ARM64) if(nativeMachine == IMAGE_FILE_MACHINE_ARM || nativeMachine == IMAGE_FILE_MACHINE_ARM64)
{ {
flags = CONTEXT_ALL; flags = CONTEXT_ALL;
} }

View File

@ -462,7 +462,7 @@ __declspec(dllexport) bool TITCALL SetMemoryBPXEx(ULONG_PTR MemoryStart, SIZE_T
auto bpType = BreakPointBuffer.at(i).BreakPointType; auto bpType = BreakPointBuffer.at(i).BreakPointType;
bool isMem = bpType == UE_MEMORY || bpType == UE_MEMORY_READ || bpType == UE_MEMORY_WRITE || bpType == UE_MEMORY_EXECUTE; bool isMem = bpType == UE_MEMORY || bpType == UE_MEMORY_READ || bpType == UE_MEMORY_WRITE || bpType == UE_MEMORY_EXECUTE;
if (isMem && bpAddr < (MemoryStart + SizeOfMemory) && bpAddr + bpSize > MemoryStart) if(isMem && bpAddr < (MemoryStart + SizeOfMemory) && bpAddr + bpSize > MemoryStart)
{ {
return false; // the place is taken return false; // the place is taken
} }

View File

@ -1054,11 +1054,13 @@ __declspec(dllexport) bool TITCALL GetAVXContext(HANDLE hActiveThread, TITAN_ENG
(1ui64 << (XSTATE_AVX512_ZMM))) (1ui64 << (XSTATE_AVX512_ZMM)))
#endif #endif
static bool SetAVX512ContextFallbackToAVX(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_AVX512_t* titcontext) { static bool SetAVX512ContextFallbackToAVX(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_AVX512_t* titcontext)
{
// Fall back to using AVX and ignore the rest // Fall back to using AVX and ignore the rest
TITAN_ENGINE_CONTEXT_t Avx; TITAN_ENGINE_CONTEXT_t Avx;
memset(&Avx, 0, sizeof(Avx)); memset(&Avx, 0, sizeof(Avx));
for (int i = 0; i < _countof(Avx.YmmRegisters); i++) { for(int i = 0; i < _countof(Avx.YmmRegisters); i++)
{
Avx.YmmRegisters[i] = titcontext->ZmmRegisters[i].Low; Avx.YmmRegisters[i] = titcontext->ZmmRegisters[i].Low;
} }
return SetAVXContext(hActiveThread, &Avx); return SetAVXContext(hActiveThread, &Avx);
@ -1066,11 +1068,11 @@ static bool SetAVX512ContextFallbackToAVX(HANDLE hActiveThread, TITAN_ENGINE_CON
__declspec(dllexport) bool TITCALL SetAVX512Context(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_AVX512_t* titcontext) __declspec(dllexport) bool TITCALL SetAVX512Context(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_AVX512_t* titcontext)
{ {
if (InitXState() == false) if(InitXState() == false)
return false; return false;
DWORD64 FeatureMask = _GetEnabledXStateFeatures(); DWORD64 FeatureMask = _GetEnabledXStateFeatures();
if ((FeatureMask & XSTATE_MASK_AVX512) == 0) if((FeatureMask & XSTATE_MASK_AVX512) == 0)
return SetAVX512ContextFallbackToAVX(hActiveThread, titcontext); return SetAVX512ContextFallbackToAVX(hActiveThread, titcontext);
DWORD ContextSize = 0; DWORD ContextSize = 0;
@ -1079,12 +1081,12 @@ __declspec(dllexport) bool TITCALL SetAVX512Context(HANDLE hActiveThread, TITAN_
NULL, NULL,
&ContextSize); &ContextSize);
if ((Success == TRUE) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) if((Success == TRUE) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
return false; return false;
DynBuf dataBuffer(ContextSize); DynBuf dataBuffer(ContextSize);
PVOID Buffer = dataBuffer.GetPtr(); PVOID Buffer = dataBuffer.GetPtr();
if (Buffer == NULL) if(Buffer == NULL)
return false; return false;
PCONTEXT Context; PCONTEXT Context;
@ -1092,16 +1094,16 @@ __declspec(dllexport) bool TITCALL SetAVX512Context(HANDLE hActiveThread, TITAN_
CONTEXT_ALL | CONTEXT_XSTATE, CONTEXT_ALL | CONTEXT_XSTATE,
&Context, &Context,
&ContextSize); &ContextSize);
if (Success == FALSE) if(Success == FALSE)
return false; return false;
if (_SetXStateFeaturesMask(Context, XSTATE_MASK_AVX | XSTATE_MASK_AVX512) == FALSE) if(_SetXStateFeaturesMask(Context, XSTATE_MASK_AVX | XSTATE_MASK_AVX512) == FALSE)
return SetAVX512ContextFallbackToAVX(hActiveThread, titcontext); return SetAVX512ContextFallbackToAVX(hActiveThread, titcontext);
if (GetThreadContext(hActiveThread, Context) == FALSE) if(GetThreadContext(hActiveThread, Context) == FALSE)
return false; return false;
if (_GetXStateFeaturesMask(Context, &FeatureMask) == FALSE) if(_GetXStateFeaturesMask(Context, &FeatureMask) == FALSE)
return false; return false;
DWORD FeatureLengthSse; DWORD FeatureLengthSse;
@ -1112,36 +1114,38 @@ __declspec(dllexport) bool TITCALL SetAVX512Context(HANDLE hActiveThread, TITAN_
XmmRegister_t* Sse = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_LEGACY_SSE, &FeatureLengthSse); XmmRegister_t* Sse = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_LEGACY_SSE, &FeatureLengthSse);
XmmRegister_t* Avx = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX, &FeatureLengthAvx); XmmRegister_t* Avx = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX, &FeatureLengthAvx);
ULONGLONG* Avx512_KMASK = (ULONGLONG*)_LocateXStateFeature(Context, XSTATE_AVX512_KMASK, &FeatureLengthAvx512_KMASK); ULONGLONG* Avx512_KMASK = (ULONGLONG*)_LocateXStateFeature(Context, XSTATE_AVX512_KMASK, &FeatureLengthAvx512_KMASK);
ZmmRegister_t* Avx512_ZMM = (ZmmRegister_t *)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM, &FeatureLengthAvx512_ZMM); ZmmRegister_t* Avx512_ZMM = (ZmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM, &FeatureLengthAvx512_ZMM);
YmmRegister_t* Avx512_ZMM_H = (YmmRegister_t *)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM_H, &FeatureLengthAvx512_ZMM_H); YmmRegister_t* Avx512_ZMM_H = (YmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM_H, &FeatureLengthAvx512_ZMM_H);
if (Sse != NULL) //If the feature is unsupported by the processor it will return NULL if(Sse != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthSse / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++) for(int i = 0; i < MIN(FeatureLengthSse / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++)
Sse[i] = titcontext->ZmmRegisters[i].Low.Low; Sse[i] = titcontext->ZmmRegisters[i].Low.Low;
} }
if (Avx != NULL) //If the feature is unsupported by the processor it will return NULL if(Avx != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++) for(int i = 0; i < MIN(FeatureLengthAvx / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++)
Avx[i] = titcontext->ZmmRegisters[i].Low.High; Avx[i] = titcontext->ZmmRegisters[i].Low.High;
} }
if (Avx512_ZMM_H != NULL) //If the feature is unsupported by the processor it will return NULL if(Avx512_ZMM_H != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx512_ZMM_H / sizeof(YmmRegister_t), _countof(titcontext->ZmmRegisters)); i++) for(int i = 0; i < MIN(FeatureLengthAvx512_ZMM_H / sizeof(YmmRegister_t), _countof(titcontext->ZmmRegisters)); i++)
Avx512_ZMM_H[i] = titcontext->ZmmRegisters[i].High; Avx512_ZMM_H[i] = titcontext->ZmmRegisters[i].High;
} }
if (Avx512_ZMM != NULL) //If the feature is unsupported by the processor it will return NULL #ifdef _WIN64
if(Avx512_ZMM != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx512_ZMM / sizeof(ZmmRegister_t), _countof(titcontext->ZmmRegisters) - FeatureLengthAvx / sizeof(XmmRegister_t)); i++) for(int i = 0; i < MIN(FeatureLengthAvx512_ZMM / sizeof(ZmmRegister_t), _countof(titcontext->ZmmRegisters) - FeatureLengthAvx / sizeof(XmmRegister_t)); i++)
Avx512_ZMM[i] = titcontext->ZmmRegisters[i + FeatureLengthAvx / sizeof(XmmRegister_t)]; Avx512_ZMM[i] = titcontext->ZmmRegisters[i + FeatureLengthAvx / sizeof(XmmRegister_t)];
} }
#endif // _WIN64
if (Avx512_KMASK != NULL) //If the feature is unsupported by the processor it will return NULL if(Avx512_KMASK != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx512_KMASK / sizeof(ULONGLONG), _countof(titcontext->Opmask)); i++) for(int i = 0; i < MIN(FeatureLengthAvx512_KMASK / sizeof(ULONGLONG), _countof(titcontext->Opmask)); i++)
Avx512_KMASK[i] = titcontext->Opmask[i]; Avx512_KMASK[i] = titcontext->Opmask[i];
} }
@ -1153,23 +1157,25 @@ static bool GetAVX512ContextFallbackToAVX(HANDLE hActiveThread, TITAN_ENGINE_CON
// Fall back to using AVX and fill the rest with 0 // Fall back to using AVX and fill the rest with 0
TITAN_ENGINE_CONTEXT_t Avx; TITAN_ENGINE_CONTEXT_t Avx;
memset(titcontext, 0, sizeof(*titcontext)); memset(titcontext, 0, sizeof(*titcontext));
if (GetAVXContext(hActiveThread, &Avx)) { if(GetAVXContext(hActiveThread, &Avx))
for (int i = 0; i < _countof(Avx.YmmRegisters); i++) {
for(int i = 0; i < _countof(Avx.YmmRegisters); i++)
titcontext->ZmmRegisters[i].Low = Avx.YmmRegisters[i]; titcontext->ZmmRegisters[i].Low = Avx.YmmRegisters[i];
return true; return true;
} }
else { else
{
return false; return false;
} }
} }
__declspec(dllexport) bool TITCALL GetAVX512Context(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_AVX512_t* titcontext) __declspec(dllexport) bool TITCALL GetAVX512Context(HANDLE hActiveThread, TITAN_ENGINE_CONTEXT_AVX512_t* titcontext)
{ {
if (InitXState() == false) if(InitXState() == false)
return false; return false;
DWORD64 FeatureMask = _GetEnabledXStateFeatures(); DWORD64 FeatureMask = _GetEnabledXStateFeatures();
if ((FeatureMask & XSTATE_MASK_AVX512) == 0) //XSTATE_MASK_AVX512 if((FeatureMask & XSTATE_MASK_AVX512) == 0) //XSTATE_MASK_AVX512
return GetAVX512ContextFallbackToAVX(hActiveThread, titcontext); return GetAVX512ContextFallbackToAVX(hActiveThread, titcontext);
DWORD ContextSize = 0; DWORD ContextSize = 0;
@ -1178,12 +1184,12 @@ __declspec(dllexport) bool TITCALL GetAVX512Context(HANDLE hActiveThread, TITAN_
NULL, NULL,
&ContextSize); &ContextSize);
if ((Success == TRUE) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER)) if((Success == TRUE) || (GetLastError() != ERROR_INSUFFICIENT_BUFFER))
return false; return false;
DynBuf dataBuffer(ContextSize); DynBuf dataBuffer(ContextSize);
PVOID Buffer = dataBuffer.GetPtr(); PVOID Buffer = dataBuffer.GetPtr();
if (Buffer == NULL) if(Buffer == NULL)
return false; return false;
PCONTEXT Context; PCONTEXT Context;
@ -1191,16 +1197,16 @@ __declspec(dllexport) bool TITCALL GetAVX512Context(HANDLE hActiveThread, TITAN_
CONTEXT_ALL | CONTEXT_XSTATE, CONTEXT_ALL | CONTEXT_XSTATE,
&Context, &Context,
&ContextSize); &ContextSize);
if (Success == FALSE) if(Success == FALSE)
return false; return false;
if (_SetXStateFeaturesMask(Context, XSTATE_MASK_AVX | XSTATE_MASK_AVX512) == FALSE) if(_SetXStateFeaturesMask(Context, XSTATE_MASK_AVX | XSTATE_MASK_AVX512) == FALSE)
return GetAVX512ContextFallbackToAVX(hActiveThread, titcontext); return GetAVX512ContextFallbackToAVX(hActiveThread, titcontext);
if (GetThreadContext(hActiveThread, Context) == FALSE) if(GetThreadContext(hActiveThread, Context) == FALSE)
return false; return false;
if (_GetXStateFeaturesMask(Context, &FeatureMask) == FALSE) if(_GetXStateFeaturesMask(Context, &FeatureMask) == FALSE)
return false; return false;
DWORD FeatureLengthSse; DWORD FeatureLengthSse;
@ -1211,36 +1217,38 @@ __declspec(dllexport) bool TITCALL GetAVX512Context(HANDLE hActiveThread, TITAN_
XmmRegister_t* Sse = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_LEGACY_SSE, &FeatureLengthSse); XmmRegister_t* Sse = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_LEGACY_SSE, &FeatureLengthSse);
XmmRegister_t* Avx = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX, &FeatureLengthAvx); XmmRegister_t* Avx = (XmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX, &FeatureLengthAvx);
ULONGLONG* Avx512_KMASK = (ULONGLONG*)_LocateXStateFeature(Context, XSTATE_AVX512_KMASK, &FeatureLengthAvx512_KMASK); ULONGLONG* Avx512_KMASK = (ULONGLONG*)_LocateXStateFeature(Context, XSTATE_AVX512_KMASK, &FeatureLengthAvx512_KMASK);
ZmmRegister_t* Avx512_ZMM = (ZmmRegister_t *)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM, &FeatureLengthAvx512_ZMM); ZmmRegister_t* Avx512_ZMM = (ZmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM, &FeatureLengthAvx512_ZMM);
YmmRegister_t* Avx512_ZMM_H = (YmmRegister_t *)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM_H, &FeatureLengthAvx512_ZMM_H); YmmRegister_t* Avx512_ZMM_H = (YmmRegister_t*)_LocateXStateFeature(Context, XSTATE_AVX512_ZMM_H, &FeatureLengthAvx512_ZMM_H);
if (Sse != NULL) //If the feature is unsupported by the processor it will return NULL if(Sse != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthSse / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++) for(int i = 0; i < MIN(FeatureLengthSse / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++)
titcontext->ZmmRegisters[i].Low.Low = Sse[i]; titcontext->ZmmRegisters[i].Low.Low = Sse[i];
} }
if (Avx != NULL) //If the feature is unsupported by the processor it will return NULL if(Avx != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++) for(int i = 0; i < MIN(FeatureLengthAvx / sizeof(XmmRegister_t), _countof(titcontext->ZmmRegisters)); i++)
titcontext->ZmmRegisters[i].Low.High = Avx[i]; titcontext->ZmmRegisters[i].Low.High = Avx[i];
} }
if (Avx512_ZMM_H != NULL) //If the feature is unsupported by the processor it will return NULL if(Avx512_ZMM_H != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx512_ZMM_H / sizeof(YmmRegister_t), _countof(titcontext->ZmmRegisters)); i++) for(int i = 0; i < MIN(FeatureLengthAvx512_ZMM_H / sizeof(YmmRegister_t), _countof(titcontext->ZmmRegisters)); i++)
titcontext->ZmmRegisters[i].High = Avx512_ZMM_H[i]; titcontext->ZmmRegisters[i].High = Avx512_ZMM_H[i];
} }
if (Avx512_ZMM != NULL) //If the feature is unsupported by the processor it will return NULL #ifdef _WIN64
if(Avx512_ZMM != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx512_ZMM / sizeof(ZmmRegister_t), _countof(titcontext->ZmmRegisters) - FeatureLengthAvx / sizeof(XmmRegister_t)); i++) for(int i = 0; i < MIN(FeatureLengthAvx512_ZMM / sizeof(ZmmRegister_t), _countof(titcontext->ZmmRegisters) - FeatureLengthAvx / sizeof(XmmRegister_t)); i++)
titcontext->ZmmRegisters[i + FeatureLengthAvx / sizeof(XmmRegister_t)] = Avx512_ZMM[i]; titcontext->ZmmRegisters[i + FeatureLengthAvx / sizeof(XmmRegister_t)] = Avx512_ZMM[i];
} }
#endif // _WIN64
if (Avx512_KMASK != NULL) //If the feature is unsupported by the processor it will return NULL if(Avx512_KMASK != NULL) //If the feature is unsupported by the processor it will return NULL
{ {
for (int i = 0; i < MIN(FeatureLengthAvx512_KMASK / sizeof(ULONGLONG), _countof(titcontext->Opmask)); i++) for(int i = 0; i < MIN(FeatureLengthAvx512_KMASK / sizeof(ULONGLONG), _countof(titcontext->Opmask)); i++)
titcontext->Opmask[i] = Avx512_KMASK[i]; titcontext->Opmask[i] = Avx512_KMASK[i];
} }

View File

@ -38,15 +38,15 @@ __declspec(dllexport) void TITCALL ForceClose()
__declspec(dllexport) void TITCALL StepInto(LPVOID StepCallBack) __declspec(dllexport) void TITCALL StepInto(LPVOID StepCallBack)
{ {
EnterCriticalSection(&engineStepActiveCr); EnterCriticalSection(&engineStepActiveCr);
if (!engineStepActive) if(!engineStepActive)
{ {
ULONG_PTR ueCurrentPosition = GetContextData(UE_CIP); ULONG_PTR ueCurrentPosition = GetContextData(UE_CIP);
unsigned char instr[16]; unsigned char instr[16];
MemoryReadSafe(dbgProcessInformation.hProcess, (void*)ueCurrentPosition, instr, sizeof(instr), 0); MemoryReadSafe(dbgProcessInformation.hProcess, (void*)ueCurrentPosition, instr, sizeof(instr), 0);
char* DisassembledString = (char*)StaticDisassembleEx(ueCurrentPosition, (LPVOID)instr); char* DisassembledString = (char*)StaticDisassembleEx(ueCurrentPosition, (LPVOID)instr);
if (strstr(DisassembledString, "PUSHF")) if(strstr(DisassembledString, "PUSHF"))
StepOver(StepCallBack); StepOver(StepCallBack);
else if (strstr(DisassembledString, "POP SS") || strstr(DisassembledString, "MOV SS")) //prevent the 'PUSH SS', 'POP SS' step trick else if(strstr(DisassembledString, "POP SS") || strstr(DisassembledString, "MOV SS")) //prevent the 'PUSH SS', 'POP SS' step trick
{ {
ueCurrentPosition += StaticLengthDisassemble((void*)instr); ueCurrentPosition += StaticLengthDisassemble((void*)instr);
SetBPX(ueCurrentPosition, UE_BREAKPOINT_TYPE_INT3 + UE_SINGLESHOOT, StepCallBack); SetBPX(ueCurrentPosition, UE_BREAKPOINT_TYPE_INT3 + UE_SINGLESHOOT, StepCallBack);

View File

@ -16,12 +16,12 @@
static void engineStep() static void engineStep()
{ {
EnterCriticalSection(&engineStepActiveCr); EnterCriticalSection(&engineStepActiveCr);
if (engineStepActive) if(engineStepActive)
{ {
DBGCode = DBG_CONTINUE; DBGCode = DBG_CONTINUE;
if (engineStepCount == 0) if(engineStepCount == 0)
{ {
typedef void(TITCALL* fCustomBreakPoint)(void); typedef void(TITCALL * fCustomBreakPoint)(void);
auto cbStep = fCustomBreakPoint(engineStepCallBack); auto cbStep = fCustomBreakPoint(engineStepCallBack);
engineStepActive = false; engineStepActive = false;
engineStepCallBack = NULL; engineStepCallBack = NULL;
@ -537,7 +537,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
CONTEXT myDBGContext; CONTEXT myDBGContext;
myDBGContext.ContextFlags = ContextControlFlags; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
if (FoundBreakPoint.BreakPointType != UE_SINGLESHOOT) if(FoundBreakPoint.BreakPointType != UE_SINGLESHOOT)
{ {
myDBGContext.EFlags |= UE_TRAP_FLAG; myDBGContext.EFlags |= UE_TRAP_FLAG;
synchronizedStep = true; synchronizedStep = true;
@ -1104,7 +1104,7 @@ __declspec(dllexport) void TITCALL DebugLoop()
CONTEXT myDBGContext; CONTEXT myDBGContext;
myDBGContext.ContextFlags = ContextControlFlags; myDBGContext.ContextFlags = ContextControlFlags;
GetThreadContext(hActiveThread, &myDBGContext); GetThreadContext(hActiveThread, &myDBGContext);
if (FoundBreakPoint.BreakPointType != UE_SINGLESHOOT) if(FoundBreakPoint.BreakPointType != UE_SINGLESHOOT)
{ {
myDBGContext.EFlags |= UE_TRAP_FLAG; myDBGContext.EFlags |= UE_TRAP_FLAG;
synchronizedStep = true; synchronizedStep = true;
@ -1285,10 +1285,10 @@ __declspec(dllexport) void TITCALL DebugLoop()
continue; continue;
// Check if the thread is already suspended // Check if the thread is already suspended
if (SuspendedThreads.count(Thread.dwThreadId) != 0) if(SuspendedThreads.count(Thread.dwThreadId) != 0)
continue; continue;
if (SuspendThread(Thread.hThread) != -1) if(SuspendThread(Thread.hThread) != -1)
SuspendedThreads.emplace(Thread.dwThreadId, Thread); SuspendedThreads.emplace(Thread.dwThreadId, Thread);
} }
} }

View File

@ -156,31 +156,31 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
{ {
bool success = false; bool success = false;
auto hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); auto hFile = CreateFileW(szFileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (hFile != INVALID_HANDLE_VALUE) if(hFile != INVALID_HANDLE_VALUE)
{ {
// Retrieve image base and entry point // Retrieve image base and entry point
DebugModuleImageBase = GetPE32DataW(szFileName, 0, UE_IMAGEBASE); DebugModuleImageBase = GetPE32DataW(szFileName, 0, UE_IMAGEBASE);
DebugModuleEntryPoint = GetPE32DataW(szFileName, 0, UE_OEP); DebugModuleEntryPoint = GetPE32DataW(szFileName, 0, UE_OEP);
auto hMapping = CreateFileMappingW(hFile, nullptr, SEC_IMAGE | PAGE_READONLY, 0, 0, nullptr); auto hMapping = CreateFileMappingW(hFile, nullptr, SEC_IMAGE | PAGE_READONLY, 0, 0, nullptr);
if (hMapping) if(hMapping)
{ {
CONTEXT ctx; CONTEXT ctx;
ctx.ContextFlags = CONTEXT_ALL; ctx.ContextFlags = CONTEXT_ALL;
if (GetThreadContext(pi.hThread, &ctx)) if(GetThreadContext(pi.hThread, &ctx))
{ {
PVOID imageBase; PVOID imageBase;
// TODO: support wow64 processes // TODO: support wow64 processes
#ifdef _WIN64 #ifdef _WIN64
auto& pebRegister = ctx.Rdx; auto & pebRegister = ctx.Rdx;
auto& entryPointRegister = ctx.Rcx; auto & entryPointRegister = ctx.Rcx;
#else #else
auto& pebRegister = ctx.Ebx; auto & pebRegister = ctx.Ebx;
auto& entryPointRegister = ctx.Eax; auto & entryPointRegister = ctx.Eax;
#endif // _WIN64 #endif // _WIN64
if (ReadProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr)) if(ReadProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr))
{ {
if (ULONG_PTR(imageBase) == DebugModuleImageBase) if(ULONG_PTR(imageBase) == DebugModuleImageBase)
{ {
// Already at the right base // Already at the right base
success = true; success = true;
@ -188,32 +188,32 @@ static bool HollowProcessWithoutASLR(const wchar_t* szFileName, PROCESS_INFORMAT
else else
{ {
auto status = NtUnmapViewOfSection(pi.hProcess, imageBase); auto status = NtUnmapViewOfSection(pi.hProcess, imageBase);
if (status == STATUS_SUCCESS) if(status == STATUS_SUCCESS)
{ {
SIZE_T viewSize = 0; SIZE_T viewSize = 0;
imageBase = PVOID(DebugModuleImageBase); imageBase = PVOID(DebugModuleImageBase);
status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY); status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY);
if (status == STATUS_CONFLICTING_ADDRESSES) if(status == STATUS_CONFLICTING_ADDRESSES)
{ {
// Remap in a random location (otherwise the process will crash) // Remap in a random location (otherwise the process will crash)
imageBase = 0; imageBase = 0;
status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY); status = NtMapViewOfSection(hMapping, pi.hProcess, &imageBase, 0, 0, nullptr, &viewSize, ViewUnmap, 0, PAGE_READONLY);
} }
if (status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE) if(status == STATUS_SUCCESS || status == STATUS_IMAGE_NOT_AT_BASE)
{ {
auto pebOk = WriteProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr); auto pebOk = WriteProcessMemory(pi.hProcess, (char*)pebRegister + offsetof(PEB, ImageBaseAddress), &imageBase, sizeof(PVOID), nullptr);
auto relocatedOk = RelocateImage(pi.hProcess, imageBase, viewSize); auto relocatedOk = RelocateImage(pi.hProcess, imageBase, viewSize);
if (pebOk && relocatedOk) if(pebOk && relocatedOk)
{ {
auto expectedBase = DebugModuleImageBase == ULONG_PTR(imageBase); auto expectedBase = DebugModuleImageBase == ULONG_PTR(imageBase);
DebugModuleImageBase = ULONG_PTR(imageBase); DebugModuleImageBase = ULONG_PTR(imageBase);
entryPointRegister = DebugModuleImageBase + DebugModuleEntryPoint; entryPointRegister = DebugModuleImageBase + DebugModuleEntryPoint;
if (SetThreadContext(pi.hThread, &ctx)) if(SetThreadContext(pi.hThread, &ctx))
{ {
success = expectedBase; success = expectedBase;
#ifndef _WIN64 #ifndef _WIN64
// For Wow64 processes, also adjust the 64-bit PEB // For Wow64 processes, also adjust the 64-bit PEB
if (IsThisProcessWow64() && !WriteProcessMemory(pi.hProcess, (char*)pebRegister - 0x1000 + 0x10, &imageBase, sizeof(PVOID), nullptr)) if(IsThisProcessWow64() && !WriteProcessMemory(pi.hProcess, (char*)pebRegister - 0x1000 + 0x10, &imageBase, sizeof(PVOID), nullptr))
success = false; success = false;
#endif // _WIN64 #endif // _WIN64
} }
@ -286,11 +286,11 @@ retry_no_aslr:
{ {
if(engineDisableAslr) if(engineDisableAslr)
{ {
if (!HollowProcessWithoutASLR(szFileName, dbgProcessInformation)) if(!HollowProcessWithoutASLR(szFileName, dbgProcessInformation))
{ {
TerminateThread(dbgProcessInformation.hThread, STATUS_CONFLICTING_ADDRESSES); TerminateThread(dbgProcessInformation.hThread, STATUS_CONFLICTING_ADDRESSES);
TerminateProcess(dbgProcessInformation.hProcess, STATUS_CONFLICTING_ADDRESSES); TerminateProcess(dbgProcessInformation.hProcess, STATUS_CONFLICTING_ADDRESSES);
if (retries++ < 10) if(retries++ < 10)
goto retry_no_aslr; goto retry_no_aslr;
memset(&dbgProcessInformation, 0, sizeof(PROCESS_INFORMATION)); memset(&dbgProcessInformation, 0, sizeof(PROCESS_INFORMATION));
return nullptr; return nullptr;

View File

@ -51,7 +51,7 @@ __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool Vari
{ {
engineDisableAslr = VariableSet; engineDisableAslr = VariableSet;
} }
else if (VariableId == UE_ENGINE_SAFE_STEP) else if(VariableId == UE_ENGINE_SAFE_STEP)
{ {
engineSafeStep = VariableSet; engineSafeStep = VariableSet;
} }