首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 操作系统 > windows >

xp上hook IofCallDriver出错

2012-12-27 
xp下hook IofCallDriver出错本帖最后由 lionxyes 于 2011-10-22 10:48:22 编辑先向将要帮助我的人表示感谢

xp下hook IofCallDriver出错
本帖最后由 lionxyes 于 2011-10-22 10:48:22 编辑 先向将要帮助我的人表示感谢.
问题是这样的:我根据《天书夜读》上的思路做了一个xp下hook IofCallDriver的小程序,当总是出错,用WinDbg单步调试时,最终的蓝屏代码为DRIVER_IRQL_NOT_LESS_OR_EQUAL,另外当不调试直接在OS中运行时,最终蓝屏代码为PAGE_FAULT_IN_NONPAGED
下面是关键的代码


//driver.h
typedef PCHAR PBYTE;//不想在一个一个替换了,so...
typedef NTSTATUS  (__fastcall *PIOFCALLDRIVER)(PDEVICE_OBJECT,PIRP);

typedef struct _DEVICE_EXTENSION {
PDEVICE_OBJECT pDevice;
UNICODE_STRING ustrDeviceName;//设备名称
UNICODE_STRING ustrSymLinkName;//符号链接名
PIOFCALLDRIVER nativerIofCallDriver;//保存系统的IofCallDriver的地址
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;


//driver.cpp
#include "Driver.h"

ULONG g_uCR0;//保存我们修改CRP寄存器之前的它的值
KSPIN_LOCK SDTSpinLock;

NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT,IN OUT PIRP);//我们的IofCallDriver;
PIOFCALLDRIVER HookIofCallDriver(IN PIOFCALLDRIVER,
 IN BOOLEAN );//Hook IofCallDriver or unhook
VOID WPOFF();//
VOID WPON();//

#pragma PAGEDCODE
VOID WPOFF()
{

    ULONG uAttr;

    _asm
    {
        push eax;
        mov eax, cr0;
        mov uAttr, eax;
        and eax, 0FFFEFFFFh; // CR0 16 BIT = 0
        mov cr0, eax;
        pop eax;
        cli
    };

g_uCR0=uAttr;
}
VOID WPON()
{

    _asm
    {
        sti
push eax;
        mov eax, g_uCR0; //恢復原有 CR0 屬性
        mov cr0, eax;
        pop eax;
    };
}

#pragma PAGEDCODE 
NTSTATUS FASTCALL MyIofCallDriver(IN PDEVICE_OBJECT pDevObj,IN OUT PIRP pIrp)
{
DbgPrint("HDM:This is MyIofCallDriver! You succeed!\n");

PDEVICE_EXTENSION pdx=(PDEVICE_EXTENSION)pDevObj->DeviceExtension;

return (*(pdx->nativerIofCallDriver))(pDevObj,pIrp);
}
#pragma PAGEDCODE
//
//当hookOrUnhook为TRUE时,IofCallDriver为我们的替换函数的地址
//当hookOrUnhook为FALSE时,则为系统IofCallDriver的地址
//无论是hook or unhook,当函数成功时,返回系统IofCallDriver的地址,否则返回NULL
PIOFCALLDRIVER HookIofCallDriver(IN PIOFCALLDRIVER IofCallDriver, 
   IN BOOLEAN hookOrUnhook)
{
DbgPrint("HDM:Enter HookIofCallDriver\n");
UNICODE_STRING functionName;
PBYTE address=NULL;//通过调用MmGetSystemRoutineAddress得到的IofCallDriver的入口地址
PBYTE nativeIofCallDriver=NULL;//IofCallDriver执行体的地址
RtlInitUnicodeString(&functionName,L"IofCallDriver");

//得到IofCallDriver的入口地址
address=(PBYTE)MmGetSystemRoutineAddress(&functionName);

if (address==NULL)
{
return NULL;
}
if (hookOrUnhook)
{
//通过反汇编可知,将上面得到的地址加两字节地址就是系统的IofCallDriver执行体的地址
nativeIofCallDriver=(PBYTE)(*(PLONG)(address+2));




KIRQL OldIrql;
KeAcquireSpinLock( &SDTSpinLock, &OldIrql );
WPOFF();

InterlockedExchange((PLONG)(address+2),(LONG)IofCallDriver);

WPON(); 
        KeReleaseSpinLock( &SDTSpinLock, OldIrql );
}
else
{
if (IofCallDriver)
{
KIRQL OldIrql;
KeAcquireSpinLock( &SDTSpinLock, &OldIrql );
WPOFF();

InterlockedExchange((PLONG)(address+2),(LONG)IofCallDriver);

WPON(); 
KeReleaseSpinLock( &SDTSpinLock, OldIrql );

nativeIofCallDriver=(PBYTE)IofCallDriver;
}
else
{
return NULL;
}
}
DbgPrint("HDM:Leave HookIofCallDriver\n");

return (PIOFCALLDRIVER)nativeIofCallDriver;
}

#pragma INITCODE
NTSTATUS CreateDevice (
IN PDRIVER_OBJECTpDriverObject) 
{
NTSTATUS status=STATUS_SUCCESS;
PDEVICE_OBJECT pDevObj;
PDEVICE_EXTENSION pDevExt;

//创建设备名称
UNICODE_STRING devName;
RtlInitUnicodeString(&devName,L"\\Device\\XPHookIofCallDriver");

//创建设备
status = IoCreateDevice( pDriverObject,
sizeof(DEVICE_EXTENSION),
&(UNICODE_STRING)devName,
FILE_DEVICE_UNKNOWN,
0, TRUE,
&pDevObj );
if (!NT_SUCCESS(status))
return status;

pDevObj->Flags |= DO_BUFFERED_IO;
pDevExt = (PDEVICE_EXTENSION)pDevObj->DeviceExtension;
pDevExt->pDevice = pDevObj;
pDevExt->ustrDeviceName = devName;
//创建符号链接
UNICODE_STRING symLinkName;
RtlInitUnicodeString(&symLinkName,L"\\??\\XPHookIofCallDriver");
pDevExt->ustrSymLinkName = symLinkName;
status = IoCreateSymbolicLink( &symLinkName,&devName );
if (!NT_SUCCESS(status)) 
{
IoDeleteDevice( pDevObj );
return status;
}


pDevExt->nativerIofCallDriver=HookIofCallDriver(MyIofCallDriver,TRUE);

if (pDevExt->nativerIofCallDriver==NULL)
{
IoDeleteDevice(pDevObj);
IoDeleteSymbolicLink(&symLinkName);
status=STATUS_UNSUCCESSFUL;
}
return status;
}


[解决办法]
这个最好要放到相应的编程版块去问吧。那里能得到更好的解答

热点排行