mirror of https://github.com/x64dbg/TitanEngine
improve safe attach option on Vista+
This commit is contained in:
parent
f835fc8719
commit
a260728ad3
|
|
@ -133,14 +133,74 @@ static HANDLE WINAPI ProcessIdToHandle(IN DWORD dwProcessId)
|
||||||
return Handle;
|
return Handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define THREAD_CREATE_FLAGS_CREATE_SUSPENDED 0x00000001
|
||||||
|
#define THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH 0x00000002
|
||||||
|
#define THREAD_CREATE_FLAGS_HIDE_FROM_DEBUGGER 0x00000004
|
||||||
|
#define THREAD_CREATE_FLAGS_HAS_SECURITY_DESCRIPTOR 0x00000010
|
||||||
|
#define THREAD_CREATE_FLAGS_ACCESS_CHECK_IN_TARGET 0x00000020
|
||||||
|
#define THREAD_CREATE_FLAGS_INITIAL_THREAD 0x00000080
|
||||||
|
|
||||||
|
static NTSTATUS CreateThreadSkipAttach(IN HANDLE ProcessHandle, IN PUSER_THREAD_START_ROUTINE StartRoutine, IN PVOID Argument)
|
||||||
|
{
|
||||||
|
NTSTATUS Status;
|
||||||
|
HANDLE hThread;
|
||||||
|
|
||||||
|
typedef NTSTATUS(NTAPI *t_NtCreateThreadEx)(
|
||||||
|
PHANDLE /* ThreadHandle */,
|
||||||
|
ACCESS_MASK /* DesiredAccess */,
|
||||||
|
POBJECT_ATTRIBUTES /* ObjectAttributes */,
|
||||||
|
HANDLE /* ProcessHandle */,
|
||||||
|
PUSER_THREAD_START_ROUTINE /* StartRoutine */,
|
||||||
|
PVOID /* Argument */,
|
||||||
|
ULONG /* CreateFlags */,
|
||||||
|
ULONG_PTR /* ZeroBits */,
|
||||||
|
SIZE_T /* StackSize */,
|
||||||
|
SIZE_T /* MaximumStackSize */,
|
||||||
|
PPS_ATTRIBUTE_LIST /* AttributeList */
|
||||||
|
);
|
||||||
|
|
||||||
|
auto p_NtCreateThreadEx = (t_NtCreateThreadEx)GetProcAddress(GetModuleHandleW(L"ntdll.dll"), "NtCreateThreadEx");
|
||||||
|
if(p_NtCreateThreadEx)
|
||||||
|
{
|
||||||
|
// Based on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/339263/16/client/crashpad_client_win.cc#697
|
||||||
|
Status = p_NtCreateThreadEx(&hThread,
|
||||||
|
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL,
|
||||||
|
nullptr,
|
||||||
|
ProcessHandle,
|
||||||
|
StartRoutine,
|
||||||
|
Argument,
|
||||||
|
THREAD_CREATE_FLAGS_SKIP_THREAD_ATTACH,
|
||||||
|
0,
|
||||||
|
0x4000 /* PAGE_SIZE * 4 */,
|
||||||
|
0,
|
||||||
|
nullptr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
CLIENT_ID ClientId;
|
||||||
|
Status = RtlCreateUserThread(ProcessHandle,
|
||||||
|
NULL,
|
||||||
|
FALSE,
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
0x4000 /* PAGE_SIZE * 4 */,
|
||||||
|
StartRoutine,
|
||||||
|
Argument,
|
||||||
|
&hThread,
|
||||||
|
&ClientId);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(NT_SUCCESS(Status))
|
||||||
|
{
|
||||||
|
NtClose(hThread);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
|
||||||
static NTSTATUS NTAPI DbgUiIssueRemoteBreakin_(IN HANDLE Process)
|
static NTSTATUS NTAPI DbgUiIssueRemoteBreakin_(IN HANDLE Process)
|
||||||
{
|
{
|
||||||
HANDLE hThread;
|
|
||||||
CLIENT_ID ClientId;
|
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
PUSER_THREAD_START_ROUTINE RemoteBreakFunction = (PUSER_THREAD_START_ROUTINE)DbgUiRemoteBreakin;
|
PUSER_THREAD_START_ROUTINE RemoteBreakFunction = (PUSER_THREAD_START_ROUTINE)DbgUiRemoteBreakin;
|
||||||
|
|
||||||
LPVOID RemoteMemory = VirtualAllocEx(Process, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ);
|
LPVOID RemoteMemory = VirtualAllocEx(Process, 0, 0x1000, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READ);
|
||||||
if(RemoteMemory)
|
if(RemoteMemory)
|
||||||
{
|
{
|
||||||
|
|
@ -156,31 +216,14 @@ static NTSTATUS NTAPI DbgUiIssueRemoteBreakin_(IN HANDLE Process)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create the thread that will do the breakin */
|
/* Create the thread that will perform the breakin (on Vista+ it will skip DllMain and TLS callbacks) */
|
||||||
Status = RtlCreateUserThread(Process,
|
return CreateThreadSkipAttach(Process, RemoteBreakFunction, NULL);
|
||||||
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)
|
static NTSTATUS NTAPI DbgUiDebugActiveProcess_(IN HANDLE Process)
|
||||||
{
|
{
|
||||||
NTSTATUS Status;
|
|
||||||
|
|
||||||
/* Tell the kernel to start debugging */
|
/* Tell the kernel to start debugging */
|
||||||
Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[1]);
|
NTSTATUS Status = NtDebugActiveProcess(Process, NtCurrentTeb()->DbgSsReserved[1]);
|
||||||
if(NT_SUCCESS(Status))
|
if(NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
/* Now break-in the process */
|
/* Now break-in the process */
|
||||||
|
|
@ -199,11 +242,8 @@ static NTSTATUS NTAPI DbgUiDebugActiveProcess_(IN HANDLE Process)
|
||||||
// Source: https://github.com/mirror/reactos/blob/c6d2b35ffc91e09f50dfb214ea58237509329d6b/reactos/dll/win32/kernel32/client/debugger.c#L480
|
// Source: https://github.com/mirror/reactos/blob/c6d2b35ffc91e09f50dfb214ea58237509329d6b/reactos/dll/win32/kernel32/client/debugger.c#L480
|
||||||
BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId)
|
BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId)
|
||||||
{
|
{
|
||||||
NTSTATUS Status, Status1;
|
|
||||||
HANDLE Handle;
|
|
||||||
|
|
||||||
/* Connect to the debugger */
|
/* Connect to the debugger */
|
||||||
Status = DbgUiConnectToDbg();
|
NTSTATUS Status = DbgUiConnectToDbg();
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
{
|
{
|
||||||
BaseSetLastNTError(Status);
|
BaseSetLastNTError(Status);
|
||||||
|
|
@ -211,14 +251,17 @@ BOOL WINAPI DebugActiveProcess_(IN DWORD dwProcessId)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the process handle */
|
/* Get the process handle */
|
||||||
Handle = ProcessIdToHandle(dwProcessId);
|
HANDLE Handle = ProcessIdToHandle(dwProcessId);
|
||||||
if(!Handle) return FALSE;
|
if(!Handle)
|
||||||
|
{
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Now debug the process */
|
/* Now debug the process */
|
||||||
Status = DbgUiDebugActiveProcess_(Handle);
|
Status = DbgUiDebugActiveProcess_(Handle);
|
||||||
|
|
||||||
/* Close the handle since we're done */
|
/* Close the handle since we're done */
|
||||||
Status1 = NtClose(Handle);
|
NtClose(Handle);
|
||||||
|
|
||||||
/* Check if debugging worked */
|
/* Check if debugging worked */
|
||||||
if(!NT_SUCCESS(Status))
|
if(!NT_SUCCESS(Status))
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue