Xor 发表于 2011-8-18 15:51:23

恢复 shadow ssdt hook

本帖最后由 Xor 于 2011-8-18 17:48 编辑

代码见4楼。

Xor 发表于 2011-8-18 16:41:20

本帖最后由 Xor 于 2011-8-18 17:49 编辑

主要问题:如何获取原shadow ssdt地址?问题已解决,代码见http://www.m5home.com/bbs/forum.php?mod=redirect&goto=findpost&ptid=5836&pid=27959

Tesla.Angela 发表于 2011-8-18 16:57:54

Xor 发表于 2011-8-18 16:41 static/image/common/back.gif
主要问题:如何获取原shadow ssdt地址?

干嘛要用“赐”,“高抬贵手”,“小弟”之类的词语?
纯爷们为了一份代码用这些词语,值得吗?!
如果你在10年1月之前你这么问,我不怪你;
可是你在10年1月之后你这么问,只能怪你不会用搜索引擎了。。。
去看看PsNull 3的代码(VB写的,本站有下载),您就能得到满意的答案。。。
不过话也说回来,我当年为了解决同样的问题,花钱,求人,也是费了不少周章,才把代码弄到手的。。。

Xor 发表于 2011-8-18 17:31:41

Tesla.Angela 发表于 2011-8-18 16:57 static/image/common/back.gif
干嘛要用“赐”,“高抬贵手”,“小弟”之类的词语?
纯爷们为了一份代码用这些词语,值得吗?!
如 ...

谢谢,不过已经找到了NTSTATUS RestoreShadow()
{
        NTSTATUS status;
        HANDLE hFile;//文件句柄
        OBJECT_ATTRIBUTES ObjAttr;
        UNICODE_STRING ustrWin32k;
        IO_STATUS_BLOCK ioStatus;
        ULONG ulShadowRaw = 0;
        ULONG ulShadowBase = 0;
        PVOID PoolArea = NULL;
        FILE_POSITION_INFORMATION fpi;
        LARGE_INTEGER Offset;
        ULONG OrigAddress = 0;
        ULONG CurAddress = 0;
        ULONG i = 0;
        ULONG ulCount = 0;
        PULONG pAddr;

        if ( pWin32kBase == NULL ||
                KeServiceDescriptorTableShadow == NULL)
        {
                dprintf("Error.");
                return STATUS_UNSUCCESSFUL;
        }
        //索引为1的项目?

        ulCount = KeServiceDescriptorTableShadow.Limit;//Linit就是表中函数的个数

        dprintf("Count Of Shadow : %d\n", ulCount );

        ulShadowBase = *(ULONG*)&KeServiceDescriptorTableShadow.Base;//得到基址

        dprintf("ulShadowBase = 0x%X\n",ulShadowBase);
        //镜像中的偏移,file offset???
        ulShadowRaw = ulShadowBase - (ULONG)pWin32kBase;
        //ulShadowRaw = RVAToRaw(pWin32kBase,ulShadowBase);

        dprintf("ulShadowRaw = 0x%X\n",ulShadowRaw);

        RtlInitUnicodeString(&ustrWin32k, L"\\SystemRoot\\System32\\win32k.sys");
        //分配空间
        PoolArea = ExAllocatePool( PagedPool, sizeof(ULONG) * ulCount );
        //分配空间,用于保存读取到的数据,因为每个地址的长度sizeof(ULONG),个数是ulCount,所以相乘

        if (!PoolArea) {
                dprintf("PoolArea is null\n");
                return STATUS_UNSUCCESSFUL;
        }

        RtlZeroMemory(&ObjAttr, sizeof(ObjAttr) );
        //获取Win32k.sys的属性
        InitializeObjectAttributes(
                &ObjAttr,
                &ustrWin32k,
                OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
                NULL,
                NULL);
        //打开文件win32K.SYS
        status = IoCreateFile(
                &hFile,
                FILE_READ_ATTRIBUTES,
                &ObjAttr,
                &ioStatus,
                0,
                FILE_ATTRIBUTE_NORMAL,
                FILE_SHARE_READ,
                FILE_OPEN,
                0,
                NULL,
                0,
                0,
                NULL,
                IO_NO_PARAMETER_CHECKING);

        if ( !NT_SUCCESS(status) ) {
                dprintf("IoCreateFile Error : 0x%X", status);
                goto __exit;
        }

        //设置文件偏移
        Offset.LowPart = ulShadowRaw;
        Offset.HighPart = 0;
        //开始读取数据
        status = ZwReadFile (
                hFile,
                NULL,
                NULL,
                NULL,
                &ioStatus,
                //从文件读出到分配空间
                PoolArea,
                ulCount*sizeof(ULONG),
                //偏移
                &Offset,
                NULL);

        if ( !NT_SUCCESS(status) ) {
                dprintf("ZwReadFile Error : 0x%X");
                goto __exit;
        }
        //改变指针类型
        pAddr = (PULONG)PoolArea;
        //比较原始地址与当前的地址并且输出调试
        _asm
        {
                CLI
                MOV EAX,CR0
                AND EAX,NOT 10000H
                MOV CR0,EAX
        }
        for (i=0;i<ulCount;i++) {
                OrigAddress = *pAddr;//指向原始地址
                CurAddress = KeServiceDescriptorTableShadow.Base;//读取当前地址
                if ( OrigAddress != CurAddress ) {
                        dprintf("ID:%-3d.OrigAddr : 0x%X CurAddr : 0x%X---Hooked!\n",i,OrigAddress,CurAddress);
                        KeServiceDescriptorTableShadow.Base=*pAddr;
                        dprintf("Already unhook!");
                } else {
                        dprintf("ID:%-3d.OrigAddr : 0x%X.CurAddr : 0x%X\n",i,OrigAddress,CurAddress);
                }
                pAddr++;//指针指向下一个函数
        }
        _asm
        {
                MOV EAX,CR0
                OR EAX,10000h
                MOV CR0,EAX
                STI
        }

__exit:
        if (PoolArea) {
                ExFreePool(PoolArea);
                //释放空间
        }
        if (hFile) {
                ZwClose(hFile);
                //关闭句柄
        }
        return status;
}

Tesla.Angela 发表于 2011-8-18 19:56:55

楼主试试用我以前发的恢复Ring 0 Inline Hook的代码恢复一下Shadow SSDT Inline Hook。。。
注意要把win32k.sys复制一次才能LoadLibraryEx。。。

ok100fen 发表于 2011-8-21 22:54:43

不错
标记一下

cainiaocai 发表于 2011-10-19 05:36:20

:L
页: [1]
查看完整版本: 恢复 shadow ssdt hook