天书上的练习-inlinehook IoCallDriver函数

//把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的反汇编和汇编函数的代码,使用的话直接添加就行了

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值