tangptr@126.com 发表于 2015-8-15 21:49:07

TP的学习笔记:实现在Win64上的MBR保护工具(无需关闭PatchGuard!)

记得前天我发了一个关于制作一个MBR保护器的帖子,只不过那个是在Win32下可用的,在Win64下不可用。现在,就来制作一个基于x64的MBR保护器。
32位MBR保护器的帖子地址:http://www.m5home.com/bbs/forum.php?mod=viewthread&tid=8573&_dsign=9b6ec8f9
由于在Win64上有PatchGuard,我们不能搞Hook SSDT之类的事情,所以,在x64上是不能搞上次那个初级保护版的了。而这一次,我们把目光投到上一次的高级保护上面。上一次的高级保护,是指Hook Disk.sys的IRP_MJ_READ和IRP_MJ_WRITE两个例程实现防止读写MBR,这一次我们同样要Hook这两个例程。
可能会有人问,不是有PatchGuard吗?搞Disk Hook真的不会蓝屏吗?事实上,的确不会蓝屏。PatchGuard只会管ntkrnlpa.exe,hal.dll,ndis.sys之类的。而这个分发例程所在的classpnp.sys不管这玩意。
其实说句实话,这份代码和32位版的差别并不大。
先是挂钩和恢复例程
void StartHook()
{
        NTSTATUS st;
        UNICODE_STRING uniDiskName;
        RtlInitUnicodeString(&uniDiskName,L"\\Driver\\Disk");
        st=ObReferenceObjectByName(&uniDiskName,OBJ_CASE_INSENSITIVE,0,0,*IoDriverObjectType,KernelMode,0,&DiskDrvObj);
        if(NT_SUCCESS(st))
        {
                IrpMjRead=(IRP_MJ_SERIES)InterlockedExchangePointer(&DiskDrvObj->MajorFunction,fake_IrpMjRead);
                IrpMjWrite=(IRP_MJ_SERIES)InterlockedExchangePointer(&DiskDrvObj->MajorFunction,fake_IrpMjWrite);
                IsHooked=TRUE;
        }
}

void StopHook()
{
        InterlockedExchangePointer(&DiskDrvObj->MajorFunction,IrpMjRead);
        InterlockedExchangePointer(&DiskDrvObj->MajorFunction,IrpMjWrite);
        ObDereferenceObject(DiskDrvObj);
        IsHooked=FALSE;
}
接着就是过滤用的伪例程
NTSTATUS fake_IrpMjWrite(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
        NTSTATUS status = STATUS_SUCCESS;
        IO_STACK_LOCATION*irpsp= IoGetCurrentIrpStackLocation(Irp);
        LARGE_INTEGER WriteOffsetInBytes= irpsp->Parameters.Write.ByteOffset;
        ULONG64 writeLength = irpsp->Parameters.Write.Length;
        LARGE_INTEGER Sectionpos={0};
        ULONG64 SectorRange;
        BOOLEAN IsDeniedAccess = FALSE;
        do
        {
                Sectionpos.HighPart = 0;
                Sectionpos.LowPart = 0x200;
                SectorRange= WriteOffsetInBytes.QuadPart/Sectionpos.QuadPart;
                if(SectorRange==0 && DeviceObject->DeviceType==FILE_DEVICE_DISK)
                {
                        IsDeniedAccess =TRUE;
                        break;
                }
        }while(0);
        if (IsDeniedAccess)
        {
                Irp->IoStatus.Information=writeLength;
                Irp->IoStatus.Status=STATUS_ACCESS_DENIED;
                IoCompleteRequest(Irp,IO_NO_INCREMENT);
                status=STATUS_ACCESS_DENIED;
        }
        else
        {
                status=IrpMjWrite(DeviceObject,Irp);
        }
        return status;
}

NTSTATUS fake_IrpMjRead(IN PDEVICE_OBJECT DeviceObject,IN PIRP Irp)
{
        NTSTATUS status = STATUS_SUCCESS;
        IO_STACK_LOCATION*irpsp= IoGetCurrentIrpStackLocation(Irp);
        LARGE_INTEGER ReadOffsetInBytes= irpsp->Parameters.Read.ByteOffset;
        ULONG64 readLength = irpsp->Parameters.Write.Length;
        LARGE_INTEGER Sectionpos={0};
        ULONG64 SectorRange;
        BOOLEAN IsDeniedAccess = FALSE;
        do
        {
                Sectionpos.HighPart = 0;
                Sectionpos.LowPart = 0x200;
                SectorRange= ReadOffsetInBytes.QuadPart/Sectionpos.QuadPart;
                if(SectorRange==0 && DeviceObject->DeviceType==FILE_DEVICE_DISK)
                {
                        IsDeniedAccess =TRUE;
                        break;
                }
        }while(0);
        if (IsDeniedAccess)
        {
                Irp->IoStatus.Information=readLength;
                Irp->IoStatus.Status=STATUS_ACCESS_DENIED;
                IoCompleteRequest(Irp,IO_NO_INCREMENT);
                status=STATUS_ACCESS_DENIED;
        }
        else
        {
                status=IrpMjWrite(DeviceObject,Irp);
        }
        return status;
}
编译的时候要选择用x64 Checked Build Environment,注意别选到ia64或者x86上面去了!如图所示:

经测试,MBR读写器无法实现读写MBR。如图所示:

p.s:本文附带的附件,其附件描述摘自Hovi.Delphic的帖子,由于TP的学习笔记系列是安利给大家的,所以既不设置阅读权限,也不设置水晶币
此外顺带在附件里加了有数字签名版和无数字签名版。我测试的时候是关了DSE用无签名版测试的。。。

Tesla.Angela 发表于 2015-8-15 22:55:36

不错。不过,这句代码不需要用ULONG64。ULONG64 readLength = irpsp->Parameters.Write.Length;

tangptr@126.com 发表于 2015-8-15 23:29:39

好像是这么回事啊。。。不过“山寨”是个什么情况。。。

陌路人 发表于 2015-8-17 00:25:26

顶一下,太深奥了,代码我就不要了.也看不懂

baichimm 发表于 2016-1-26 00:46:53

谢谢

safeho 发表于 2016-1-26 14:27:32

顶一下

n36437517 发表于 2016-2-19 09:31:25

谢楼主分享。。。。。。

860000023 发表于 2016-4-20 12:01:11

谢谢分享,

tangptr@126.com 发表于 2016-5-6 22:35:07

简单更新了一下,把驱动的Checked编译模式改成了Free,顺带加了数字签名,调用者改成默认以Admin权限执行,这下不必关闭DSE了。

jumpbin 发表于 2018-7-29 16:37:29

顶一下
页: [1]
查看完整版本: TP的学习笔记:实现在Win64上的MBR保护工具(无需关闭PatchGuard!)