很早前 写的一个设备栈过滤驱动 也可以叫做劫持 可以干很猥琐的事情
#include <ntddk.h>
//比较注册表,并打印LOG
ULONG __stdcall OutLog(PUNICODE_STRING DriverServiceName)
{
UNICODE_STRING CmpRegistryPath;
DbgPrint("LOG:%ws",DriverServiceName->Buffer);
RtlInitUnicodeString(&CmpRegistryPath,L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Services\\xxxxxx");//是否为要修改的驱动,以注册表判断
return RtlCompareUnicodeString(&CmpRegistryPath,DriverServiceName,FALSE);
}
ULONG JmpXXX;
ULONG DVREntry;
__declspec(naked) MyDriverEntry()
{
__asm
{
pushad
pushfd
mov eax,dword ptr[ebp-90h]
push eax
call OutLog
cmp eax,0
jnz NOJE
mov eax,[DVREntry]
mov dword Ptr[edi+2Ch],eax
NOJE:
popfd
popad
push dword ptr[ebp-90h]
push edi
jmp [JmpXXX]
}
}
void HookLoadDvr()
{
ULONG uIoLoadAddress;
char NewCode[] = {0xe9,0x00,0x00,0x00,0x00,0x00,0x00};
int j;
char* PmemAddress;
uIoLoadAddress = 0x80580ba8;//本机的IopLoadDriver地址 测试用直接写的
uIoLoadAddress+=0x662; //Hook MemAddress
*(ULONG*)(&NewCode[1]) = (ULONG)MyDriverEntry - 5 - uIoLoadAddress;
JmpXXX = uIoLoadAddress+7;//跳回去的地址
PmemAddress = (char*)uIoLoadAddress;
__asm{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
for(j=0;j<5;j++)
{
PmemAddress[j] = NewCode[j];
}
__asm{
mov eax,cr0
or eax,10000h
mov cr0,eax
sti
}
}
void Unload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("Unload~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
}
NTSTATUS cppDisPatch(PDEVICE_OBJECT device,PIRP irp);
//默认为INIT
#pragma code_seg("PAGE")
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject , IN PUNICODE_STRING RegistryPath)
{
UNICODE_STRING CmpRegistryPath;
int i;
NTSTATUS status;
UNICODE_STRING DveName;
UNICODE_STRING LinkName;
PDEVICE_OBJECT pDevObj;
DbgPrint("DriverEntry~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n");
RtlInitUnicodeString(&CmpRegistryPath,L"\\REGISTRY\\MACHINE\\SYSTEM\\ControlSet001\\Services\\xxxxxx");
//比较下注册表是自己的入口还是HOOK的入口
if(RtlCompareUnicodeString(&CmpRegistryPath,RegistryPath,FALSE) != 0)
{//如果是自己的入口 就定位驱动入口地址 并 HOOK
// DVREntry = DriverObject->DriverInit;//这里的入口地址前面还有一小段引导代码,但是第2次执行入口的时候,那段代码就被注销了
DVREntry = (ULONG)DriverEntry;
DbgPrint(" DriverEntry Address = %08X~~~~\n",DriverEntry);
HookLoadDvr();
DriverObject->DriverUnload=Unload;
return STATUS_SUCCESS;
}
//如果是HOOK的驱动的入口会到这里
for(i = 0;i < IRP_MJ_MAXIMUM_FUNCTION ; i++)
{
DriverObject -> MajorFunction = cppDisPatch;
}
DriverObject->DriverUnload=Unload;
RtlInitUnicodeString(&DveName,L"\\Device\\XXXXXXXXXXXXXX");
status = IoCreateDevice(DriverObject,
NULL,
&DveName,
FILE_DEVICE_UNKNOWN,
0,TRUE,
&pDevObj);
if(!NT_SUCCESS(status))
{
DbgPrint("IoCreateDevice Error*********************************************\n");
return status;
}
pDevObj->Flags |= DO_BUFFERED_IO;
RtlInitUnicodeString(&LinkName,L"\\??\\XXXXXXXXXXXXXXX");
status = IoCreateSymbolicLink(&LinkName,&DveName);
if(!NT_SUCCESS(status))
{
DbgPrint("IoCreateSymbolicLink Error*********************************************\n");
return status;
}
return STATUS_SUCCESS;
}
NTSTATUS cppDisPatch(PDEVICE_OBJECT device,PIRP irp)
{
ULONG InputLen;
ULONG OutputLen;
ULONG CtlCode;
UCHAR* buffer;
UCHAR function;
ULONG t_OutLen;
PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(irp);
InputLen = irpsp->Parameters.DeviceIoControl.InputBufferLength;//输入缓冲区
OutputLen = irpsp->Parameters.DeviceIoControl.OutputBufferLength;//输出缓冲区
CtlCode = irpsp->Parameters.DeviceIoControl.IoControlCode;//控制代码
buffer = (UCHAR*)irp->AssociatedIrp.SystemBuffer;//获得缓冲区
function = irpsp->MajorFunction;//IRP类型
t_OutLen = 0;
switch (CtlCode)
{
case 0xXXXXXX:
{//模拟
}
case 0xXXXXXX:
{//模拟
}
}
irp->IoStatus.Status = STATUS_SUCCESS;
irp->IoStatus.Information = t_OutLen;
IoCompleteRequest(irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}