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;
}