Clean up TTD APIs

This commit is contained in:
Duncan Ogilvie 2026-09-07 02:41:27 +02:00
parent fc2d0a2678
commit 4276bfa2f7
5 changed files with 256 additions and 14 deletions

View File

@ -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);

View File

@ -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); }

View File

@ -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;

View File

@ -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);

View File

@ -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); }