mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
* added KphSetHandleGrantedAccess; KPH can finally bypass all protected process restrictions
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@1254 21ef857c-d57f-4fe0-8362-d861dc6d29cd
This commit is contained in:
@@ -4,6 +4,7 @@ Process Hacker
|
||||
* NEW/IMPROVED:
|
||||
* KProcessHacker can now perform process memory reading/writing
|
||||
by itself and does not require MmCopyVirtualMemory
|
||||
* KProcessHacker can now bypass all handle-opening protections
|
||||
* Better highlighting
|
||||
* Shows function file and line numbers where available
|
||||
* FIXED:
|
||||
|
||||
Binary file not shown.
@@ -199,6 +199,12 @@ NTSTATUS KphSetContextThread(
|
||||
KPROCESSOR_MODE AccessMode
|
||||
);
|
||||
|
||||
NTSTATUS KphSetHandleGrantedAccess(
|
||||
PEPROCESS Process,
|
||||
HANDLE Handle,
|
||||
ACCESS_MASK GrantedAccess
|
||||
);
|
||||
|
||||
NTSTATUS KphSuspendProcess(
|
||||
HANDLE ProcessHandle
|
||||
);
|
||||
|
||||
@@ -68,7 +68,7 @@
|
||||
#define KPH_GETTHREADID KPH_CTL_CODE(24)
|
||||
#define KPH_TERMINATETHREAD KPH_CTL_CODE(25)
|
||||
#define KPH_GETFEATURES KPH_CTL_CODE(26)
|
||||
#define KPH_RESERVED2 KPH_CTL_CODE(27)
|
||||
#define KPH_SETHANDLEGRANTEDACCESS KPH_CTL_CODE(27)
|
||||
#define KPH_ASSIGNIMPERSONATIONTOKEN KPH_CTL_CODE(28)
|
||||
|
||||
#define GET_BIT(integer, bit) (((integer) >> (bit)) & 0x1)
|
||||
|
||||
@@ -29,6 +29,11 @@
|
||||
#define OBJECT_TO_OBJECT_HEADER(o) \
|
||||
CONTAINING_RECORD((o), OBJECT_HEADER, Body)
|
||||
|
||||
#define OBJ_PROTECT_CLOSE 0x00000001L
|
||||
#define OBJ_INHERIT 0x00000002L
|
||||
#define OBJ_AUDIT_OBJECT_CLOSE 0x00000004L
|
||||
#define OBJ_HANDLE_ATTRIBUTES (OBJ_PROTECT_CLOSE | OBJ_INHERIT | OBJ_AUDIT_OBJECT_CLOSE)
|
||||
|
||||
/* FUNCTION DEFS */
|
||||
|
||||
NTSTATUS NTAPI ObOpenObjectByName(
|
||||
|
||||
@@ -96,6 +96,7 @@ EXT ULONG OffEpObjectTable;
|
||||
EXT ULONG OffEpProtectedProcessOff;
|
||||
EXT ULONG OffEpProtectedProcessBit;
|
||||
EXT ULONG OffEpRundownProtect;
|
||||
EXT ULONG OffOhBody;
|
||||
EXT ULONG OffOtiGenericMapping;
|
||||
|
||||
/* Functions
|
||||
|
||||
@@ -233,6 +233,8 @@ PCHAR GetIoControlName(ULONG ControlCode)
|
||||
return "KphTerminateThread";
|
||||
else if (ControlCode == KPH_GETFEATURES)
|
||||
return "Get Features";
|
||||
else if (ControlCode == KPH_SETHANDLEGRANTEDACCESS)
|
||||
return "KphSetHandleGrantedAccess";
|
||||
else if (ControlCode == KPH_ASSIGNIMPERSONATIONTOKEN)
|
||||
return "KphAssignImpersonationToken";
|
||||
else
|
||||
@@ -1155,6 +1157,32 @@ NTSTATUS KphDispatchDeviceControl(PDEVICE_OBJECT DeviceObject, PIRP Irp)
|
||||
}
|
||||
break;
|
||||
|
||||
/* KphSetHandleGrantedAccess
|
||||
*
|
||||
* Sets the granted access for a handle.
|
||||
*/
|
||||
case KPH_SETHANDLEGRANTEDACCESS:
|
||||
{
|
||||
struct
|
||||
{
|
||||
HANDLE Handle;
|
||||
ACCESS_MASK GrantedAccess;
|
||||
} *args = dataBuffer;
|
||||
|
||||
if (inLength < sizeof(*args))
|
||||
{
|
||||
status = STATUS_BUFFER_TOO_SMALL;
|
||||
goto IoControlEnd;
|
||||
}
|
||||
|
||||
status = KphSetHandleGrantedAccess(
|
||||
PsGetCurrentProcess(),
|
||||
args->Handle,
|
||||
args->GrantedAccess
|
||||
);
|
||||
}
|
||||
break;
|
||||
|
||||
/* KphAssignImpersonationToken
|
||||
*
|
||||
* Assigns an impersonation token to a thread.
|
||||
|
||||
@@ -138,11 +138,58 @@ BOOLEAN KphEnumProcessHandleTable(
|
||||
handleTable,
|
||||
EnumHandleProcedure,
|
||||
Context,
|
||||
Handle);
|
||||
Handle
|
||||
);
|
||||
ObDereferenceProcessHandleTable(Process);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* KphpSetHandleGrantedAccessEnumCallback
|
||||
*
|
||||
* The callback for KphEnumProcessHandleTable, used by
|
||||
* KphSetHandleGrantedAccess.
|
||||
*/
|
||||
BOOLEAN KphpSetHandleGrantedAccessEnumCallback(
|
||||
PHANDLE_TABLE_ENTRY HandleTableEntry,
|
||||
HANDLE Handle,
|
||||
PSET_HANDLE_GRANTED_ACCESS_DATA Context
|
||||
)
|
||||
{
|
||||
if (Handle != Context->Handle)
|
||||
return FALSE;
|
||||
|
||||
HandleTableEntry->GrantedAccess = Context->GrantedAccess;
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* KphSetHandleGrantedAccess
|
||||
*
|
||||
* Sets the granted access of a handle.
|
||||
*/
|
||||
NTSTATUS KphSetHandleGrantedAccess(
|
||||
PEPROCESS Process,
|
||||
HANDLE Handle,
|
||||
ACCESS_MASK GrantedAccess
|
||||
)
|
||||
{
|
||||
BOOLEAN result;
|
||||
SET_HANDLE_GRANTED_ACCESS_DATA context;
|
||||
|
||||
context.Handle = Handle;
|
||||
context.GrantedAccess = GrantedAccess;
|
||||
|
||||
result = KphEnumProcessHandleTable(
|
||||
Process,
|
||||
KphpSetHandleGrantedAccessEnumCallback,
|
||||
&context,
|
||||
NULL
|
||||
);
|
||||
|
||||
return result ? STATUS_SUCCESS : STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
/* ObDereferenceProcessHandleTable
|
||||
*
|
||||
* Allows the process to terminate.
|
||||
|
||||
@@ -119,6 +119,7 @@ NTSTATUS KvInit()
|
||||
OffEpProtectedProcessBit = 0;
|
||||
OffEpRundownProtect = 0x80;
|
||||
OffOtiGenericMapping = 0x60 + 0x8;
|
||||
OffOhBody = 0x18;
|
||||
|
||||
/* We are scanning for PspTerminateProcess which has
|
||||
the same signature as PsTerminateProcess because
|
||||
@@ -181,6 +182,7 @@ NTSTATUS KvInit()
|
||||
OffEpProtectedProcessOff = 0x224;
|
||||
OffEpProtectedProcessBit = 0xb;
|
||||
OffEpRundownProtect = 0x98;
|
||||
OffOhBody = 0x18;
|
||||
|
||||
INIT_SCAN(
|
||||
PsTerminateProcessScan,
|
||||
@@ -231,6 +233,7 @@ NTSTATUS KvInit()
|
||||
OffEpProtectedProcessBit = 0xb;
|
||||
OffEpRundownProtect = 0xb0;
|
||||
OffOtiGenericMapping = 0x28 + 0xc;
|
||||
OffOhBody = 0x18;
|
||||
|
||||
INIT_SCAN(
|
||||
PsTerminateProcessScan,
|
||||
|
||||
@@ -75,7 +75,7 @@ namespace ProcessHacker.Native
|
||||
KphGetThreadId,
|
||||
KphTerminateThread,
|
||||
GetFeatures,
|
||||
Reserved2,
|
||||
KphSetHandleGrantedAccess,
|
||||
KphAssignImpersonationToken
|
||||
}
|
||||
|
||||
@@ -463,6 +463,16 @@ namespace ProcessHacker.Native
|
||||
_fileHandle.IoControl(CtlCode(Control.KphSetContextThread), inData, 8, null, 0);
|
||||
}
|
||||
|
||||
public void KphSetHandleGrantedAccess(IntPtr handle, int grantedAccess)
|
||||
{
|
||||
byte* inData = stackalloc byte[8];
|
||||
|
||||
*(int*)inData = handle.ToInt32();
|
||||
*(int*)(inData + 4) = grantedAccess;
|
||||
|
||||
_fileHandle.IoControl(CtlCode(Control.KphSetHandleGrantedAccess), inData, 8, null, 0);
|
||||
}
|
||||
|
||||
public void KphSuspendProcess(ProcessHandle processHandle)
|
||||
{
|
||||
int processHandleInt = processHandle;
|
||||
|
||||
@@ -78,7 +78,17 @@ namespace ProcessHacker.Native.Objects
|
||||
/// <param name="access">The desired access to the job object.</param>
|
||||
public JobObjectHandle(ProcessHandle processHandle, JobObjectAccess access)
|
||||
{
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenProcessJob(processHandle, access));
|
||||
try
|
||||
{
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenProcessJob(processHandle, access));
|
||||
}
|
||||
catch (WindowsException)
|
||||
{
|
||||
// Use KPH to set the handle's granted access.
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenProcessJob(processHandle,
|
||||
(JobObjectAccess)StandardRights.Synchronize));
|
||||
KProcessHacker.Instance.KphSetHandleGrantedAccess(this.Handle, (int)access);
|
||||
}
|
||||
|
||||
if (this.Handle == IntPtr.Zero)
|
||||
Win32.ThrowLastError();
|
||||
|
||||
@@ -129,10 +129,28 @@ namespace ProcessHacker.Native.Objects
|
||||
/// <param name="access">The desired access to the process.</param>
|
||||
public ProcessHandle(int pid, ProcessAccess access)
|
||||
{
|
||||
// If we have KPH, use it.
|
||||
if (KProcessHacker.Instance != null)
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenProcess(pid, access));
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenProcess(pid, access));
|
||||
}
|
||||
catch (WindowsException)
|
||||
{
|
||||
// This would only happen if the process is DRM-protected or if
|
||||
// some part of ObReferenceObjectByHandle is hooked. We can
|
||||
// open the process with SYNCHRONIZE access and set the granted access
|
||||
// using KPH.
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenProcess(pid,
|
||||
(ProcessAccess)StandardRights.Synchronize));
|
||||
KProcessHacker.Instance.KphSetHandleGrantedAccess(this.Handle, (int)access);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Handle = Win32.OpenProcess(access, false, pid);
|
||||
}
|
||||
|
||||
if (this.Handle == IntPtr.Zero)
|
||||
Win32.ThrowLastError();
|
||||
|
||||
@@ -73,9 +73,23 @@ namespace ProcessHacker.Native.Objects
|
||||
public ThreadHandle(int tid, ThreadAccess access)
|
||||
{
|
||||
if (KProcessHacker.Instance != null)
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenThread((int)tid, access));
|
||||
{
|
||||
try
|
||||
{
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenThread(tid, access));
|
||||
}
|
||||
catch (WindowsException)
|
||||
{
|
||||
// Open the thread with minimum access (SYNCHRONIZE) and set the granted access.
|
||||
this.Handle = new IntPtr(KProcessHacker.Instance.KphOpenThread(tid,
|
||||
(ThreadAccess)StandardRights.Synchronize));
|
||||
KProcessHacker.Instance.KphSetHandleGrantedAccess(this.Handle, (int)access);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Handle = Win32.OpenThread(access, false, tid);
|
||||
}
|
||||
|
||||
if (this.Handle == IntPtr.Zero)
|
||||
Win32.ThrowLastError();
|
||||
|
||||
Reference in New Issue
Block a user