www.pudn.com > CallMsgRing0.rar > CallMsgRing0.c, change:2005-03-12,size:15916b


// CallMsgRing0.c 
// 
// Generated by C DriverWizard 3.2.0 (Build 2485) 
// Requires DDK Only 
// File created on 3/12/2005 
// 
 
#include "pch.h" 
#include "..\intrface.h" 
#ifdef CALLMSGRING0_WMI_TRACE 
#include "CallMsgRing0.tmh" 
#endif 
 
// global data 
CALLMSGRING0_DATA g_Data; 
 
#define HOOKINT 0x0f0 
 
/* Buffer to store result of sidt instruction */ 
char buffer[6]; 
 
/* Pointer to structure to identify the limit and base of IDTR*/ 
PIdtr_t Idtr=(PIdtr_t)buffer; 
IdtEntry OldEntry; 
PIdtEntry pIdtEntry; 
ULONG count; 
PVOID NewHandler,TMP; 
DWORD cur,tss_ring0esp; 
WORD tr; 
void __declspec(naked) cfunc(PVOID addr,PVOID stack) 
{ 
	_asm enter 256,0 
	_asm pushfd 
	_asm pushad 
		_asm sidt buffer 
		pIdtEntry = (PIdtEntry)Idtr->Base; 
	OldEntry = pIdtEntry[HOOKINT];  //#define HOOKINT 0xF0 
	_asm lea eax,interrupt 
		_asm mov NewHandler,eax 
		/*接管中断0xF0,目的是让应用程序能通过使用int 0f0h 
		指令返回到核心态。 
		int 0f0h起的作用正是等同于ret 
		F0陷阱的处理函数恢复内核栈等至“调用”前的状态*/ 
		_asm cli 
		pIdtEntry[HOOKINT].Dpl        = 3; 
	pIdtEntry[HOOKINT].Type       = 0xF; 
	pIdtEntry[HOOKINT].Present    = 1; 
	pIdtEntry[HOOKINT].OffsetLow  = (unsigned short)NewHandler; 
	pIdtEntry[HOOKINT].OffsetHigh = \ 
		(unsigned short)((unsigned int)NewHandler>>16); 
	_asm sti 
		_asm { 
			str word ptr[tr] 
			push eax 
				sgdt [esp-2] 
				pop eax 
					movzx ebx,word ptr[tr] 
					and ebx,0fffffff8h 
						add eax,ebx 
						mov ebx,[eax] 
						and ebx,0ffff0000h 
							shr ebx,16 
							mov ecx,[eax+4] 
							and ecx,0ffh 
								shl ecx,16 
								or ebx,ecx 
								mov ecx,[eax+4] 
								and ecx,0ff000000h 
									or ebx,ecx  //tss base 
									mov ebx,[ebx+4]    
									mov tss_ring0esp,ebx 
									mov cur,esp 
		} 
		count=tss_ring0esp-cur; 
		TMP=(PVOID)ExAllocatePool(  NonPagedPool,count); 
		if(!TMP) goto exit; 
		/*上面代码获取当前内核栈的地址与需保存大小 
		下面代码保存栈内容*/ 
		_asm{ 
			mov ecx,count 
				mov edi,TMP 
				mov esi,cur 
				cld 
				rep movsb 
		} 
		/*模拟返回环境,不用多解释了 
		iretd我们把它类比于call*/ 
		_asm{ 
			mov eax,3bh 
				mov fs,ax 
				mov eax,23h 
				push eax 
				mov eax,stack 
				push eax 
				pushfd 
				mov eax,1bh 
				push eax 
				mov eax,addr 
				push eax 
				iretd 
		} 
		/*int 0f0h后返回这里开始执行*/ 
interrupt: 
		_asm{ 
			mov eax,30h 
				mov fs,ax 
				mov ecx,count 
				mov esi,TMP 
				mov edi,cur 
				cld 
				rep movsb 
				mov esp,cur 
		} 
		_asm cli 
			pIdtEntry[HOOKINT] = OldEntry; 
		_asm sti 
exit: 
			_asm popad 
			_asm popfd 
			_asm leave 
			_asm ret 8 
} 
 
 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  DriverEntry  
//      Installable driver initialization entry point. 
//      This entry point is called directly by the I/O system. 
// 
//  Arguments: 
//      IN  DriverObject 
//              pointer to the driver object 
// 
//      IN  RegistryPath 
//              pointer to a unicode string representing the path, 
//              to driver-specific key in the registry. 
// 
//  Return Value: 
//      Status 
// 
NTSTATUS DriverEntry( 
    IN  PDRIVER_OBJECT  DriverObject, 
    IN  PUNICODE_STRING RegistryPath 
    ) 
{ 
    NTSTATUS                            status; 
    PDEVICE_OBJECT                      deviceObject; 
    PCALLMSGRING0_DEVICE_EXTENSION   deviceExtension; 
    UNICODE_STRING                      ntName; 
    UNICODE_STRING                      win32Name; 
 
    CallMsgRing0DebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"++"); 
    CallMsgRing0DebugPrint(DBG_INIT, DBG_INFO, "Compiled at %s on %s", __TIME__, __DATE__); 
 
#ifdef DBG 
//    DbgBreakPoint(); 
#endif 
 
#ifdef CALLMSGRING0_WMI_TRACE  
    WPP_INIT_TRACING(DriverObject, RegistryPath); 
#endif 
 
    RtlZeroMemory(&g_Data, sizeof(CALLMSGRING0_DATA)); 
 
    // save registry path 
    g_Data.RegistryPath.Length = RegistryPath->Length; 
    g_Data.RegistryPath.MaximumLength = RegistryPath->Length + sizeof(UNICODE_NULL); 
    g_Data.RegistryPath.Buffer = (PWCHAR)ExAllocatePoolWithTag( 
                                            PagedPool, 
                                            g_Data.RegistryPath.MaximumLength, 
                                            CALLMSGRING0_POOL_TAG 
                                            ); 
 
    if (g_Data.RegistryPath.Buffer == NULL) 
    { 
        status = STATUS_INSUFFICIENT_RESOURCES; 
 
        CallMsgRing0DebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__": Failed to allocate memory for RegistryPath"); 
 
        return status; 
    } 
 
    RtlCopyUnicodeString(&g_Data.RegistryPath, RegistryPath); 
 
    // setup our dispatch function table in the driver object 
    DriverObject->MajorFunction[IRP_MJ_CREATE] = CallMsgRing0CreateDispatch; 
    DriverObject->MajorFunction[IRP_MJ_CLOSE] = CallMsgRing0CloseDispatch; 
    DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = CallMsgRing0DeviceIoControlDispatch; 
    DriverObject->MajorFunction[IRP_MJ_CLEANUP] = CallMsgRing0CleanupDispatch; 
    DriverObject->MajorFunction[IRP_MJ_SHUTDOWN] = CallMsgRing0ShutdownDispatch; 
    DriverObject->DriverUnload = CallMsgRing0Unload; 
 
    // initialize device name 
    RtlInitUnicodeString(&ntName, L"\\Device\\CallMsgRing0Device"); 
 
    // Create our function device object. 
    status = IoCreateDevice( 
                DriverObject, 
                sizeof (CALLMSGRING0_DEVICE_EXTENSION), 
                &ntName, 
                FILE_DEVICE_UNKNOWN, 
                0, 
                FALSE, 
                &deviceObject 
                ); 
 
    if (!NT_SUCCESS (status))  
    { 
        ExFreePool(g_Data.RegistryPath.Buffer); 
        g_Data.RegistryPath.Buffer = NULL; 
 
        CallMsgRing0DebugPrint(DBG_INIT, DBG_ERR, __FUNCTION__"--. STATUS %x", status); 
 
        return status; 
    } 
 
    // Initialize the device extension. 
    deviceExtension = (PCALLMSGRING0_DEVICE_EXTENSION)deviceObject->DeviceExtension; 
 
    // Zero the memory 
    RtlZeroMemory(deviceExtension, sizeof(CALLMSGRING0_DEVICE_EXTENSION)); 
 
    // save our device object pointer 
    deviceExtension->DeviceObject = deviceObject; 
 
    // This flag sets the buffering method for reads and writes 
    // to METHOD_DIRECT.  IOCTLs are handled by IO control codes 
    // independent of the value of this flag. 
    deviceObject->Flags |= DO_DIRECT_IO; 
 
    RtlInitUnicodeString(&win32Name, L"\\??\\CallMsgRing0Device"); 
    status = IoCreateSymbolicLink(&win32Name, &ntName); 
    if (!NT_SUCCESS(status)) 
    { 
        IoDeleteDevice(deviceObject); 
 
        ExFreePool(g_Data.RegistryPath.Buffer); 
        g_Data.RegistryPath.Buffer = NULL; 
 
        return status; 
    } 
 
    IoRegisterShutdownNotification(deviceObject); 
 
    CallMsgRing0DebugPrint(DBG_INIT, DBG_TRACE, __FUNCTION__"--. STATUS %x", status); 
 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0CreateDispatch 
//      Dispatch routine for IRP_MJ_CREATE requests. 
// 
//  Arguments: 
//      IN  DeviceObject 
//              pointer to the device object for our device 
// 
//      IN  Irp 
//              the create IRP 
// 
//  Return Value: 
//      NT status code. 
// 
NTSTATUS CallMsgRing0CreateDispatch( 
    IN  PDEVICE_OBJECT  DeviceObject, 
    IN  PIRP            Irp 
    ) 
{ 
    PCALLMSGRING0_DEVICE_EXTENSION    deviceExtension; 
    NTSTATUS                        status; 
 
    CallMsgRing0DebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp); 
 
    deviceExtension = (PCALLMSGRING0_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 
 
    InterlockedIncrement(&deviceExtension->OpenHandleCount); 
 
    status = STATUS_SUCCESS; 
 
    Irp->IoStatus.Information = 0; 
    Irp->IoStatus.Status = status; 
    IoCompleteRequest(Irp, IO_NO_INCREMENT); 
 
    CallMsgRing0DebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status); 
 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0CloseDispatch 
//      Dispatch routine for IRP_MJ_CLOSE requests. 
// 
//  Arguments: 
//      IN  DeviceObject 
//              pointer to the device object for our device 
// 
//      IN  Irp 
//              the close IRP 
// 
//  Return Value: 
//      NT status code. 
// 
NTSTATUS CallMsgRing0CloseDispatch( 
    IN  PDEVICE_OBJECT  DeviceObject, 
    IN  PIRP            Irp 
    ) 
{ 
    PCALLMSGRING0_DEVICE_EXTENSION    deviceExtension; 
    NTSTATUS                        status; 
 
    CallMsgRing0DebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp); 
 
    deviceExtension = (PCALLMSGRING0_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 
 
    status = STATUS_SUCCESS; 
 
    Irp->IoStatus.Information = 0; 
    Irp->IoStatus.Status = status; 
    IoCompleteRequest (Irp, IO_NO_INCREMENT); 
 
    InterlockedDecrement(&deviceExtension->OpenHandleCount); 
 
    CallMsgRing0DebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p, STATUS %x", Irp, status); 
 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0CleanupDispatch 
//      Dispatch routine for IRP_MJ_CLEANUP requests. 
// 
//  Arguments: 
//      IN  DeviceObject 
//              pointer to the device object for our device 
// 
//      IN  Irp 
//              the create IRP 
// 
//  Return Value: 
//      NT status code. 
// 
NTSTATUS CallMsgRing0CleanupDispatch( 
    IN  PDEVICE_OBJECT  DeviceObject, 
    IN  PIRP            Irp 
    ) 
{ 
    PCALLMSGRING0_DEVICE_EXTENSION    deviceExtension; 
    NTSTATUS                status; 
    PIO_STACK_LOCATION      irpStack; 
 
    CallMsgRing0DebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp); 
 
    deviceExtension = (PCALLMSGRING0_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 
 
    irpStack = IoGetCurrentIrpStackLocation(Irp); 
    CallMsgRing0FlushQueues(deviceExtension, irpStack->FileObject); 
 
    status = STATUS_SUCCESS; 
 
    Irp->IoStatus.Information = 0; 
    Irp->IoStatus.Status = status; 
    IoCompleteRequest(Irp, IO_NO_INCREMENT); 
 
    CallMsgRing0DebugPrint(DBG_CREATECLOSE, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status); 
 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0Unload 
//      Driver unload callback. 
// 
//  Arguments: 
//      IN  DriverObject 
//              pointer to the driver object 
// 
//  Return Value: 
//      none 
// 
VOID CallMsgRing0Unload( 
    IN  PDRIVER_OBJECT  DriverObject 
    ) 
{ 
    UNICODE_STRING  win32Name; 
 
    CallMsgRing0DebugPrint(DBG_UNLOAD, DBG_TRACE, __FUNCTION__"++"); 
 
    RtlInitUnicodeString(&win32Name, L"\\??\\CallMsgRing0Device"); 
    IoDeleteSymbolicLink(&win32Name); 
 
    IoUnregisterShutdownNotification(DriverObject->DeviceObject); 
 
    IoDeleteDevice(DriverObject->DeviceObject); 
 
    // The device object(s) should be NULL now 
    // (since we unload, all the devices objects associated with this 
    // driver must be deleted. 
    ASSERT(DriverObject->DeviceObject == NULL); 
 
    // We should not be unloaded until all the devices we control 
    // have been removed from our queue. 
 
    // release memory block allocated for registry path 
    if (g_Data.RegistryPath.Buffer != NULL) 
    { 
        ExFreePool(g_Data.RegistryPath.Buffer); 
        g_Data.RegistryPath.Buffer = NULL; 
    } 
 
    CallMsgRing0DebugPrint(DBG_UNLOAD, DBG_TRACE, __FUNCTION__"--"); 
 
#ifdef CALLMSGRING0_WMI_TRACE 
    WPP_CLEANUP(DriverObject); 
#endif 
 
    return; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0DeviceIoControlDispatch 
//      Dispatch routine for IRP_MJ_DEVICE_CONTROL requests. 
// 
//  Arguments: 
//      IN  DeviceObject 
//              pointer to the device object for our device 
// 
//      IN  Irp 
//              the device i/o control IRP 
// 
//  Return Value: 
//      NT status code. 
// 
NTSTATUS CallMsgRing0DeviceIoControlDispatch( 
    IN  PDEVICE_OBJECT  DeviceObject, 
    IN  PIRP            Irp 
    ) 
{ 
    PIO_STACK_LOCATION              irpStack; 
    NTSTATUS                        status; 
    PCALLMSGRING0_DEVICE_EXTENSION    deviceExtension; 
    PVOID                           inputBuffer; 
    ULONG                           inputLength; 
    PVOID                           outputBuffer; 
    ULONG                           outputLength; 
     
	PVOID addr,stack; 
 
    CallMsgRing0DebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp); 
 
    deviceExtension = (PCALLMSGRING0_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 
 
    // Get our IRP stack location 
    irpStack = IoGetCurrentIrpStackLocation(Irp); 
 
    // Get the buffer lengths 
    inputLength = irpStack->Parameters.DeviceIoControl.InputBufferLength; 
    outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength; 
 
    switch (irpStack->Parameters.DeviceIoControl.IoControlCode)  
    { 
 
	case IOCTL_CALL_RING3: 
		CallMsgRing0DebugPrint(DBG_IO, DBG_INFO, __FUNCTION__": IOCTL_CALL_RING3"); 
 
		// buffered ioctl 
		inputBuffer = Irp->AssociatedIrp.SystemBuffer; 
		outputBuffer = Irp->AssociatedIrp.SystemBuffer; 
 
		addr = *(PVOID*)(inputBuffer); //ring3函数地址 
		stack = *((PVOID*)(inputBuffer)+1);//ring3栈地址 
		cfunc(addr,stack); 
 
 
		status = STATUS_SUCCESS; 
		Irp->IoStatus.Information = 0; 
		Irp->IoStatus.Status = status; 
		IoCompleteRequest (Irp, IO_NO_INCREMENT); 
 
		break; 
 
    default: 
        status = STATUS_INVALID_DEVICE_REQUEST; 
        Irp->IoStatus.Status = status; 
        IoCompleteRequest (Irp, IO_NO_INCREMENT); 
        break; 
    } 
 
    CallMsgRing0DebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status); 
 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0ShutdownDispatch 
//      Dispatch routine for IRP_MJ_SHUTDOWN requests. 
// 
//  Arguments: 
//      IN  DeviceObject 
//              pointer to the device object for our device 
// 
//      IN  Irp 
//              the shutdown IRP 
// 
//  Return Value: 
//      NT status code. 
// 
NTSTATUS CallMsgRing0ShutdownDispatch( 
    IN  PDEVICE_OBJECT  DeviceObject, 
    IN  PIRP            Irp 
    ) 
{ 
    NTSTATUS                        status; 
    PCALLMSGRING0_DEVICE_EXTENSION    deviceExtension; 
 
    CallMsgRing0DebugPrint(DBG_GENERAL, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp); 
 
    deviceExtension = (PCALLMSGRING0_DEVICE_EXTENSION)DeviceObject->DeviceExtension; 
 
    status = STATUS_NOT_IMPLEMENTED; 
 
    Irp->IoStatus.Status = status; 
    Irp->IoStatus.Information = 0; 
    IoCompleteRequest (Irp, IO_NO_INCREMENT); 
 
    CallMsgRing0DebugPrint(DBG_GENERAL, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status); 
 
    return status; 
} 
 
/////////////////////////////////////////////////////////////////////////////////////////////////// 
//  CallMsgRing0FlushQueues 
//      Flush oustanding IRPs for closed file object. 
// 
//  Arguments: 
//      IN  DeviceExtension 
//              our device extension 
// 
//      IN  FileObject 
//              about to be closed file object 
// 
//  Return Value: 
//      none 
// 
VOID CallMsgRing0FlushQueues( 
    IN  PCALLMSGRING0_DEVICE_EXTENSION   DeviceExtension, 
    IN  PFILE_OBJECT            FileObject 
    ) 
{ 
    ULONG   index; 
 
    CallMsgRing0DebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"++"); 
 
    CallMsgRing0DebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--"); 
 
    return; 
}