mirror of https://github.com/x64dbg/GleeBug
Clean up TTD APIs
This commit is contained in:
parent
fc2d0a2678
commit
4276bfa2f7
|
|
@ -11,6 +11,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef void(TITCALL* TITANCBSTEP)();
|
typedef void(TITCALL* TITANCBSTEP)();
|
||||||
|
typedef void(TITCALL* TITANCBPAUSE)();
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
|
@ -63,6 +64,8 @@ enum TitanSessionCapability : uint64_t
|
||||||
UE_SESSION_CAP_NATIVE_HANDLES = 1ull << 12,
|
UE_SESSION_CAP_NATIVE_HANDLES = 1ull << 12,
|
||||||
UE_SESSION_CAP_EXCEPTION_CONTINUE = 1ull << 13,
|
UE_SESSION_CAP_EXCEPTION_CONTINUE = 1ull << 13,
|
||||||
UE_SESSION_CAP_TIMELINE_STATE = 1ull << 14,
|
UE_SESSION_CAP_TIMELINE_STATE = 1ull << 14,
|
||||||
|
UE_SESSION_CAP_PAUSE_EXECUTION = 1ull << 16,
|
||||||
|
UE_SESSION_CAP_NAVIGABLE_PROCESS_EXIT = 1ull << 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -103,6 +106,14 @@ typedef struct
|
||||||
#define UE_ENGINE_RESET_CUSTOM_HANDLER 7
|
#define UE_ENGINE_RESET_CUSTOM_HANDLER 7
|
||||||
#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8
|
#define UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK 8
|
||||||
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
||||||
|
#define UE_ENGINE_WOW64_SINGLE_STEP_WORKAROUND 14
|
||||||
|
|
||||||
|
enum TitanPausePolicy
|
||||||
|
{
|
||||||
|
UE_PAUSE_POLICY_NONINVASIVE = 0,
|
||||||
|
UE_PAUSE_POLICY_STANDARD = 1,
|
||||||
|
UE_PAUSE_POLICY_AGGRESSIVE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
#define UE_OPTION_REMOVEALL 1
|
#define UE_OPTION_REMOVEALL 1
|
||||||
#define UE_OPTION_DISABLEALL 2
|
#define UE_OPTION_DISABLEALL 2
|
||||||
|
|
@ -896,8 +907,8 @@ __declspec(dllexport) bool TITCALL GetSessionInfo(TITAN_SESSION_INFO* SessionInf
|
||||||
__declspec(dllexport) bool TITCALL ReplayGetPosition(TITAN_REPLAY_POSITION* Position);
|
__declspec(dllexport) bool TITCALL ReplayGetPosition(TITAN_REPLAY_POSITION* Position);
|
||||||
__declspec(dllexport) bool TITCALL ReplayGetExtent(TITAN_REPLAY_POSITION* First, TITAN_REPLAY_POSITION* Last);
|
__declspec(dllexport) bool TITCALL ReplayGetExtent(TITAN_REPLAY_POSITION* First, TITAN_REPLAY_POSITION* Last);
|
||||||
__declspec(dllexport) bool TITCALL ReplaySetPosition(const TITAN_REPLAY_POSITION* Position);
|
__declspec(dllexport) bool TITCALL ReplaySetPosition(const TITAN_REPLAY_POSITION* Position);
|
||||||
__declspec(dllexport) bool TITCALL ReplayRun(bool Reverse);
|
__declspec(dllexport) bool TITCALL ReplayRunBack();
|
||||||
__declspec(dllexport) bool TITCALL ReplayStep(bool Reverse, bool StepOver, TITANCBSTEP StepCallBack);
|
__declspec(dllexport) bool TITCALL ReplayStepBack(TITANCBSTEP StepCallBack);
|
||||||
__declspec(dllexport) void* TITCALL InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack);
|
__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 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 InitDLLDebug(const char* szFileName, bool ReserveModuleBase, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack);
|
||||||
|
|
@ -1096,7 +1107,7 @@ __declspec(dllexport) bool TITCALL TitanGetModulePathW(HANDLE hProcess, ULONG_PT
|
||||||
__declspec(dllexport) bool TITCALL TitanCloseHandle(HANDLE hEngineHandle);
|
__declspec(dllexport) bool TITCALL TitanCloseHandle(HANDLE hEngineHandle);
|
||||||
__declspec(dllexport) bool TITCALL ProcessIsWow64(HANDLE hProcess, PBOOL isWow64);
|
__declspec(dllexport) bool TITCALL ProcessIsWow64(HANDLE hProcess, PBOOL isWow64);
|
||||||
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode);
|
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode);
|
||||||
__declspec(dllexport) bool TITCALL TitanDebugBreakProcess(HANDLE hProcess);
|
__declspec(dllexport) bool TITCALL RequestPause(TitanPausePolicy MaximumPolicy, TITANCBPAUSE PauseCallback);
|
||||||
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId);
|
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId);
|
||||||
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread);
|
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread);
|
||||||
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread);
|
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread);
|
||||||
|
|
|
||||||
|
|
@ -69,13 +69,13 @@ __declspec(dllexport) bool TITCALL ReplaySetPosition(const TITAN_REPLAY_POSITION
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL ReplayRun(bool Reverse)
|
__declspec(dllexport) bool TITCALL ReplayRunBack()
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
SetLastError(ERROR_NOT_SUPPORTED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL ReplayStep(bool Reverse, bool StepOver, TITANCBSTEP StepCallBack)
|
__declspec(dllexport) bool TITCALL ReplayStepBack(TITANCBSTEP StepCallBack)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
SetLastError(ERROR_NOT_SUPPORTED);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -241,7 +241,14 @@ __declspec(dllexport) bool TITCALL ProcessIsWow64(HANDLE hProcess, PBOOL isWow64
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode) { return !!TerminateProcess(hProcess, exitCode); }
|
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode) { return !!TerminateProcess(hProcess, exitCode); }
|
||||||
__declspec(dllexport) bool TITCALL TitanDebugBreakProcess(HANDLE hProcess) { return !!DebugBreakProcess(hProcess); }
|
__declspec(dllexport) bool TITCALL RequestPause(TitanPausePolicy MaximumPolicy, TITANCBPAUSE PauseCallback)
|
||||||
|
{
|
||||||
|
if(MaximumPolicy < UE_PAUSE_POLICY_NONINVASIVE || MaximumPolicy > UE_PAUSE_POLICY_AGGRESSIVE || !PauseCallback)
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
else
|
||||||
|
SetLastError(ERROR_NOT_SUPPORTED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId) { return CreateRemoteThread(hProcess, nullptr, 0, start, argument, creationFlags, threadId); }
|
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId) { return CreateRemoteThread(hProcess, nullptr, 0, start, argument, creationFlags, threadId); }
|
||||||
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread) { return SuspendThread(hThread); }
|
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread) { return SuspendThread(hThread); }
|
||||||
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread) { return ResumeThread(hThread); }
|
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread) { return ResumeThread(hThread); }
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,7 @@
|
||||||
#include "PEB.h"
|
#include "PEB.h"
|
||||||
#include "Global.Engine.Context.h"
|
#include "Global.Engine.Context.h"
|
||||||
#include "Hider.h"
|
#include "Hider.h"
|
||||||
|
#include <TlHelp32.h>
|
||||||
|
|
||||||
// Related to floating x87 registers
|
// Related to floating x87 registers
|
||||||
#define GetSTInTOPStackFromStatusWord(StatusWord) ((StatusWord & 0x3800) >> 11)
|
#define GetSTInTOPStackFromStatusWord(StatusWord) ((StatusWord & 0x3800) >> 11)
|
||||||
|
|
@ -26,6 +27,7 @@ public:
|
||||||
//Debugger
|
//Debugger
|
||||||
PROCESS_INFORMATION* InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder)
|
PROCESS_INFORMATION* InitDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder)
|
||||||
{
|
{
|
||||||
|
cancelPause();
|
||||||
mCbATTACHBREAKPOINT = nullptr;
|
mCbATTACHBREAKPOINT = nullptr;
|
||||||
if(!Init(szFileName, szCommandLine, szCurrentFolder))
|
if(!Init(szFileName, szCommandLine, szCurrentFolder))
|
||||||
return nullptr;
|
return nullptr;
|
||||||
|
|
@ -62,11 +64,13 @@ public:
|
||||||
|
|
||||||
bool StopDebug()
|
bool StopDebug()
|
||||||
{
|
{
|
||||||
|
cancelPause();
|
||||||
return Stop();
|
return Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
|
bool AttachDebugger(DWORD ProcessId, bool KillOnExit, LPVOID DebugInfo, LPVOID CallBack)
|
||||||
{
|
{
|
||||||
|
cancelPause();
|
||||||
if(!Attach(ProcessId))
|
if(!Attach(ProcessId))
|
||||||
return false;
|
return false;
|
||||||
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
|
mCbATTACHBREAKPOINT = STEPCALLBACK(CallBack);
|
||||||
|
|
@ -191,6 +195,84 @@ public:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RequestPause(TitanPausePolicy MaximumPolicy, TITANCBPAUSE PauseCallback)
|
||||||
|
{
|
||||||
|
if(MaximumPolicy < UE_PAUSE_POLICY_NONINVASIVE || MaximumPolicy > UE_PAUSE_POLICY_AGGRESSIVE ||
|
||||||
|
!PauseCallback || !mProcess || !mThread || !mMainProcess.hProcess)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_INVALID_PARAMETER);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool escalate = false;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
if(mPauseCallback)
|
||||||
|
{
|
||||||
|
escalate = MaximumPolicy == UE_PAUSE_POLICY_AGGRESSIVE && !mPauseBreakInExpected &&
|
||||||
|
GetTickCount64() - mPauseRequestTime >= 2000;
|
||||||
|
if(!escalate)
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if(MaximumPolicy == UE_PAUSE_POLICY_NONINVASIVE)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_NOT_SUPPORTED);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
mPauseCallback = PauseCallback;
|
||||||
|
mPauseRequestTime = GetTickCount64();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(escalate)
|
||||||
|
{
|
||||||
|
requestPauseBreakIn(); // The current-IP request remains pending on failure.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto thread = mAttachedToProcess ? mMainProcess.hThread : mThread->hThread;
|
||||||
|
auto threadId = mAttachedToProcess ? mMainProcess.dwThreadId : mThread->dwThreadId;
|
||||||
|
auto previousSuspendCount = SuspendThread(thread);
|
||||||
|
if(previousSuspendCount != 0)
|
||||||
|
{
|
||||||
|
if(previousSuspendCount != (DWORD)-1)
|
||||||
|
ResumeThread(thread);
|
||||||
|
if(MaximumPolicy == UE_PAUSE_POLICY_AGGRESSIVE && requestPauseBreakIn())
|
||||||
|
return true;
|
||||||
|
cancelPause();
|
||||||
|
SetLastError(ERROR_BUSY);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
CONTEXT context = {};
|
||||||
|
context.ContextFlags = CONTEXT_CONTROL;
|
||||||
|
bool armed = GetThreadContext(thread, &context) != FALSE;
|
||||||
|
#ifdef _WIN64
|
||||||
|
auto cip = (ULONG_PTR)context.Rip;
|
||||||
|
#else
|
||||||
|
auto cip = (ULONG_PTR)context.Eip;
|
||||||
|
#endif
|
||||||
|
if(armed)
|
||||||
|
{
|
||||||
|
armed = mProcess->SetBreakpoint(cip, [this](const BreakpointInfo &)
|
||||||
|
{
|
||||||
|
completePause();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
if(armed)
|
||||||
|
PostThreadMessageW(threadId, WM_NULL, 0, 0);
|
||||||
|
auto resumed = ResumeThread(thread) != (DWORD)-1;
|
||||||
|
if(armed && resumed)
|
||||||
|
return true;
|
||||||
|
if(armed)
|
||||||
|
mProcess->DeleteBreakpoint(cip);
|
||||||
|
if(MaximumPolicy == UE_PAUSE_POLICY_AGGRESSIVE && requestPauseBreakIn())
|
||||||
|
return true;
|
||||||
|
cancelPause();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
void SetEngineVariable(DWORD VariableId, bool VariableSet)
|
void SetEngineVariable(DWORD VariableId, bool VariableSet)
|
||||||
{
|
{
|
||||||
switch(VariableId)
|
switch(VariableId)
|
||||||
|
|
@ -207,6 +289,9 @@ public:
|
||||||
case UE_ENGINE_NO_CONSOLE_WINDOW:
|
case UE_ENGINE_NO_CONSOLE_WINDOW:
|
||||||
mNoConsoleWindow = VariableSet;
|
mNoConsoleWindow = VariableSet;
|
||||||
break;
|
break;
|
||||||
|
case UE_ENGINE_WOW64_SINGLE_STEP_WORKAROUND:
|
||||||
|
mWow64SingleStepWorkaround = VariableSet;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -334,8 +419,24 @@ public:
|
||||||
|
|
||||||
void StepInto(LPVOID CallBack)
|
void StepInto(LPVOID CallBack)
|
||||||
{
|
{
|
||||||
if(!mThread || !CallBack)
|
if(!mThread || !mProcess || !CallBack)
|
||||||
return;
|
return;
|
||||||
|
#ifndef _WIN64
|
||||||
|
if(mWow64SingleStepWorkaround)
|
||||||
|
{
|
||||||
|
unsigned char data[7] = {};
|
||||||
|
auto cip = GetContextDataEx(mThread->hThread, UE_CIP);
|
||||||
|
if(mProcess->MemReadSafe(cip, data, sizeof(data), nullptr) &&
|
||||||
|
data[0] == 0xEA && data[5] == 0x33 && data[6] == 0x00)
|
||||||
|
{
|
||||||
|
ULONG_PTR returnAddress = 0;
|
||||||
|
auto csp = GetContextDataEx(mThread->hThread, UE_CSP);
|
||||||
|
if(mProcess->MemReadSafe(csp, &returnAddress, sizeof(returnAddress), nullptr) &&
|
||||||
|
SetBPX(returnAddress, UE_SINGLESHOOT, CallBack))
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
mThread->StepInto(STEPCALLBACK(CallBack));
|
mThread->StepInto(STEPCALLBACK(CallBack));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -910,6 +1011,12 @@ protected:
|
||||||
|
|
||||||
void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const Thread & thread) override
|
void cbCreateThreadEvent(const CREATE_THREAD_DEBUG_INFO & createThread, const Thread & thread) override
|
||||||
{
|
{
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
if(mPauseBreakInExpected && mPauseBreakInStart &&
|
||||||
|
(ULONG_PTR)createThread.lpStartAddress == mPauseBreakInStart)
|
||||||
|
mPauseBreakInThreadId = thread.dwThreadId;
|
||||||
|
}
|
||||||
if(mCbCREATETHREAD)
|
if(mCbCREATETHREAD)
|
||||||
mCbCREATETHREAD(&createThread);
|
mCbCREATETHREAD(&createThread);
|
||||||
}
|
}
|
||||||
|
|
@ -932,6 +1039,23 @@ protected:
|
||||||
mCbUNLOADDLL(&unloadDll);
|
mCbUNLOADDLL(&unloadDll);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cbExceptionEvent(const EXCEPTION_DEBUG_INFO & exceptionInfo) override
|
||||||
|
{
|
||||||
|
bool pauseBreakIn = false;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
pauseBreakIn = mPauseBreakInExpected && mThread && mPauseBreakInThreadId &&
|
||||||
|
mThread->dwThreadId == mPauseBreakInThreadId &&
|
||||||
|
(exceptionInfo.ExceptionRecord.ExceptionCode == STATUS_BREAKPOINT ||
|
||||||
|
exceptionInfo.ExceptionRecord.ExceptionCode == STATUS_WX86_BREAKPOINT);
|
||||||
|
}
|
||||||
|
if(pauseBreakIn)
|
||||||
|
{
|
||||||
|
mContinueStatus = DBG_CONTINUE;
|
||||||
|
completePause();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, bool firstChance) override
|
void cbUnhandledException(const EXCEPTION_RECORD & exceptionRecord, bool firstChance) override
|
||||||
{
|
{
|
||||||
if(mCbUNHANDLEDEXCEPTION)
|
if(mCbUNHANDLEDEXCEPTION)
|
||||||
|
|
@ -967,6 +1091,87 @@ protected:
|
||||||
}
|
}
|
||||||
|
|
||||||
private: //functions
|
private: //functions
|
||||||
|
ULONG_PTR pauseBreakInStartAddress()
|
||||||
|
{
|
||||||
|
auto localNtdll = GetModuleHandleW(L"ntdll.dll");
|
||||||
|
auto localStart = localNtdll ? GetProcAddress(localNtdll, "DbgUiRemoteBreakin") : nullptr;
|
||||||
|
if(!localStart || !mMainProcess.dwProcessId)
|
||||||
|
return 0;
|
||||||
|
auto snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE | TH32CS_SNAPMODULE32,
|
||||||
|
mMainProcess.dwProcessId);
|
||||||
|
if(snapshot == INVALID_HANDLE_VALUE)
|
||||||
|
return 0;
|
||||||
|
MODULEENTRY32W module = {};
|
||||||
|
module.dwSize = sizeof(module);
|
||||||
|
ULONG_PTR result = 0;
|
||||||
|
if(Module32FirstW(snapshot, &module))
|
||||||
|
{
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if(!_wcsicmp(module.szModule, L"ntdll.dll"))
|
||||||
|
{
|
||||||
|
result = (ULONG_PTR)module.modBaseAddr +
|
||||||
|
(ULONG_PTR)localStart - (ULONG_PTR)localNtdll;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while(Module32NextW(snapshot, &module));
|
||||||
|
}
|
||||||
|
CloseHandle(snapshot);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool requestPauseBreakIn()
|
||||||
|
{
|
||||||
|
auto startAddress = pauseBreakInStartAddress();
|
||||||
|
if(!startAddress)
|
||||||
|
{
|
||||||
|
SetLastError(ERROR_PROC_NOT_FOUND);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
mPauseBreakInExpected = true;
|
||||||
|
mPauseBreakInStart = startAddress;
|
||||||
|
mPauseBreakInThreadId = 0;
|
||||||
|
}
|
||||||
|
if(DebugBreakProcess(mMainProcess.hProcess))
|
||||||
|
return true;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
mPauseBreakInExpected = false;
|
||||||
|
mPauseBreakInStart = 0;
|
||||||
|
mPauseBreakInThreadId = 0;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void completePause()
|
||||||
|
{
|
||||||
|
TITANCBPAUSE callback = nullptr;
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
callback = mPauseCallback;
|
||||||
|
mPauseCallback = nullptr;
|
||||||
|
mPauseRequestTime = 0;
|
||||||
|
mPauseBreakInExpected = false;
|
||||||
|
mPauseBreakInStart = 0;
|
||||||
|
mPauseBreakInThreadId = 0;
|
||||||
|
}
|
||||||
|
if(callback)
|
||||||
|
callback();
|
||||||
|
}
|
||||||
|
|
||||||
|
void cancelPause()
|
||||||
|
{
|
||||||
|
std::lock_guard<std::mutex> lock(mPauseMutex);
|
||||||
|
mPauseCallback = nullptr;
|
||||||
|
mPauseRequestTime = 0;
|
||||||
|
mPauseBreakInExpected = false;
|
||||||
|
mPauseBreakInStart = 0;
|
||||||
|
mPauseBreakInThreadId = 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline Registers::R registerFromDword(DWORD IndexOfRegister)
|
inline Registers::R registerFromDword(DWORD IndexOfRegister)
|
||||||
{
|
{
|
||||||
switch(IndexOfRegister)
|
switch(IndexOfRegister)
|
||||||
|
|
@ -1343,6 +1548,13 @@ private: //functions
|
||||||
|
|
||||||
private: //variables
|
private: //variables
|
||||||
bool mSetDebugPrivilege = false;
|
bool mSetDebugPrivilege = false;
|
||||||
|
bool mWow64SingleStepWorkaround = true;
|
||||||
|
std::mutex mPauseMutex;
|
||||||
|
TITANCBPAUSE mPauseCallback = nullptr;
|
||||||
|
ULONGLONG mPauseRequestTime = 0;
|
||||||
|
bool mPauseBreakInExpected = false;
|
||||||
|
ULONG_PTR mPauseBreakInStart = 0;
|
||||||
|
DWORD mPauseBreakInThreadId = 0;
|
||||||
typedef void(*CUSTOMHANDLER)(const void*);
|
typedef void(*CUSTOMHANDLER)(const void*);
|
||||||
typedef void(*STEPCALLBACK)();
|
typedef void(*STEPCALLBACK)();
|
||||||
typedef STEPCALLBACK BPCALLBACK;
|
typedef STEPCALLBACK BPCALLBACK;
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef void(TITCALL* TITANCBSTEP)();
|
typedef void(TITCALL* TITANCBSTEP)();
|
||||||
|
typedef void(TITCALL* TITANCBPAUSE)();
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
|
@ -63,6 +64,8 @@ enum TitanSessionCapability : uint64_t
|
||||||
UE_SESSION_CAP_NATIVE_HANDLES = 1ull << 12,
|
UE_SESSION_CAP_NATIVE_HANDLES = 1ull << 12,
|
||||||
UE_SESSION_CAP_EXCEPTION_CONTINUE = 1ull << 13,
|
UE_SESSION_CAP_EXCEPTION_CONTINUE = 1ull << 13,
|
||||||
UE_SESSION_CAP_TIMELINE_STATE = 1ull << 14,
|
UE_SESSION_CAP_TIMELINE_STATE = 1ull << 14,
|
||||||
|
UE_SESSION_CAP_PAUSE_EXECUTION = 1ull << 16,
|
||||||
|
UE_SESSION_CAP_NAVIGABLE_PROCESS_EXIT = 1ull << 17,
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
|
|
@ -107,6 +110,14 @@ typedef struct
|
||||||
#define UE_ENGINE_MEMBP_ALT 11
|
#define UE_ENGINE_MEMBP_ALT 11
|
||||||
#define UE_ENGINE_DISABLE_ASLR 12
|
#define UE_ENGINE_DISABLE_ASLR 12
|
||||||
#define UE_ENGINE_SAFE_STEP 13
|
#define UE_ENGINE_SAFE_STEP 13
|
||||||
|
#define UE_ENGINE_WOW64_SINGLE_STEP_WORKAROUND 14
|
||||||
|
|
||||||
|
enum TitanPausePolicy
|
||||||
|
{
|
||||||
|
UE_PAUSE_POLICY_NONINVASIVE = 0,
|
||||||
|
UE_PAUSE_POLICY_STANDARD = 1,
|
||||||
|
UE_PAUSE_POLICY_AGGRESSIVE = 2,
|
||||||
|
};
|
||||||
|
|
||||||
#define UE_OPTION_REMOVEALL 1
|
#define UE_OPTION_REMOVEALL 1
|
||||||
#define UE_OPTION_DISABLEALL 2
|
#define UE_OPTION_DISABLEALL 2
|
||||||
|
|
@ -900,8 +911,8 @@ __declspec(dllexport) bool TITCALL GetSessionInfo(TITAN_SESSION_INFO* SessionInf
|
||||||
__declspec(dllexport) bool TITCALL ReplayGetPosition(TITAN_REPLAY_POSITION* Position);
|
__declspec(dllexport) bool TITCALL ReplayGetPosition(TITAN_REPLAY_POSITION* Position);
|
||||||
__declspec(dllexport) bool TITCALL ReplayGetExtent(TITAN_REPLAY_POSITION* First, TITAN_REPLAY_POSITION* Last);
|
__declspec(dllexport) bool TITCALL ReplayGetExtent(TITAN_REPLAY_POSITION* First, TITAN_REPLAY_POSITION* Last);
|
||||||
__declspec(dllexport) bool TITCALL ReplaySetPosition(const TITAN_REPLAY_POSITION* Position);
|
__declspec(dllexport) bool TITCALL ReplaySetPosition(const TITAN_REPLAY_POSITION* Position);
|
||||||
__declspec(dllexport) bool TITCALL ReplayRun(bool Reverse);
|
__declspec(dllexport) bool TITCALL ReplayRunBack();
|
||||||
__declspec(dllexport) bool TITCALL ReplayStep(bool Reverse, bool StepOver, TITANCBSTEP StepCallBack);
|
__declspec(dllexport) bool TITCALL ReplayStepBack(TITANCBSTEP StepCallBack);
|
||||||
__declspec(dllexport) void* TITCALL InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder);
|
__declspec(dllexport) void* TITCALL InitNativeDebug(char* szFileName, char* szCommandLine, char* szCurrentFolder);
|
||||||
__declspec(dllexport) void* TITCALL InitNativeDebugW(const wchar_t* szFileName, const wchar_t* szCommandLine, const wchar_t* szCurrentFolder);
|
__declspec(dllexport) void* TITCALL InitNativeDebugW(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 InitDebugEx(const char* szFileName, const char* szCommandLine, const char* szCurrentFolder, LPVOID EntryCallBack);
|
||||||
|
|
@ -1102,7 +1113,7 @@ __declspec(dllexport) bool TITCALL TitanGetModulePathW(HANDLE hProcess, ULONG_PT
|
||||||
__declspec(dllexport) bool TITCALL TitanCloseHandle(HANDLE hEngineHandle);
|
__declspec(dllexport) bool TITCALL TitanCloseHandle(HANDLE hEngineHandle);
|
||||||
__declspec(dllexport) bool TITCALL ProcessIsWow64(HANDLE hProcess, PBOOL isWow64);
|
__declspec(dllexport) bool TITCALL ProcessIsWow64(HANDLE hProcess, PBOOL isWow64);
|
||||||
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode);
|
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode);
|
||||||
__declspec(dllexport) bool TITCALL TitanDebugBreakProcess(HANDLE hProcess);
|
__declspec(dllexport) bool TITCALL RequestPause(TitanPausePolicy MaximumPolicy, TITANCBPAUSE PauseCallback);
|
||||||
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId);
|
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId);
|
||||||
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread);
|
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread);
|
||||||
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread);
|
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread);
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,8 @@ __declspec(dllexport) bool TITCALL GetSessionInfo(TITAN_SESSION_INFO* SessionInf
|
||||||
UE_SESSION_CAP_CONTEXT_READ | UE_SESSION_CAP_FORWARD_EXECUTION |
|
UE_SESSION_CAP_CONTEXT_READ | UE_SESSION_CAP_FORWARD_EXECUTION |
|
||||||
UE_SESSION_CAP_MEMORY_WRITE | UE_SESSION_CAP_CONTEXT_WRITE |
|
UE_SESSION_CAP_MEMORY_WRITE | UE_SESSION_CAP_CONTEXT_WRITE |
|
||||||
UE_SESSION_CAP_PROCESS_CONTROL | UE_SESSION_CAP_THREAD_CONTROL |
|
UE_SESSION_CAP_PROCESS_CONTROL | UE_SESSION_CAP_THREAD_CONTROL |
|
||||||
UE_SESSION_CAP_NATIVE_HANDLES | UE_SESSION_CAP_EXCEPTION_CONTINUE;
|
UE_SESSION_CAP_NATIVE_HANDLES | UE_SESSION_CAP_EXCEPTION_CONTINUE |
|
||||||
|
UE_SESSION_CAP_PAUSE_EXECUTION;
|
||||||
#ifdef _WIN64
|
#ifdef _WIN64
|
||||||
SessionInfo->machineType = IMAGE_FILE_MACHINE_AMD64;
|
SessionInfo->machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||||
#else
|
#else
|
||||||
|
|
@ -69,13 +70,13 @@ __declspec(dllexport) bool TITCALL ReplaySetPosition(const TITAN_REPLAY_POSITION
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL ReplayRun(bool Reverse)
|
__declspec(dllexport) bool TITCALL ReplayRunBack()
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
SetLastError(ERROR_NOT_SUPPORTED);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL ReplayStep(bool Reverse, bool StepOver, TITANCBSTEP StepCallBack)
|
__declspec(dllexport) bool TITCALL ReplayStepBack(TITANCBSTEP StepCallBack)
|
||||||
{
|
{
|
||||||
SetLastError(ERROR_NOT_SUPPORTED);
|
SetLastError(ERROR_NOT_SUPPORTED);
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -241,7 +242,7 @@ __declspec(dllexport) bool TITCALL ProcessIsWow64(HANDLE hProcess, PBOOL isWow64
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode) { return !!TerminateProcess(hProcess, exitCode); }
|
__declspec(dllexport) bool TITCALL TitanTerminateProcess(HANDLE hProcess, DWORD exitCode) { return !!TerminateProcess(hProcess, exitCode); }
|
||||||
__declspec(dllexport) bool TITCALL TitanDebugBreakProcess(HANDLE hProcess) { return !!DebugBreakProcess(hProcess); }
|
__declspec(dllexport) bool TITCALL RequestPause(TitanPausePolicy MaximumPolicy, TITANCBPAUSE PauseCallback) { return emu.RequestPause(MaximumPolicy, PauseCallback); }
|
||||||
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId) { return CreateRemoteThread(hProcess, nullptr, 0, start, argument, creationFlags, threadId); }
|
__declspec(dllexport) HANDLE TITCALL TitanCreateRemoteThread(HANDLE hProcess, LPTHREAD_START_ROUTINE start, LPVOID argument, DWORD creationFlags, LPDWORD threadId) { return CreateRemoteThread(hProcess, nullptr, 0, start, argument, creationFlags, threadId); }
|
||||||
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread) { return SuspendThread(hThread); }
|
__declspec(dllexport) DWORD TITCALL TitanSuspendThread(HANDLE hThread) { return SuspendThread(hThread); }
|
||||||
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread) { return ResumeThread(hThread); }
|
__declspec(dllexport) DWORD TITCALL TitanResumeThread(HANDLE hThread) { return ResumeThread(hThread); }
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue