lionxyes
驱动牛犊
驱动牛犊
  • 注册日期2011-10-16
  • 最后登录2012-01-01
  • 粉丝0
  • 关注0
  • 积分7分
  • 威望51点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1603回复:0

xp下hook IofCallDriver出错

楼主#
更多 发布于:2011-10-22 11:14
先向将要帮助我的人表示感谢.
问题是这样的:我根据《天书夜读》上的思路做了一个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_OBJECT    pDriverObject)
{
    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;
}

也许我很菜,但please help me
游客

返回顶部