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_CALL_PLUGIN_DEBUG_CALLBACK 8
|
||||
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
||||
#define UE_ENGINE_SAFE_ATTACH 10
|
||||
|
||||
#define UE_OPTION_REMOVEALL 1
|
||||
#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_CALL_PLUGIN_DEBUG_CALLBACK = 8;
|
||||
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_DISABLEALL = 2;
|
||||
|
|
|
|||
|
|
@ -71,7 +71,8 @@ enum eEngineVariable : DWORD
|
|||
UE_ENGINE_CALL_PLUGIN_CALLBACK = UE::UE_ENGINE_CALL_PLUGIN_CALLBACK,
|
||||
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_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
|
||||
|
|
|
|||
|
|
@ -336,7 +336,8 @@ const
|
|||
UE_ENGINE_CALL_PLUGIN_CALLBACK = 6;
|
||||
UE_ENGINE_RESET_CUSTOM_HANDLER = 7;
|
||||
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_DISABLEALL = 2;
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ UE_ENGINE_CALL_PLUGIN_CALLBACK = 6
|
|||
UE_ENGINE_RESET_CUSTOM_HANDLER = 7
|
||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8
|
||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9
|
||||
UE_ENGINE_SAFE_ATTACH = 10
|
||||
|
||||
UE_OPTION_REMOVEALL = 1
|
||||
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_RESET_CUSTOM_HANDLER EQU 7
|
||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK EQU 8
|
||||
UE_ENGINE_SAFE_ATTACH EQU 10
|
||||
UE_ENGINE_SET_DEBUG_PRIVILEGE EQU 9
|
||||
UE_OPTION_REMOVEALL EQU 1
|
||||
UE_OPTION_DISABLEALL EQU 2
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ UE_ENGINE_CALL_PLUGIN_CALLBACK = 6
|
|||
UE_ENGINE_RESET_CUSTOM_HANDLER = 7
|
||||
UE_ENGINE_CALL_PLUGIN_DEBUG_CALLBACK = 8
|
||||
UE_ENGINE_SET_DEBUG_PRIVILEGE = 9
|
||||
UE_ENGINE_SAFE_ATTACH = 10
|
||||
|
||||
UE_OPTION_REMOVEALL = 1
|
||||
UE_OPTION_DISABLEALL = 2
|
||||
|
|
|
|||
|
|
@ -93,3 +93,141 @@ void StepOutStepCallBack()
|
|||
else
|
||||
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 ClearTlsCallBackList();
|
||||
void StepOutStepCallBack();
|
||||
BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId);
|
||||
|
||||
#endif //_GLOBAL_DEBUGGER_H
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ bool enginePassAllExceptions = true;
|
|||
bool engineExecutePluginCallBack = true;
|
||||
bool engineAutoHideFromDebugger = false; // hardcoded
|
||||
bool engineEnableDebugPrivilege = false;
|
||||
bool engineSafeAttach = false;
|
||||
|
||||
char engineFoundDLLName[512] = {0};
|
||||
char engineFoundAPIName[512] = {0};
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@ extern bool enginePassAllExceptions;
|
|||
extern bool engineExecutePluginCallBack;
|
||||
extern bool engineAutoHideFromDebugger;
|
||||
extern bool engineEnableDebugPrivilege;
|
||||
extern bool engineSafeAttach;
|
||||
|
||||
//Global.Engine.Functions
|
||||
void EngineInit();
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ __declspec(dllexport) bool TITCALL AttachDebugger(DWORD ProcessId, bool KillOnEx
|
|||
EngineSetDebugPrivilege(GetCurrentProcess(), true);
|
||||
DebugRemoveDebugPrivilege = true;
|
||||
}
|
||||
if(DebugActiveProcess(ProcessId))
|
||||
if((engineSafeAttach ? DebugActiveProcess_ : DebugActiveProcess)(ProcessId))
|
||||
{
|
||||
if(engineEnableDebugPrivilege)
|
||||
EngineSetDebugPrivilege(GetCurrentProcess(), false);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,10 @@ __declspec(dllexport) void TITCALL SetEngineVariable(DWORD VariableId, bool Vari
|
|||
{
|
||||
engineEnableDebugPrivilege = VariableSet;
|
||||
}
|
||||
else if(VariableId == UE_ENGINE_SAFE_ATTACH)
|
||||
{
|
||||
engineSafeAttach = VariableSet;
|
||||
}
|
||||
}
|
||||
|
||||
__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_CALL_PLUGIN_DEBUG_CALLBACK 8
|
||||
#define UE_ENGINE_SET_DEBUG_PRIVILEGE 9
|
||||
#define UE_ENGINE_SAFE_ATTACH 10
|
||||
|
||||
#define UE_OPTION_REMOVEALL 1
|
||||
#define UE_OPTION_DISABLEALL 2
|
||||
|
|
|
|||
Loading…
Reference in New Issue