mirror of https://github.com/x64dbg/TitanEngine
Add safe attach option
This commit is contained in:
parent
ab037ef1c5
commit
bfec722a12
|
|
@ -56,6 +56,7 @@
|
||||||
#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_SAFE_ATTACH 10
|
||||||
|
|
||||||
#define UE_OPTION_REMOVEALL 1
|
#define UE_OPTION_REMOVEALL 1
|
||||||
#define UE_OPTION_DISABLEALL 2
|
#define UE_OPTION_DISABLEALL 2
|
||||||
|
|
|
||||||
|
|
@ -52,6 +52,7 @@ const BYTE UE_ENGINE_CALL_PLUGIN_CALLBACK = 6;
|
||||||
const BYTE UE_ENGINE_RESET_CUSTOM_HANDLER = 7;
|
const BYTE UE_ENGINE_RESET_CUSTOM_HANDLER = 7;
|
||||||
const BYTE UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
const BYTE UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
||||||
const BYTE UE_ENGINE_SET_DEBUG_PRIVILEGE = 9;
|
const BYTE UE_ENGINE_SET_DEBUG_PRIVILEGE = 9;
|
||||||
|
const BYTE UE_ENGINE_SAFE_ATTACH = 10;
|
||||||
|
|
||||||
const BYTE UE_OPTION_REMOVEALL = 1;
|
const BYTE UE_OPTION_REMOVEALL = 1;
|
||||||
const BYTE UE_OPTION_DISABLEALL = 2;
|
const BYTE UE_OPTION_DISABLEALL = 2;
|
||||||
|
|
|
||||||
|
|
@ -71,7 +71,8 @@ enum eEngineVariable : DWORD
|
||||||
UE_ENGINE_CALL_PLUGIN_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_CALLBACK,
|
UE_ENGINE_CALL_PLUGIN_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_CALLBACK,
|
||||||
UE_ENGINE_RESET_CUSTOM_HANDLER = UE::UE_ENGINE_RESET_CUSTOM_HANDLER,
|
UE_ENGINE_RESET_CUSTOM_HANDLER = UE::UE_ENGINE_RESET_CUSTOM_HANDLER,
|
||||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK,
|
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK,
|
||||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = UE::UE_ENGINE_SET_DEBUG_PRIVILEGE
|
UE_ENGINE_SET_DEBUG_PRIVILEGE = UE::UE_ENGINE_SET_DEBUG_PRIVILEGE,
|
||||||
|
UE_ENGINE_SAFE_ATTACH = UE::UE_ENGINE_SAFE_ATTACH,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum eBPRemoveOption : DWORD
|
enum eBPRemoveOption : DWORD
|
||||||
|
|
|
||||||
|
|
@ -336,7 +336,8 @@ const
|
||||||
UE_ENGINE_CALL_PLUGIN_CALLBACK = 6;
|
UE_ENGINE_CALL_PLUGIN_CALLBACK = 6;
|
||||||
UE_ENGINE_RESET_CUSTOM_HANDLER = 7;
|
UE_ENGINE_RESET_CUSTOM_HANDLER = 7;
|
||||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
||||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9;
|
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9;
|
||||||
|
UE_ENGINE_SAFE_ATTACH = 10;
|
||||||
|
|
||||||
UE_OPTION_REMOVEALL = 1;
|
UE_OPTION_REMOVEALL = 1;
|
||||||
UE_OPTION_DISABLEALL = 2;
|
UE_OPTION_DISABLEALL = 2;
|
||||||
|
|
|
||||||
|
|
@ -37,6 +37,7 @@ UE_ENGINE_CALL_PLUGIN_CALLBACK = 6
|
||||||
UE_ENGINE_RESET_CUSTOM_HANDLER = 7
|
UE_ENGINE_RESET_CUSTOM_HANDLER = 7
|
||||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8
|
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8
|
||||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9
|
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9
|
||||||
|
UE_ENGINE_SAFE_ATTACH = 10
|
||||||
|
|
||||||
UE_OPTION_REMOVEALL = 1
|
UE_OPTION_REMOVEALL = 1
|
||||||
UE_OPTION_DISABLEALL = 2
|
UE_OPTION_DISABLEALL = 2
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ UE_ENGINE_BACKUP_FOR_CRITICAL_FUNCTIONS EQU 5
|
||||||
UE_ENGINE_CALL_PLUGIN_CALLBACK EQU 6
|
UE_ENGINE_CALL_PLUGIN_CALLBACK EQU 6
|
||||||
UE_ENGINE_RESET_CUSTOM_HANDLER EQU 7
|
UE_ENGINE_RESET_CUSTOM_HANDLER EQU 7
|
||||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK EQU 8
|
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK EQU 8
|
||||||
|
UE_ENGINE_SAFE_ATTACH EQU 10
|
||||||
UE_ENGINE_SET_DEBUG_PRIVILEGE EQU 9
|
UE_ENGINE_SET_DEBUG_PRIVILEGE EQU 9
|
||||||
UE_OPTION_REMOVEALL EQU 1
|
UE_OPTION_REMOVEALL EQU 1
|
||||||
UE_OPTION_DISABLEALL EQU 2
|
UE_OPTION_DISABLEALL EQU 2
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@ UE_ENGINE_CALL_PLUGIN_CALLBACK = 6
|
||||||
UE_ENGINE_RESET_CUSTOM_HANDLER = 7
|
UE_ENGINE_RESET_CUSTOM_HANDLER = 7
|
||||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8
|
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8
|
||||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9
|
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9
|
||||||
|
UE_ENGINE_SAFE_ATTACH = 10
|
||||||
|
|
||||||
UE_OPTION_REMOVEALL = 1
|
UE_OPTION_REMOVEALL = 1
|
||||||
UE_OPTION_DISABLEALL = 2
|
UE_OPTION_DISABLEALL = 2
|
||||||
|
|
|
||||||
|
|
@ -93,3 +93,141 @@ void StepOutStepCallBack()
|
||||||
else
|
else
|
||||||
StepOver(StepOutStepCallBack);
|
StepOver(StepOutStepCallBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static DWORD BaseSetLastNTError(IN NTSTATUS Status)
|
||||||
|
{
|
||||||
|
DWORD dwErrCode;
|
||||||
|
dwErrCode = RtlNtStatusToDosError(Status);
|
||||||
|
SetLastError(dwErrCode);
|
||||||
|
return dwErrCode;
|
||||||
|
}
|
||||||
|
|
||||||
|
static HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||||
|
HANDLE Handle;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
|
||||||
|
/* If we don't have a PID, look it up */
|
||||||
|
//if (dwProcessId == MAXDWORD) dwProcessId = (DWORD_PTR)CsrGetProcessId();
|
||||||
|
|
||||||
|
/* Open a handle to the process */
|
||||||
|
ClientId.UniqueThread = NULL;
|
||||||
|
ClientId.UniqueProcess = UlongToHandle(dwProcessId);
|
||||||
|
InitializeObjectAttributes(&ObjectAttributes, NULL, 0, NULL, NULL);
|
||||||
|
Status = NtOpenProcess(&Handle,
|
||||||
|
PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION |
|
||||||
|
PROCESS_VM_WRITE | PROCESS_VM_READ |
|
||||||
|
PROCESS_SUSPEND_RESUME | PROCESS_QUERY_INFORMATION,
|
||||||
|
&ObjectAttributes,
|
||||||
|
&ClientId);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return the handle */
|
||||||
|
return Handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS NTAPI DbgUiIssueRemoteBreakin_(IN HANDLE Process)
|
||||||
|
{
|
||||||
|
HANDLE hThread;
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
PUSER_THREAD_START_ROUTINE RemoteBreakFunction = (PUSER_THREAD_START_ROUTINE)DbgUiRemoteBreakin;
|
||||||
|
|
||||||
|
LPVOID RemoteMemory = VirtualAllocEx(Process, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ);
|
||||||
|
if(RemoteMemory)
|
||||||
|
{
|
||||||
|
SIZE_T written = 0;
|
||||||
|
unsigned char payload[] = { 0xCC, 0xC3 };
|
||||||
|
if(WriteProcessMemory(Process, RemoteMemory, payload, sizeof(payload), &written))
|
||||||
|
{
|
||||||
|
RemoteBreakFunction = (PUSER_THREAD_START_ROUTINE)RemoteMemory;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
VirtualFreeEx(Process, RemoteMemory, 0, MEM_RELEASE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create the thread that will do the breakin */
|
||||||
|
Status = RtlCreateUserThread(Process,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0x1000 /* PAGE_SIZE */,
|
||||||
|
RemoteBreakFunction,
|
||||||
|
NULL,
|
||||||
|
&hThread,
|
||||||
|
&ClientId);
|
||||||
|
|
||||||
|
/* Close the handle on success */
|
||||||
|
if(NT_SUCCESS(Status)) NtClose(hThread);
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
static NTSTATUS NTAPI DbgUiDebugActiveProcess_(IN HANDLE Process)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
|
||||||
|
/* Tell the kernel to start debugging */
|
||||||
|
Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[1]);
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Now break-in the process */
|
||||||
|
Status = DbgUiIssueRemoteBreakin_(Process);
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* We couldn't break-in, cancel debugging */
|
||||||
|
DbgUiStopDebugging(Process);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Return status */
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source: https://github.com/mirror/reactos/blob/c6d2b35ffc91e09f50dfb214ea58237509329d6b/reactos/dll/win32/kernel32/client/debugger.c#L480
|
||||||
|
BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId)
|
||||||
|
{
|
||||||
|
NTSTATUS Status, Status1;
|
||||||
|
HANDLE Handle;
|
||||||
|
|
||||||
|
/* Connect to the debugger */
|
||||||
|
Status = DbgUiConnectToDbg();
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Get the process handle */
|
||||||
|
Handle = ProcessIdToHandle(dwProcessId);
|
||||||
|
if(!Handle) return FALSE;
|
||||||
|
|
||||||
|
/* Now debug the process */
|
||||||
|
Status = DbgUiDebugActiveProcess_(Handle);
|
||||||
|
|
||||||
|
/* Close the handle since we're done */
|
||||||
|
Status1 = NtClose(Handle);
|
||||||
|
|
||||||
|
/* Check if debugging worked */
|
||||||
|
if(!NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
/* Fail */
|
||||||
|
BaseSetLastNTError(Status);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Success */
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
@ -46,5 +46,6 @@ void DebuggerReset();
|
||||||
void ClearProcessList();
|
void ClearProcessList();
|
||||||
void ClearTlsCallBackList();
|
void ClearTlsCallBackList();
|
||||||
void StepOutStepCallBack();
|
void StepOutStepCallBack();
|
||||||
|
BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId);
|
||||||
|
|
||||||
#endif //_GLOBAL_DEBUGGER_H
|
#endif //_GLOBAL_DEBUGGER_H
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ bool enginePassAllExceptions = true;
|
||||||
bool engineExecutePluginCallBack = true;
|
bool engineExecutePluginCallBack = true;
|
||||||
bool engineAutoHideFromDebugger = false; // hardcoded
|
bool engineAutoHideFromDebugger = false; // hardcoded
|
||||||
bool engineEnableDebugPrivilege = false;
|
bool engineEnableDebugPrivilege = false;
|
||||||
|
bool engineSafeAttach = false;
|
||||||
|
|
||||||
char engineFoundDLLName[512] = {0};
|
char engineFoundDLLName[512] = {0};
|
||||||
char engineFoundAPIName[512] = {0};
|
char engineFoundAPIName[512] = {0};
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@ extern bool enginePassAllExceptions;
|
||||||
extern bool engineExecutePluginCallBack;
|
extern bool engineExecutePluginCallBack;
|
||||||
extern bool engineAutoHideFromDebugger;
|
extern bool engineAutoHideFromDebugger;
|
||||||
extern bool engineEnableDebugPrivilege;
|
extern bool engineEnableDebugPrivilege;
|
||||||
|
extern bool engineSafeAttach;
|
||||||
|
|
||||||
//Global.Engine.Functions
|
//Global.Engine.Functions
|
||||||
void EngineInit();
|
void EngineInit();
|
||||||
|
|
|
||||||
|
|
@ -550,7 +550,7 @@ __declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnEx
|
||||||
EngineSetDebugPrivilege(GetCurrentProcess(), true);
|
EngineSetDebugPrivilege(GetCurrentProcess(), true);
|
||||||
DebugRemoveDebugPrivilege = true;
|
DebugRemoveDebugPrivilege = true;
|
||||||
}
|
}
|
||||||
if(DebugActiveProcess(ProcessId))
|
if((engineSafeAttach ? DebugActiveProcess_ : DebugActiveProcess)(ProcessId))
|
||||||
{
|
{
|
||||||
if(engineEnableDebugPrivilege)
|
if(engineEnableDebugPrivilege)
|
||||||
EngineSetDebugPrivilege(GetCurrentProcess(), false);
|
EngineSetDebugPrivilege(GetCurrentProcess(), false);
|
||||||
|
|
|
||||||
|
|
@ -42,6 +42,10 @@ __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool Vari
|
||||||
{
|
{
|
||||||
engineEnableDebugPrivilege = VariableSet;
|
engineEnableDebugPrivilege = VariableSet;
|
||||||
}
|
}
|
||||||
|
else if(VariableId == UE_ENGINE_SAFE_ATTACH)
|
||||||
|
{
|
||||||
|
engineSafeAttach = VariableSet;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles)
|
__declspec(dllexport) bool TITCALL EngineCreateMissingDependencies(char* szFileName, char* szOutputFolder, bool LogCreatedFiles)
|
||||||
|
|
|
||||||
|
|
@ -469,6 +469,7 @@ typedef struct HOOK_ENTRY
|
||||||
#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_SAFE_ATTACH 10
|
||||||
|
|
||||||
#define UE_OPTION_REMOVEALL 1
|
#define UE_OPTION_REMOVEALL 1
|
||||||
#define UE_OPTION_DISABLEALL 2
|
#define UE_OPTION_DISABLEALL 2
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue