|
本帖最后由 sunsea 于 2020-11-7 17:13 编辑
- // get list of disk class devices
- Status = IoGetDeviceInterfaces(&GUID_DEVINTERFACE_DISK,NULL,0,&SymbolicLinkList);
- if(!NT_SUCCESS(Status))
- {
- return Status;
- }
- // allocate memory for read buffer
- // the minimum buffer size should be 2048 bytes for one CD/DVD-ROM sector
- size = 0x800;
- buf = (PUCHAR)ExAllocatePoolWithTag(PagedPool,size,SVBUS_POOL_TAG);
- if(buf == NULL)
- {
- return STATUS_INSUFFICIENT_RESOURCES;
- }
- // do this for every disk in the Unicode string list
- for(p = SymbolicLinkList; *p != UNICODE_NULL; p += len)
- {
- // do not check our own SVBus, this can BSOD with the error "System Thread Exception not handled" if we send IRP_MJ_READ in IoCallDriver of ReadWritePhysicalDisk
- /*lint -save -e585 Warning 585: The sequence (??\) is not a valid Trigraph sequence */
- if(RtlCompareMemory(p,L"\\??\\SVBus",(SIZE_T)0x12) != 0x12)
- /*lint -restore */
- {
- // initialize device name unicode string
- RtlInitUnicodeString(&deviceNameUnicodeString,p);
- // get a pointer to the top object in the named device object's stack and a pointer to the corresponding file object
- Status = IoGetDeviceObjectPointer(&deviceNameUnicodeString,FILE_ALL_ACCESS,&FileObject,&FileDeviceObject);
- if(NT_SUCCESS(Status))
- {
- // CDROM
- if(DeviceExtension->Disk.VirtualDeviceType == CDROM)
- {
- // read possible CD001 location of virtual ISO file on physical disk
- ByteOffset.QuadPart = (LONGLONG)DeviceExtension->Disk.ImageStartOffsetInBytes + 0x8000; //算出镜像文件首地址,然后求出特征标记所在地址
- }
- // HDD and FLOPPY
- else
- {
- // read possible MBR location of virtual hard disk file on physical disk
- ByteOffset.QuadPart = (LONGLONG)DeviceExtension->Disk.ImageStartOffsetInBytes;//算出镜像文件首地址,然后求出特征标记所在地址
- }
- // zero read buffer memory
- RtlZeroMemory(buf,size);
- // read / write physical disk
- Status = ReadWritePhysicalDisk(FileDeviceObject,FileObject,IRP_MJ_READ,buf,(ULONG)size,&ByteOffset);
- if(NT_SUCCESS(Status))
- {
- // CDROM
- if(DeviceExtension->Disk.VirtualDeviceType == CDROM)
- {
- // check for string "CD001"
- if(buf[1] == 'C' && buf[2] == 'D' && buf[3] == '0' && buf[4] == '0' && buf[5] == '1') //读写,检查标记,对就给过
- {
- // we have found a valid CDROM ISO, save file object and file device object
- DeviceExtension->Disk.FileObject = FileObject;
- DeviceExtension->Disk.FileDeviceObject = FileDeviceObject;
- // free read buffer memory
- ExFreePoolWithTag(buf,SVBUS_POOL_TAG);
- // free list of disks
- ExFreePool(SymbolicLinkList);
- return STATUS_SUCCESS;
- }
- }
- // HDD and FLOPPY
- else if(DeviceExtension->Disk.VirtualDeviceType == HDD || DeviceExtension->Disk.VirtualDeviceType == FLOPPY)
- {
- // check for last 2 bytes of a valid MBR
- if(buf[510] == 0x55 && buf[511] == 0xAA) //读写,检查标记,对就给过
- {
- // we have found a valid MBR, save file object and file device object
- DeviceExtension->Disk.FileObject = FileObject;
- DeviceExtension->Disk.FileDeviceObject = FileDeviceObject;
- // free read buffer memory
- ExFreePoolWithTag(buf,SVBUS_POOL_TAG);
- // free list of disks
- ExFreePool(SymbolicLinkList);
- return STATUS_SUCCESS;
- }
- }
- }
- // we have not found a CDROM ISO or an MBR
- // dereference the file object, this will also indirectly dereference the device object
- ObDereferenceObject(FileObject);
- }
- }
- // get Unicode string length of physical disk
- // add 2 bytes for Unicode terminating null and continue with the next physical disk in the list
- len = wcslen(p) + 1;
- }
复制代码
SVBus作者思路就两部:
1,算出镜像文件应该所在物理磁盘上的位置
2,根据位置,逐个检查物理磁盘,读指定位置,看有没有特征标记,有就给过,不再检查
跟那些0x80 0x81没有任何关系……这个思路我只能说牛逼,用最小的代码量覆盖了99%的情况……毕竟两个磁盘上同一位置都有有效标记很罕见……也意味着这个方案应该是可以移植到UEFI下的…… |
|