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用无签名版测试的。。。 不错。不过,这句代码不需要用ULONG64。ULONG64 readLength = irpsp->Parameters.Write.Length; 好像是这么回事啊。。。不过“山寨”是个什么情况。。。 顶一下,太深奥了,代码我就不要了.也看不懂 谢谢 顶一下 谢楼主分享。。。。。。 谢谢分享,
简单更新了一下,把驱动的Checked编译模式改成了Free,顺带加了数字签名,调用者改成默认以Admin权限执行,这下不必关闭DSE了。
顶一下
页:
[1]