首页
社区
课程
招聘
[求助]恢复inline hook死机蓝屏问题
发表于: 2010-7-4 20:42 5719

[求助]恢复inline hook死机蓝屏问题

2010-7-4 20:42
5719
小弟我刚学驱动,试着网上的写了一下,主要针对NtReadVirtualMemory练习一下,目的是去掉其他驱动对该函数前10字节的inline hook 。驱动能正常加载,但是当我准备打开xuetr查看时就死机了,如果用kd查看就蓝屏。想问问为什么。下面代码中有两个地方有疑问,也请大侠们帮小弟看看,谢了

#include<ntddk.h>
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
        PVOID   ServiceTableBase;
        PULONG  ServiceCounterTableBase;
        ULONG   NumberOfService;
        ULONG   ParamTableBase;
}SERVICE_DESCRIPTOR_TABLE,*PSERVICE_DESCRIPTOR_TABLE;

extern PSERVICE_DESCRIPTOR_TABLE   KeServiceDescriptorTable; //KeServiceDescriptorTable为导出函数

VOID Hook();
VOID Unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
//////////////////////////////////////

ULONG JmpReadAddr;
ULONG OldReadAddr;

__declspec(naked)
NTSTATUS __stdcall
MyNtReadVirtualMemory(
                                      HANDLE ProcessHandle,                  
                                       PVOID BaseAddress,
                                       PVOID Buffer,
                      ULONG NumberOfBytesToRead,
                      PULONG NumberOfBytesReaded)
{
        //跳过去
        __asm
        {
                push    0x1c
                push    80802ef0h  //共十个字节(硬编码要注意改变)
//上面这句指令中的值在不同的系统中是不同的,好像应该是个什么地址,但这里为了简单测试
//采用硬编码,代码中的值是原函数在我操作系统中的值,
                jmp    [JmpReadAddr]  
        }
}

NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
        DriverObject->DriverUnload = OnUnload;
        KdPrint(("Unhooker load"));
        Hook();
        return STATUS_SUCCESS;
}
/////////////////////////////////////////////////////
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
        KdPrint(("Unhooker unload!"));
        Unhook();
}
/////////////////////////////////////////////////////
VOID Hook()
{
        ULONG  AddressRead;
       
        AddressRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xba * 4;//0xbA为NtReadVirtualMemory服务ID
       
        OldReadAddr = *(ULONG*)AddressRead;
       
        JmpReadAddr = OldReadAddr + 10;
//上面这句代码中的OldReadAddr 地址看网上的例子是用的其他方式表示,这里由于对这个函数是否导出,和具体获取函数地址等还不是很了解。所以我采用了这种方法。不知道是否正确,还请指点,网上说的添加一个导出库,并且声明该函数原型,如果是这样的话我可以用下面这种形式获取地址吗 //JmpReadAddr = (ULONG)NtReadVirtualMemory + 10;

        __asm
        {
                //去掉内存保护
                cli
                        mov  eax,cr0
                        and  eax,not 10000h
                        mov  cr0,eax
        }
       
        *((ULONG*)AddressRead) = (ULONG)MyNtReadVirtualMemory;//HOOK SSDT
       
        __asm
        {
                //恢复内存保护  
                mov  eax,cr0
                or   eax,10000h
                mov  cr0,eax
                sti
        }
}
//////////////////////////////////////////////////////
VOID Unhook()
{
        ULONG  AddressRead;
       
        AddressRead = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0xba * 4;//0xbA为NtReadVirtualMemory服务ID
        __asm
        {
                cli
                mov  eax,cr0
                and  eax,not 10000h
                mov  cr0,eax
        }

        *((ULONG*)AddressRead) = (ULONG)OldReadAddr;//还原SSDT
       
        __asm
        {  
                mov  eax,cr0
                or   eax,10000h
                mov  cr0,eax
                sti
        }

        KdPrint(("Unhook"));
}

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 0
支持
分享
最新回复 (4)
雪    币: 136
活跃值: (48)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
2
貌似JmpReadAddr 你的好好研究下
2010-7-4 20:46
0
雪    币: 451
活跃值: (41)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
你好,是这样的我的想法是前面OldReadAddr = *(ULONG*)AddressRead;不是保存了read函数在ssdt表中获取的原始地址吗,我感觉这个地址是最原始的read函数的地址(如果没有被ssdt hook的话,)如果用这个地址取代JmpReadAddr = (ULONGNtReadVirtualMemory + 10;这种方法应该是等价的吧,我是这样想的,不知道有什么地方遗漏了,希望指点
2010-7-4 21:00
0
雪    币: 217
活跃值: (68)
能力值: ( LV12,RANK:210 )
在线值:
发帖
回帖
粉丝
4
从文件中读取函数地址导出表比较保险
2010-7-4 21:24
0
雪    币: 64
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
源文件中提取NtReadVirtualMemory
然后加载到内存,重定位搞好。
修改ssdt,哈哈
2010-7-5 19:55
0
游客
登录 | 注册 方可回帖
返回
//