mirror of
https://github.com/mirror/processhacker
synced 2026-06-08 16:03:24 +00:00
bbe1014194
git-svn-id: svn://svn.code.sf.net/p/processhacker/code@2851 21ef857c-d57f-4fe0-8362-d861dc6d29cd
1779 lines
38 KiB
C
1779 lines
38 KiB
C
/*
|
|
* Process Hacker -
|
|
* KProcessHacker API
|
|
*
|
|
* Copyright (C) 2009-2010 wj32
|
|
*
|
|
* This file is part of Process Hacker.
|
|
*
|
|
* Process Hacker is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* Process Hacker is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with Process Hacker. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
#include <kph.h>
|
|
#include <wchar.h>
|
|
|
|
typedef struct _KPH_ZWQUERYOBJECT_BUFFER
|
|
{
|
|
NTSTATUS Status;
|
|
ULONG ReturnLength;
|
|
PVOID BufferBase;
|
|
CHAR Buffer[1];
|
|
} KPH_ZWQUERYOBJECT_BUFFER, *PKPH_ZWQUERYOBJECT_BUFFER;
|
|
|
|
NTSTATUS KphpDeviceIoControl(
|
|
HANDLE KphHandle,
|
|
ULONG KphControlCode,
|
|
PVOID InBuffer,
|
|
ULONG InBufferLength,
|
|
PVOID OutBuffer,
|
|
ULONG OutBufferLength,
|
|
PULONG ReturnLength
|
|
);
|
|
|
|
NTSTATUS KphConnect(
|
|
__out PHANDLE KphHandle,
|
|
__in_opt PWSTR DeviceName
|
|
)
|
|
{
|
|
UNICODE_STRING objectName;
|
|
OBJECT_ATTRIBUTES objectAttributes;
|
|
IO_STATUS_BLOCK isb;
|
|
|
|
if (DeviceName)
|
|
RtlInitUnicodeString(&objectName, DeviceName);
|
|
else
|
|
RtlInitUnicodeString(&objectName, KPH_DEVICE_NAME);
|
|
|
|
InitializeObjectAttributes(
|
|
&objectAttributes,
|
|
&objectName,
|
|
OBJ_CASE_INSENSITIVE,
|
|
NULL,
|
|
NULL
|
|
);
|
|
|
|
return NtOpenFile(
|
|
KphHandle,
|
|
FILE_GENERIC_READ | FILE_GENERIC_WRITE,
|
|
&objectAttributes,
|
|
&isb,
|
|
FILE_SHARE_READ | FILE_SHARE_WRITE,
|
|
FILE_NON_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphConnect2(
|
|
__out PHANDLE KphHandle,
|
|
__in_opt PWSTR DeviceName,
|
|
__in PWSTR FileName
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
WCHAR fullDeviceName[MAX_PATH + 1];
|
|
SC_HANDLE scmHandle;
|
|
SC_HANDLE serviceHandle;
|
|
BOOLEAN started = FALSE;
|
|
BOOLEAN created = FALSE;
|
|
|
|
if (!DeviceName)
|
|
DeviceName = L"KProcessHacker";
|
|
|
|
_snwprintf(fullDeviceName, MAX_PATH, L"\\Device\\%s", DeviceName);
|
|
|
|
// Try to open the device.
|
|
status = KphConnect(KphHandle, fullDeviceName);
|
|
|
|
if (NT_SUCCESS(status))
|
|
return status;
|
|
|
|
if (
|
|
status != STATUS_NO_SUCH_DEVICE &&
|
|
status != STATUS_NO_SUCH_FILE &&
|
|
status != STATUS_OBJECT_NAME_NOT_FOUND
|
|
)
|
|
return status;
|
|
|
|
// Load the driver, and try again.
|
|
|
|
// Try to start the service, if it exists.
|
|
|
|
scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CONNECT);
|
|
|
|
if (scmHandle)
|
|
{
|
|
serviceHandle = OpenService(scmHandle, DeviceName, SERVICE_START);
|
|
|
|
if (serviceHandle)
|
|
{
|
|
if (StartService(serviceHandle, 0, NULL))
|
|
started = TRUE;
|
|
|
|
CloseServiceHandle(serviceHandle);
|
|
}
|
|
|
|
CloseServiceHandle(scmHandle);
|
|
}
|
|
|
|
if (!started)
|
|
{
|
|
// Try to create the service.
|
|
|
|
scmHandle = OpenSCManager(NULL, NULL, SC_MANAGER_CREATE_SERVICE);
|
|
|
|
if (scmHandle)
|
|
{
|
|
serviceHandle = CreateService(
|
|
scmHandle,
|
|
DeviceName,
|
|
DeviceName,
|
|
SERVICE_ALL_ACCESS,
|
|
SERVICE_KERNEL_DRIVER,
|
|
SERVICE_DEMAND_START,
|
|
SERVICE_ERROR_IGNORE,
|
|
FileName,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
L""
|
|
);
|
|
|
|
if (serviceHandle)
|
|
{
|
|
created = TRUE;
|
|
StartService(serviceHandle, 0, NULL);
|
|
}
|
|
|
|
CloseServiceHandle(scmHandle);
|
|
}
|
|
}
|
|
|
|
// Try to open the device again.
|
|
status = KphConnect(KphHandle, fullDeviceName);
|
|
|
|
if (created)
|
|
{
|
|
// "Delete" the service. Since we (may) have a handle to
|
|
// the device, the SCM will delete the service automatically
|
|
// when it is stopped (upon reboot).
|
|
DeleteService(serviceHandle);
|
|
CloseServiceHandle(serviceHandle);
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphDisconnect(
|
|
__in HANDLE KphHandle
|
|
)
|
|
{
|
|
return NtClose(KphHandle);
|
|
}
|
|
|
|
NTSTATUS KphpDeviceIoControl(
|
|
HANDLE KphHandle,
|
|
ULONG KphControlCode,
|
|
PVOID InBuffer,
|
|
ULONG InBufferLength,
|
|
PVOID OutBuffer,
|
|
ULONG OutBufferLength,
|
|
PULONG ReturnLength
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
IO_STATUS_BLOCK ioStatusBlock;
|
|
|
|
status = NtDeviceIoControlFile(
|
|
KphHandle,
|
|
NULL,
|
|
NULL,
|
|
NULL,
|
|
&ioStatusBlock,
|
|
KphControlCode,
|
|
InBuffer,
|
|
InBufferLength,
|
|
OutBuffer,
|
|
OutBufferLength
|
|
);
|
|
|
|
if (NT_SUCCESS(status) && ReturnLength)
|
|
*ReturnLength = (ULONG)ioStatusBlock.Information;
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphGetFeatures(
|
|
__in HANDLE KphHandle,
|
|
__out PULONG Features
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
ULONG features;
|
|
|
|
if (NT_SUCCESS(status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETFEATURES,
|
|
NULL,
|
|
0,
|
|
&features,
|
|
sizeof(ULONG),
|
|
NULL
|
|
)))
|
|
*Features = features;
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphNtClose(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE Handle
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE Handle;
|
|
} args;
|
|
|
|
args.Handle = Handle;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_NtClose,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphSsQueryClientEntry(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ClientEntryHandle,
|
|
__out PKPHSS_CLIENT_INFORMATION ClientInformation,
|
|
__in ULONG ClientInformationLength,
|
|
__out PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ClientEntryHandle;
|
|
PKPHSS_CLIENT_INFORMATION ClientInformation;
|
|
ULONG ClientInformationLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ClientEntryHandle = ClientEntryHandle;
|
|
args.ClientInformation = ClientInformation;
|
|
args.ClientInformationLength = ClientInformationLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SSQUERYCLIENTENTRY,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphOpenProcess(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE ProcessHandle,
|
|
__in HANDLE ProcessId,
|
|
__in ACCESS_MASK DesiredAccess
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessId;
|
|
ACCESS_MASK DesiredAccess;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
} ret;
|
|
|
|
args.ProcessId = ProcessId;
|
|
args.DesiredAccess = DesiredAccess;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*ProcessHandle = ret.ProcessHandle;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphOpenThread(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE ThreadHandle,
|
|
__in HANDLE ThreadId,
|
|
__in ACCESS_MASK DesiredAccess
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ThreadId;
|
|
ACCESS_MASK DesiredAccess;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
} ret;
|
|
|
|
args.ThreadId = ThreadId;
|
|
args.DesiredAccess = DesiredAccess;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENTHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*ThreadHandle = ret.ThreadHandle;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphOpenProcessToken(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE TokenHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in ACCESS_MASK DesiredAccess
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
ACCESS_MASK DesiredAccess;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE TokenHandle;
|
|
} ret;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.DesiredAccess = DesiredAccess;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENPROCESSTOKEN,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*TokenHandle = ret.TokenHandle;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphGetProcessProtected(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessId,
|
|
__out PBOOLEAN IsProtected
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessId;
|
|
} args;
|
|
struct
|
|
{
|
|
BOOLEAN IsProtected;
|
|
} ret;
|
|
|
|
args.ProcessId = ProcessId;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETPROCESSPROTECTED,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*IsProtected = ret.IsProtected;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphSetProcessProtected(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessId,
|
|
__in BOOLEAN IsProtected
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessId;
|
|
BOOLEAN IsProtected;
|
|
} args;
|
|
|
|
args.ProcessId = ProcessId;
|
|
args.IsProtected = IsProtected;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETPROCESSPROTECTED,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphTerminateProcess(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in NTSTATUS ExitStatus
|
|
)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
NTSTATUS ExitStatus;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.ExitStatus = ExitStatus;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_TERMINATEPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
/* Check if we were trying to terminate the current
|
|
* process and do it now. */
|
|
if (status == STATUS_CANT_TERMINATE_SELF)
|
|
status = NtTerminateProcess(NtCurrentProcess(), ExitStatus);
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphSuspendProcess(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SUSPENDPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphResumeProcess(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_RESUMEPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphReadVirtualMemory(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in PVOID BaseAddress,
|
|
__out_bcount(BufferLength) PVOID Buffer,
|
|
__in ULONG BufferLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PVOID BaseAddress;
|
|
PVOID Buffer;
|
|
ULONG BufferLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.BaseAddress = BaseAddress;
|
|
args.Buffer = Buffer;
|
|
args.BufferLength = BufferLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_READVIRTUALMEMORY,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphWriteVirtualMemory(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in PVOID BaseAddress,
|
|
__in_bcount(BufferLength) PVOID Buffer,
|
|
__in ULONG BufferLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PVOID BaseAddress;
|
|
PVOID Buffer;
|
|
ULONG BufferLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.BaseAddress = BaseAddress;
|
|
args.Buffer = Buffer;
|
|
args.BufferLength = BufferLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_WRITEVIRTUALMEMORY,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphSetProcessToken(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE SourceProcessId,
|
|
__in HANDLE TargetProcessId
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE SourceProcessId;
|
|
HANDLE TargetProcessId;
|
|
} args;
|
|
|
|
args.SourceProcessId = SourceProcessId;
|
|
args.TargetProcessId = TargetProcessId;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETPROCESSTOKEN,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphGetThreadStartAddress(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__out PPVOID StartAddress
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
} args;
|
|
struct
|
|
{
|
|
PVOID StartAddress;
|
|
} ret;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETTHREADSTARTADDRESS,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*StartAddress = ret.StartAddress;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphSetHandleAttributes(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in HANDLE Handle,
|
|
__in ULONG Flags
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
HANDLE Handle;
|
|
ULONG Flags;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.Handle = Handle;
|
|
args.Flags = Flags;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETHANDLEATTRIBUTES,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphGetHandleObjectName(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in HANDLE Handle,
|
|
__out_bcount_opt(BufferLength) PUNICODE_STRING Buffer,
|
|
__in ULONG BufferLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
UNICODE_STRING buffer;
|
|
ULONG returnLength;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
HANDLE Handle;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.Handle = Handle;
|
|
|
|
if (Buffer && BufferLength >= sizeof(UNICODE_STRING))
|
|
{
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETHANDLEOBJECTNAME,
|
|
&args,
|
|
sizeof(args),
|
|
Buffer,
|
|
BufferLength,
|
|
&returnLength
|
|
);
|
|
|
|
Buffer->Buffer = (PWSTR)PTR_ADD_OFFSET(Buffer, sizeof(UNICODE_STRING));
|
|
|
|
if (ReturnLength)
|
|
{
|
|
if (status == STATUS_BUFFER_TOO_SMALL)
|
|
*ReturnLength = Buffer->Length;
|
|
else
|
|
*ReturnLength = returnLength;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
// User doesn't give us a buffer, or it was too small.
|
|
// Use our internal buffer.
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETHANDLEOBJECTNAME,
|
|
&args,
|
|
sizeof(args),
|
|
&buffer,
|
|
sizeof(UNICODE_STRING),
|
|
&returnLength
|
|
);
|
|
|
|
if (ReturnLength)
|
|
{
|
|
if (status == STATUS_BUFFER_TOO_SMALL)
|
|
*ReturnLength = buffer.Length;
|
|
else
|
|
*ReturnLength = returnLength;
|
|
}
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphOpenProcessJob(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE JobHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in ACCESS_MASK DesiredAccess
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
ACCESS_MASK DesiredAccess;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE JobHandle;
|
|
} ret;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.DesiredAccess = DesiredAccess;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENPROCESSJOB,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*JobHandle = ret.JobHandle;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphGetContextThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__inout PCONTEXT ThreadContext
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
PCONTEXT ThreadContext;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.ThreadContext = ThreadContext;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETCONTEXTTHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphSetContextThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in PCONTEXT ThreadContext
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
PCONTEXT ThreadContext;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.ThreadContext = ThreadContext;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETCONTEXTTHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphGetThreadWin32Thread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__out PPVOID Win32Thread
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
} args;
|
|
struct
|
|
{
|
|
PVOID Win32Thread;
|
|
} ret;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETTHREADWIN32THREAD,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*Win32Thread = ret.Win32Thread;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphDuplicateObject(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE SourceProcessHandle,
|
|
__in HANDLE SourceHandle,
|
|
__in_opt HANDLE TargetProcessHandle,
|
|
__out_opt PHANDLE TargetHandle,
|
|
__in ACCESS_MASK DesiredAccess,
|
|
__in ULONG HandleAttributes,
|
|
__in ULONG Options
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE SourceProcessHandle;
|
|
HANDLE SourceHandle;
|
|
HANDLE TargetProcessHandle;
|
|
PHANDLE TargetHandle;
|
|
ACCESS_MASK DesiredAccess;
|
|
ULONG HandleAttributes;
|
|
ULONG Options;
|
|
} args;
|
|
|
|
args.SourceProcessHandle = SourceProcessHandle;
|
|
args.SourceHandle = SourceHandle;
|
|
args.TargetProcessHandle = TargetProcessHandle;
|
|
args.TargetHandle = TargetHandle;
|
|
args.DesiredAccess = DesiredAccess;
|
|
args.HandleAttributes = HandleAttributes;
|
|
args.Options = Options;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_DUPLICATEOBJECT,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphZwQueryObject(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in HANDLE Handle,
|
|
__in OBJECT_INFORMATION_CLASS ObjectInformationClass,
|
|
__in_bcount_opt(BufferLength) PVOID Buffer,
|
|
__in ULONG BufferLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
HANDLE Handle;
|
|
OBJECT_INFORMATION_CLASS ObjectInformationClass;
|
|
} args;
|
|
PKPH_ZWQUERYOBJECT_BUFFER ret;
|
|
ULONG retLength;
|
|
|
|
// Make sure we understand the object information class
|
|
// because we will be fixing the buffer later.
|
|
if (
|
|
ObjectInformationClass != ObjectBasicInformation &&
|
|
ObjectInformationClass != ObjectNameInformation &&
|
|
ObjectInformationClass != ObjectTypeInformation
|
|
)
|
|
return STATUS_INVALID_INFO_CLASS;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.Handle = Handle;
|
|
args.ObjectInformationClass = ObjectInformationClass;
|
|
|
|
retLength = FIELD_OFFSET(KPH_ZWQUERYOBJECT_BUFFER, Buffer) + BufferLength;
|
|
ret = PhAllocate(retLength);
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_ZWQUERYOBJECT,
|
|
&args,
|
|
sizeof(args),
|
|
ret,
|
|
retLength,
|
|
NULL
|
|
);
|
|
|
|
// Make sure the actual I/O control request succeeded.
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
// Check if ZwQueryObject succeeded.
|
|
status = ret->Status;
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
if (Buffer)
|
|
{
|
|
// Copy the buffer contents to the user buffer.
|
|
memcpy(Buffer, ret->Buffer, ret->ReturnLength);
|
|
|
|
// Rebase pointers in the buffer.
|
|
if (ObjectInformationClass == ObjectNameInformation)
|
|
{
|
|
POBJECT_NAME_INFORMATION nameInfo = (POBJECT_NAME_INFORMATION)Buffer;
|
|
|
|
nameInfo->Name.Buffer = (PWSTR)REBASE_ADDRESS(
|
|
nameInfo->Name.Buffer,
|
|
ret->BufferBase,
|
|
Buffer
|
|
);
|
|
}
|
|
else if (ObjectInformationClass == ObjectTypeInformation)
|
|
{
|
|
POBJECT_TYPE_INFORMATION typeInfo = (POBJECT_TYPE_INFORMATION)Buffer;
|
|
|
|
typeInfo->TypeName.Buffer = (PWSTR)REBASE_ADDRESS(
|
|
typeInfo->TypeName.Buffer,
|
|
ret->BufferBase,
|
|
Buffer
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (ReturnLength)
|
|
*ReturnLength = ret->ReturnLength;
|
|
}
|
|
|
|
PhFree(ret);
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphGetProcessId(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in HANDLE Handle,
|
|
__out PHANDLE ProcessId
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
HANDLE Handle;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE ProcessId;
|
|
} ret;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.Handle = Handle;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETPROCESSID,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*ProcessId = ret.ProcessId;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphGetThreadId(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in HANDLE Handle,
|
|
__out PHANDLE ThreadId,
|
|
__out_opt PHANDLE ProcessId
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
HANDLE Handle;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE ThreadId;
|
|
HANDLE ProcessId;
|
|
} ret;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.Handle = Handle;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_GETTHREADID,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*ThreadId = ret.ThreadId;
|
|
|
|
if (ProcessId)
|
|
*ProcessId = ret.ProcessId;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphTerminateThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in NTSTATUS ExitStatus
|
|
)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
NTSTATUS ExitStatus;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.ExitStatus = ExitStatus;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_TERMINATETHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if (status == STATUS_CANT_TERMINATE_SELF)
|
|
status = NtTerminateThread(NtCurrentThread(), ExitStatus);
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphSetHandleGrantedAccess(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE Handle,
|
|
__in ACCESS_MASK GrantedAccess
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE Handle;
|
|
ACCESS_MASK GrantedAccess;
|
|
} args;
|
|
|
|
args.Handle = Handle;
|
|
args.GrantedAccess = GrantedAccess;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETHANDLEGRANTEDACCESS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphAssignImpersonationToken(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in HANDLE TokenHandle
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
HANDLE TokenHandle;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.TokenHandle = TokenHandle;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_ASSIGNIMPERSONATIONTOKEN,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphProtectAdd(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in BOOLEAN AllowKernelMode,
|
|
__in ACCESS_MASK ProcessAllowMask,
|
|
__in ACCESS_MASK ThreadAllowMask
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
LOGICAL AllowKernelMode;
|
|
ACCESS_MASK ProcessAllowMask;
|
|
ACCESS_MASK ThreadAllowMask;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.AllowKernelMode = AllowKernelMode;
|
|
args.ProcessAllowMask = ProcessAllowMask;
|
|
args.ThreadAllowMask = ThreadAllowMask;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_PROTECTADD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphProtectRemove(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_PROTECTREMOVE,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphProtectQuery(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__out PBOOLEAN AllowKernelMode,
|
|
__out PACCESS_MASK ProcessAllowMask,
|
|
__out PACCESS_MASK ThreadAllowMask
|
|
)
|
|
{
|
|
NTSTATUS status = STATUS_SUCCESS;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PLOGICAL AllowKernelMode;
|
|
PACCESS_MASK ProcessAllowMask;
|
|
PACCESS_MASK ThreadAllowMask;
|
|
} args;
|
|
LOGICAL allowKernelMode;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.AllowKernelMode = &allowKernelMode;
|
|
args.ProcessAllowMask = ProcessAllowMask;
|
|
args.ThreadAllowMask = ThreadAllowMask;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_PROTECTQUERY,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*AllowKernelMode = (BOOLEAN)allowKernelMode;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphUnsafeReadVirtualMemory(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in PVOID BaseAddress,
|
|
__in_bcount(BufferLength) PVOID Buffer,
|
|
__in ULONG BufferLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PVOID BaseAddress;
|
|
PVOID Buffer;
|
|
ULONG BufferLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.BaseAddress = BaseAddress;
|
|
args.Buffer = Buffer;
|
|
args.BufferLength = BufferLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_UNSAFEREADVIRTUALMEMORY,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphSetExecuteOptions(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in ULONG ExecuteOptions
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
ULONG ExecuteOptions;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.ExecuteOptions = ExecuteOptions;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETEXECUTEOPTIONS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphQueryProcessHandles(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__out_bcount_opt(BufferLength) PVOID Buffer,
|
|
__in_opt ULONG BufferLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PVOID Buffer;
|
|
ULONG BufferLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.Buffer = Buffer;
|
|
args.BufferLength = BufferLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_QUERYPROCESSHANDLES,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphOpenThreadProcess(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE ProcessHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in ACCESS_MASK DesiredAccess
|
|
)
|
|
{
|
|
NTSTATUS status;
|
|
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
ACCESS_MASK DesiredAccess;
|
|
} args;
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
} ret;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.DesiredAccess = DesiredAccess;
|
|
|
|
status = KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENTHREADPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
&ret,
|
|
sizeof(ret),
|
|
NULL
|
|
);
|
|
|
|
if (NT_SUCCESS(status))
|
|
{
|
|
*ProcessHandle = ret.ProcessHandle;
|
|
}
|
|
|
|
return status;
|
|
}
|
|
|
|
NTSTATUS KphCaptureStackBackTraceThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in ULONG FramesToSkip,
|
|
__in ULONG FramesToCapture,
|
|
__out_ecount(FramesToCapture) PPVOID BackTrace,
|
|
__out_opt PULONG CapturedFrames,
|
|
__out_opt PULONG BackTraceHash
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
ULONG FramesToSkip;
|
|
ULONG FramesToCapture;
|
|
PPVOID BackTrace;
|
|
PULONG CapturedFrames;
|
|
PULONG BackTraceHash;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.FramesToSkip = FramesToSkip;
|
|
args.FramesToCapture = FramesToCapture;
|
|
args.BackTrace = BackTrace;
|
|
args.CapturedFrames = CapturedFrames;
|
|
args.BackTraceHash = BackTraceHash;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_CAPTURESTACKBACKTRACETHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphDangerousTerminateThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in NTSTATUS ExitStatus
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
NTSTATUS ExitStatus;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.ExitStatus = ExitStatus;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_DANGEROUSTERMINATETHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphOpenType(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE TypeHandle,
|
|
__in POBJECT_ATTRIBUTES ObjectAttributes
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
PHANDLE TypeHandle;
|
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
|
} args;
|
|
|
|
args.TypeHandle = TypeHandle;
|
|
args.ObjectAttributes = ObjectAttributes;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENTYPE,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphOpenDriver(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE DriverHandle,
|
|
__in POBJECT_ATTRIBUTES ObjectAttributes
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
PHANDLE DriverHandle;
|
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
|
} args;
|
|
|
|
args.DriverHandle = DriverHandle;
|
|
args.ObjectAttributes = ObjectAttributes;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENDRIVER,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphQueryInformationDriver(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE DriverHandle,
|
|
__in DRIVER_INFORMATION_CLASS DriverInformationClass,
|
|
__out_bcount_opt(DriverInformationLength) PVOID DriverInformation,
|
|
__in ULONG DriverInformationLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE DriverHandle;
|
|
DRIVER_INFORMATION_CLASS DriverInformationClass;
|
|
PVOID DriverInformation;
|
|
ULONG DriverInformationLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.DriverHandle = DriverHandle;
|
|
args.DriverInformationClass = DriverInformationClass;
|
|
args.DriverInformation = DriverInformation;
|
|
args.DriverInformationLength = DriverInformationLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_QUERYINFORMATIONDRIVER,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphOpenDirectoryObject(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE DirectoryHandle,
|
|
__in ACCESS_MASK DesiredAccess,
|
|
__in POBJECT_ATTRIBUTES ObjectAttributes
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
PHANDLE DirectoryHandle;
|
|
ACCESS_MASK DesiredAccess;
|
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
|
} args;
|
|
|
|
args.DirectoryHandle = DirectoryHandle;
|
|
args.DesiredAccess = DesiredAccess;
|
|
args.ObjectAttributes = ObjectAttributes;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENDIRECTORYOBJECT,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphOpenNamedObject(
|
|
__in HANDLE KphHandle,
|
|
__out PHANDLE Handle,
|
|
__in ACCESS_MASK DesiredAccess,
|
|
__in POBJECT_ATTRIBUTES ObjectAttributes
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
PHANDLE Handle;
|
|
ACCESS_MASK DesiredAccess;
|
|
POBJECT_ATTRIBUTES ObjectAttributes;
|
|
} args;
|
|
|
|
args.Handle = Handle;
|
|
args.DesiredAccess = DesiredAccess;
|
|
args.ObjectAttributes = ObjectAttributes;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_OPENNAMEDOBJECT,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphQueryInformationProcess(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in PROCESS_INFORMATION_CLASS ProcessInformationClass,
|
|
__out_bcount_opt(ProcessInformationLength) PVOID ProcessInformation,
|
|
__in ULONG ProcessInformationLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PROCESS_INFORMATION_CLASS ProcessInformationClass;
|
|
PVOID ProcessInformation;
|
|
ULONG ProcessInformationLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.ProcessInformationClass = ProcessInformationClass;
|
|
args.ProcessInformation = ProcessInformation;
|
|
args.ProcessInformationLength = ProcessInformationLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_QUERYINFORMATIONPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphQueryInformationThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in THREAD_INFORMATION_CLASS ThreadInformationClass,
|
|
__out_bcount_opt(ThreadInformationLength) PVOID ThreadInformation,
|
|
__in ULONG ThreadInformationLength,
|
|
__out_opt PULONG ReturnLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
THREAD_INFORMATION_CLASS ThreadInformationClass;
|
|
PVOID ThreadInformation;
|
|
ULONG ThreadInformationLength;
|
|
PULONG ReturnLength;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.ThreadInformationClass = ThreadInformationClass;
|
|
args.ThreadInformation = ThreadInformation;
|
|
args.ThreadInformationLength = ThreadInformationLength;
|
|
args.ReturnLength = ReturnLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_QUERYINFORMATIONTHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphSetInformationProcess(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ProcessHandle,
|
|
__in PROCESS_INFORMATION_CLASS ProcessInformationClass,
|
|
__in_bcount(ProcessInformationLength) PVOID ProcessInformation,
|
|
__in ULONG ProcessInformationLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ProcessHandle;
|
|
PROCESS_INFORMATION_CLASS ProcessInformationClass;
|
|
PVOID ProcessInformation;
|
|
ULONG ProcessInformationLength;
|
|
} args;
|
|
|
|
args.ProcessHandle = ProcessHandle;
|
|
args.ProcessInformationClass = ProcessInformationClass;
|
|
args.ProcessInformation = ProcessInformation;
|
|
args.ProcessInformationLength = ProcessInformationLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETINFORMATIONPROCESS,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|
|
|
|
NTSTATUS KphSetInformationThread(
|
|
__in HANDLE KphHandle,
|
|
__in HANDLE ThreadHandle,
|
|
__in THREAD_INFORMATION_CLASS ThreadInformationClass,
|
|
__in_bcount(ThreadInformationLength) PVOID ThreadInformation,
|
|
__in ULONG ThreadInformationLength
|
|
)
|
|
{
|
|
struct
|
|
{
|
|
HANDLE ThreadHandle;
|
|
THREAD_INFORMATION_CLASS ThreadInformationClass;
|
|
PVOID ThreadInformation;
|
|
ULONG ThreadInformationLength;
|
|
} args;
|
|
|
|
args.ThreadHandle = ThreadHandle;
|
|
args.ThreadInformationClass = ThreadInformationClass;
|
|
args.ThreadInformation = ThreadInformation;
|
|
args.ThreadInformationLength = ThreadInformationLength;
|
|
|
|
return KphpDeviceIoControl(
|
|
KphHandle,
|
|
KPH_SETINFORMATIONTHREAD,
|
|
&args,
|
|
sizeof(args),
|
|
NULL,
|
|
0,
|
|
NULL
|
|
);
|
|
}
|