//把IofCallDriver开头指令拷贝下来,移到我们自己地中继函数中
//把IofCallDriver开头写入跳转指令跳转到我的中继函数
//中继函数中执行对我自己的IofCallDriver钩子函数的调用
//中继函数中执行原来的IofCallDriver函数中拷贝过来的几条指令
//跳转回到原来的IofCallDriver后开始的跳转点继续执行
//#include "xde.h"
#include "xde.c"
#include "ntddk.h"
#include <wdm.h>
//2
ULONG *g_new_address=NULL;
ULONG *g_new_address1=NULL;
VOID my_address();
//先调用一便
MyVistaIoCallDriverRelay()
{
__asm{
push old_codes
pop g_new_address
push old_codes1
pop g_new_address1
}
DbgPrint(("ENTER MyVistaIoCallDriverRelay/n"));
__asm
{
old_codes:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
old_codes1:
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
nop
}
DbgPrint(("leave MyVistaIoCallDriverRelay/n"));
//这里出错了一次
return;
}
VOID hook()
{
//3
KdPrint(("start hooking/n"));
ULONG old_cr0;
//将jmp指令假如到CODE中去
size_t leng;
ULONG code[12];
struct xde_instr myjmp={0};
myjmp.opcode=0xea;
myjmp.addrsize=4;
myjmp.datasize=2;
myjmp.addr_l[0]=(ULONG)my_address;//我们自己的函数地址
myjmp.data_s[0]=8;
leng=xde_asm((unsigned char *)code,&myjmp);
KdPrint(("leng is %d code is 0x%08X%",leng,code));
if (leng==NULL)
{
KdPrint(("leng is NULL failed/n"));
return;
}
KIRQL irql;
//解除权限
irql=KeRaiseIrqlToDpcLevel();
DbgBreakPoint();
__asm
{
//cli
mov eax,cr0
mov old_cr0,eax
and eax,not 10000h
mov cr0,eax
//这里出错了一次
}
KeLowerIrql(irql);
//4
//拷贝代码
// 首先是计算长度
size_t length,total_length=0;
struct xde_instr code_instr={0};
UNICODE_STRING functionName;
RtlInitUnicodeString(&functionName,L"IoCallDriver");
ULONG *start_address=(ULONG*)MmGetSystemRoutineAddress(&functionName);
ULONG *oldstart_address=(ULONG*)MmGetSystemRoutineAddress(&functionName);
//这里出错了一次
KdPrint(("*start_address is 0x%08X%,*oldstart_address is 0x%08X%/n"),*start_address,*oldstart_address);
//记录下原来的IoCallDriver地址
while (total_length<7)
{
length=xde_disasm((unsigned char *)start_address,&code_instr);
if (length==0)
{
return;
}
total_length+=length;
start_address+=length;
}
//11---
size_t length1;
ULONG code1[12];
struct xde_instr myjmp1={0};
myjmp1.opcode=0xea;
myjmp1.addrsize=4;
myjmp1.datasize=2;
myjmp1.addr_l[0]=(ULONG)start_address;//
myjmp1.data_s[0]=8;
length1=xde_asm((unsigned char *)code1,&myjmp1);
KdPrint(("length1 is %d code1 is 0x%08X%/n",length1,code1));
if (length1==0)
{
KdPrint(("length1 is NULL failed/n"));
goto sss;
}
irql=KeRaiseIrqlToDpcLevel();
__try{
__asm
{
mov esi,oldstart_address
mov edi,g_new_address
mov ecx,total_length
cld
rep movsb
//写入jmp
mov edi,oldstart_address
lea esi,code
//这里出错了一次
//code=0xF8B5DB84
//[code]=44be20ea
//
mov ecx,leng
cld
rep movsb
//old_codes1:在这写入jmp回iocalldriver
mov edi,start_address
lea esi,code1
mov ecx,length1
cld
rep movsb
}
}
__except(1)
{
KdPrint(("OCCUR excepting/n"));
}
//5
sss:
//还原权限
__asm
{
mov eax,old_cr0
mov cr0,eax
// sti
}
KeLowerIrql(irql);
}
VOID my_address()
{
//EDX保存第二参数
PIO_STACK_LOCATION irpstack;
PIRP irp;
__asm{
cmp edx,0
jz s1;
mov irp,edx
}
irpstack=IoGetCurrentIrpStackLocation(irp);
KdPrint(("current IRP is %c",irpstack->MajorFunction));
goto s2;
s1:
DbgPrint(("IRp is null/n"));
s2:
MyVistaIoCallDriverRelay();
}
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint(("OnUnload/n"));
}
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
DriverObject->DriverUnload=OnUnload;
MyVistaIoCallDriverRelay();
hook();
return STATUS_SUCCESS;
}
//这其中用到了XDE的反汇编和汇编函数的代码,使用的话直接添加就行了