* 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:
wj32
2009-05-09 11:57:47 +00:00
parent 25cfaf3415
commit 6eaaa3deb8
13 changed files with 149 additions and 6 deletions
+1
View File
@@ -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.
+6
View File
@@ -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)
+5
View File
@@ -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(
+1
View File
@@ -96,6 +96,7 @@ EXT ULONG OffEpObjectTable;
EXT ULONG OffEpProtectedProcessOff;
EXT ULONG OffEpProtectedProcessBit;
EXT ULONG OffEpRundownProtect;
EXT ULONG OffOhBody;
EXT ULONG OffOtiGenericMapping;
/* Functions
+28
View File
@@ -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.
+48 -1
View File
@@ -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.
+3
View File
@@ -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,
+11 -1
View File
@@ -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();