MBR 是硬盘的主引导记录,它独立于操作系统之外,不管你装 Windows 操作系统还是
Linux 操作系统等等,它都存在,它包括引导程序、分区表、结束标志(0x55AA)。它被
bios将引导程序加载在0x7C00的起始位置,检查最后的两位标志位是否正确,如果正确,
取出活动分区的起始扇区(引导扇区),然后跳转到活动分区的引导扇区,通过引导扇区的
引导程序在找到 NTLDR 区域,如果 NTLDR 文件丢失或者损坏,就会出现一段熟悉的信
息:”NTLDR is missing,please Ctrl+Alt+Del”,然后你就只有重启计算机,或者修复
NTLDR。NTLDR(startup.com +osload), startup.com是16位的程序,它运行在实模式,其
中很重要的工作就是负责将实模式(不支持分页,采取段首址*0x10+偏移,所有读写都是特
权指令)切换到保护模式并且开启分页功能。然后重定位 osload 程序,这个就是核心的启
动程序,它加载核心设备(BOOT 型)的驱动,比如:ftdisk.sys、atapi.sys、disk.sys 等
等,加载后再加载 ntoskrnl.exe,控制权在交给 ntoskrnl.exe 程序,加载一些其他设备驱
动、服务等等,最后进去系统。具体的细节我以后在跟大家讨论。鬼影 2 就是替换
fips.sys驱动,并且替换bios的扩展in113,来接官对MBR的读写。所以MBR是极其重要,
在vista以后的系统,微软也意识到MBR的重要性,所以对MBR采取了保护措施,不能随便
改写,由于微软不在支持windows xp的升级,所以winxp下的MBR经常被病毒、木马利用。
但是目前还有很多用户在使用 winxp,下面我给大街介绍一种保护 MBR 的方式,通过 OBJECT
HOOK来实现。
通过对磁盘类驱动的IRP_MJ_WRITE的分发例程进行OBJECT HOOK,对写入的扇区偏移来进
行判定,如果是第一分区(mbr在第一分区的0柱面 0磁道0扇区)的磁盘设备,并且偏移
扇区为0,也就是从0扇区里的位置开始写入的操作全部拦截,从而保护mbr不被修改。我
的方法过于简单,可以将未被修改的 MBR512 个字节的内容进行 HASH。然后对要写入的 512
个字节也进行 HASH,如果 hash 值不同,则 MBR 证明已被修改过,则拦截该写入操作。主要
代码如下:
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING uniobjname={0};
PDRIVER_OBJECT diskdrvobj;
NTSTATUS status;
if ( g_bHooked&& g_Origal_disk_Write_Dispatch)
{
RtlInitUnicodeString(&uniobjname,L"\\Driver\\Disk");
status = ObReferenceObjectByName(&uniobjname,
OBJ_CASE_INSENSITIVE,
0,
0,
*IoDriverObjectType,
KernelMode,
0,
&diskdrvobj);
if (NT_SUCCESS(status))
{
InterlockedExchangePointer(&diskdrvobj->MajorFunction[IRP_MJ_WRITE],(PDRIVER
_DISPATCH)g_Origal_disk_Write_Dispatch);
g_bHooked =FALSE;
ObDereferenceObject(diskdrvobj);
}
}
return;
}
PDEVICE_OBJECT GetFirstPartitionDevice()
{
UNICODE_STRING uniobjname={0};
PDRIVER_OBJECT diskdrvobj;
NTSTATUS status;
PDEVICE_OBJECT result=NULL;
PDEVICE_OBJECT findev;
RtlInitUnicodeString(&uniobjname,L"\\Driver\\Disk");
status = ObReferenceObjectByName(&uniobjname,
OBJ_CASE_INSENSITIVE,
0,
0,
*IoDriverObjectType,
KernelMode,
0, |