#include "ntddk.h"
#include "ldasm.h"
const WCHAR DeviceName[]=L"\\Device\\protect";
const WCHAR DeviceLink[]=L"\\DosDevices\\protect";
#pragma pack(1)
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
PULONG_PTR Base;
PULONG Count;
ULONG Limit;
#if defined(_IA64_)
LONG TableBaseGpOffset;
#endif
PUCHAR Number;
} KSERVICE_TABLE_DESCRIPTOR, *PKSERVICE_TABLE_DESCRIPTOR;
#pragma pack()
KSERVICE_TABLE_DESCRIPTOR NTSYSAPI KeServiceDescriptorTable;
PMDL MDLSystemCall;
PULONG MappedSystemCallTable;
LARGE_INTEGER m_UserTime;
LARGE_INTEGER m_KernelTime;
PCHAR output;
PCHAR protect;
LONG pid;
KEVENT event;
#define IOCTL_PROCESS_INFORMATION_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1000, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_PROCESS_NUMBER_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1001, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HOOKAPI_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1002, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_UNHOOKAPI_CONTROL CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1003, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HOOKAPI_CONTROL1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1004, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_UNHOOKAPI_CONTROL1 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1005, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_HOOKAPI_CONTROL2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1006, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define IOCTL_UNHOOKAPI_CONTROL2 CTL_CODE(FILE_DEVICE_UNKNOWN, 0x1007, METHOD_BUFFERED, FILE_ANY_ACCESS)
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.Base[ *(PULONG)((PUCHAR)_function+1) ]
#define SYSCALL_INDEX(_Function) *(PULONG)((PUCHAR)_Function+1)
#define HOOK_SYSCALL(_Index, _Hook, _Orig ) \
_Orig = InterlockedExchange( (PLONG) &MappedSystemCallTable[_Index], (LONG) _Hook)
#define UNHOOK_SYSCALL(_Index, _Hook, _Orig ) \
InterlockedExchange( (PLONG) &MappedSystemCallTable[_Index], (LONG) _Hook)
typedef struct _SYSTEM_THREAD {
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientId;
KPRIORITY Priority;
LONG BasePriority;
ULONG ContextSwitchCount;
ULONG State;
KWAIT_REASON WaitReason;
} SYSTEM_THREAD, *PSYSTEM_THREAD;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
ULONG NumberOfThreads;
LARGE_INTEGER Reserved[3];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ImageName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
ULONG PrivatePageCount;
VM_COUNTERS VirtualMemoryCounters;
IO_COUNTERS IoCounters;
SYSTEM_THREAD Threads[0];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;
typedef struct _SYSTEM_PROCESSOR_TIMES {
LARGE_INTEGER IdleTime;
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER DpcTime;
LARGE_INTEGER InterruptTime;
ULONG InterruptCount;
} SYSTEM_PROCESSOR_TIMES, *PSYSTEM_PROCESSOR_TIMES;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemBasicInformation = 0,
SystemCpuInformation = 1,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3, /* was SystemTimeInformation */
Unknown4,
SystemProcessInformation = 5,
Unknown6,
Unknown7,
SystemProcessorPerformanceInformation = 8,
Unknown9,
Unknown10,
SystemModuleInformation = 11,
Unknown12,
Unknown13,
Unknown14,
Unknown15,
SystemHandleInformation = 16,
Unknown17,
SystemPageFileInformation = 18,
Unknown19,
Unknown20,
SystemCacheInformation = 21,
Unknown22,
SystemInterruptInformation = 23,
SystemDpcBehaviourInformation = 24,
SystemFullMemoryInformation = 25,
SystemNotImplemented6 = 25,
SystemLoadImage = 26,
SystemUnloadImage = 27,
SystemTimeAdjustmentInformation = 28,
SystemTimeAdjustment = 28,
SystemSummaryMemoryInformation = 29,
SystemNotImplemented7 = 29,
SystemNextEventIdInformation = 30,
SystemNotImplemented8 = 30,
SystemEventIdsInformation = 31,
SystemCrashDumpInformation = 32,
SystemExceptionInformation = 33,
SystemCrashDumpStateInformation = 34,
SystemKernelDebuggerInformation = 35,
SystemContextSwitchInformation = 36,
SystemRegistryQuotaInformation = 37,
SystemCurrentTimeZoneInformation = 44,
SystemTimeZoneInformation = 44,
SystemLookasideInformation = 45,
SystemSetTimeSlipEvent = 46,
SystemCreateSession = 47,
SystemDeleteSession = 48,
SystemInvalidInfoClass4 = 49,
SystemRangeStartInformation = 50,
SystemVerifierInformation = 51,
SystemAddVerifier = 52,
SystemSessionProcessesInformation = 53,
SystemInformationClassMax
} SYSTEM_INFORMATION_CLASS, *PSYSTEM_INFORMATION_CLASS;
typedef
NTSTATUS
(NTAPI
*ZWQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN SIZE_T Length,
OUT PSIZE_T ResultLength
);
typedef
NTSTATUS
(NTAPI
*ZWCREATESECTION)(
OUT PHANDLE SectionHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER MaximumSize OPTIONAL,
IN ULONG SectionPageProtection,
IN ULONG AllocationAttributes,
IN HANDLE FileHandle OPTIONAL);
typedef
NTSTATUS
(NTAPI
*ZWOPENPROCESS)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId OPTIONAL
);
NTSTATUS
NTAPI
ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN SIZE_T Length,
OUT PSIZE_T ResultLength);
ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;
ZWCREATESECTION OldZwCreateSection;
ZWOPENPROCESS OldZwOpenProcess;
NTSTATUS
NTAPI
Fake_ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN SIZE_T Length,
OUT PSIZE_T ResultLength
)
{
NTSTATUS Status;
UNICODE_STRING process_name;
RtlInitUnicodeString(&process_name, L"TestSys.exe");
Status = OldZwQuerySystemInformation(
SystemInformationClass,
SystemInformation,
Length,
ResultLength
);
if(NT_SUCCESS(Status))
{
if(SystemInformationClass == SystemProcessInformation)
{
struct _SYSTEM_PROCESS_INFORMATION *curr = (struct _SYSTEM_PROCESS_INFORMATION *)SystemInformation;
struct _SYSTEM_PROCESS_INFORMATION *prev = NULL;
if(curr->NextEntryOffset)
((char *)curr += curr->NextEntryOffset);
while(curr)
{
if (curr->ImageName.Buffer != NULL)
{
if (RtlEqualUnicodeString(&process_name, &curr->ImageName, TRUE))
{
m_UserTime.QuadPart += curr->UserTime.QuadPart;
m_KernelTime.QuadPart += curr->KernelTime.QuadPart;
if(prev) // Middle or Last entry
{
if(curr->NextEntryOffset)
prev->NextEntryOffset += curr->NextEntryOffset;
else // we are last, so make prev the end
prev->NextEntryOffset = 0;
}
else
{
if(curr->NextEntryOffset)
{
// we are first in the list, so move it forward
(char *)SystemInformation += curr->NextEntryOffset;
}
else // we are the only process!