1

I created a little program on python that reads the boot sector at a low level so it will not corrupt the device. I successfully ran this program yesterday in Linux and I got the idea to do the same thing in Windows. But the only problem that came was that I wasn't enabled to read for example:\Device\Harddisk0\Partition1, the boot partition or \Device\Harddisk0\DR0, the raw disk 0. Each time that I try it throws an error: No such a file or a directory

What I am doing wrong?

Praveen Patel
  • 429
  • 4
  • 11
Zeiad Badawy
  • 51
  • 1
  • 10
  • Did you try with the `\\.` prefix? That is `open("\\\\.\\Device\\Harddisk0\\Partition1")` – selbie Dec 31 '16 at 21:03
  • you cannot use the same method: boot sector is not mapped on a file. Where did you read that it was possible like that on windows? – Jean-François Fabre Dec 31 '16 at 21:08
  • It gives me the same error – Zeiad Badawy Dec 31 '16 at 21:09
  • 1
    `\Device\Harddisk0\DR0` is in the object namespace. The Windows API makes selective use of this namespace, e.g. global symbolic links to devices are created in `\GLOBAL??`, e.g. `C:` => `\Device\HarddiskVolume2`. The legacy DOS namespace lets you use *some* device links here, such as drive letters and legacy DOS devices such as `CON`, but to access everything you need one of the WinAPI device prefixes, either ``\\.\`` (some path processing and forward slash is allowed, but limited to `MAX_PATH` characters) or ``\\?\`` (no path processing; must be Unicode and use backslash). – Eryk Sun Dec 31 '16 at 21:49
  • 3
    The link you're looking for is `\\.\PhysicalDrive0`, which opens `\Device\Harddisk0\DR0`. Similarly `\\.\PhysicalDrive1` opens `\Device\Harddisk1\DR1`. The other one, `\Device\Harddisk0\Partition1` is a volume, not a disk. You can just open the volume drive letter or GUID mountpoint, e.g. `\\.\C:`. But you can't hard code this. You have to use the API to map a volume by drive letter, GUID volume name, or NTFS mount point to a physical disk number. – Eryk Sun Dec 31 '16 at 22:01
  • I tried `t = open(r"\\.\PhysicalDrive0")` and it gets me the error : `Permission Denied`. So I did it in my command line as administrator and it gave me : `OSError: [WinError 1] Incorrect Function` – Zeiad Badawy Dec 31 '16 at 22:29
  • Python's high-level I/O tries to stat the file, which fails. Use `disk_fd = os.open( r"\\.\PhysicalDrive0", os.O_RDONLY | os.O_BINARY);` `data = os.read(disk_fd, 512);` `os.close(disk_fd)`. – Eryk Sun Dec 31 '16 at 22:33
  • Exactly what are you reading in Linux? We need to know whether you're trying to read a master boot record / GUID partition table on the disk or the volume boot record on the volume. If you want to read the VBR for the system disk, open `'\\.\%s' % os.environ['SystemDrive']`. This will almost always be `\\.\C:`. – Eryk Sun Dec 31 '16 at 22:55

2 Answers2

3

The Correct Way To Do It Is:

import os
disk_fd = os.open( r"\\.\PhysicalDrive0", os.O_RDONLY | os.O_BINARY)
data = os.read(disk_fd, 512)
os.close(disk_fd)

Thanks To @eryksun

Zeiad Badawy
  • 51
  • 1
  • 10
0

all depended from NT or WIN32 api you using. ZwOpenFile or CreateFileW ?

\Device\Harddisk0\Partition1 is NT name format and must be used in ZwOpenFile or ZwCreateFile only.

for use this name in CreateFileW you must prefix it by \\?\globalroot

so code example - (using both NT and win32 calls in single function)

void xxx()
{
    HANDLE hFile;
    IO_STATUS_BLOCK iosb;
    UNICODE_STRING ObjectName;
    OBJECT_ATTRIBUTES oa = { sizeof(oa), 0, &ObjectName, OBJ_CASE_INSENSITIVE };
    RtlInitUnicodeString(&ObjectName, L"\\Device\\Harddisk0\\Partition1");

    UCHAR buf[0x200];
    if (0 <= ZwOpenFile(&hFile, FILE_GENERIC_READ, &oa, &iosb, FILE_SHARE_VALID_FLAGS, FILE_SYNCHRONOUS_IO_NONALERT))
    {
        LARGE_INTEGER ByteOffset = {};
        ZwReadFile(hFile, 0, 0, 0, &iosb, buf, sizeof(buf), &ByteOffset, 0);
        ZwClose(hFile);
    }

    hFile = CreateFile(L"\\\\?\\globalroot\\Device\\Harddisk0\\Partition1", FILE_GENERIC_READ, FILE_SHARE_VALID_FLAGS,
        0, OPEN_EXISTING, 0, 0);

    if (hFile != INVALID_HANDLE_VALUE)
    {
        OVERLAPPED ov = {};
        ULONG n;
        ReadFile(hFile, buf, sizeof(buf), &n, &ov);
        CloseHandle(hFile);
    }
}

also you can use next SymbolicLinks with CreateFileW :

  • \\?\Harddisk<X>Partition<Y> - for partition (1,2,..) on HardDisk (0,1,..)
  • \\?\PhysicalDrive<X> for HardDisk (0,1,..)

all depend from - how you got this paths ? or you simply hardcode it ?

RbMm
  • 31,280
  • 3
  • 35
  • 56
  • 1
    That's just a link to the volume, e.g. `\Device\HarddiskVolume1`, so why wouldn't you just open the conventional drive letter, GUID volume name, or NTFS mount point? For example, `\\.\C:`. Otherwise if you wanted to open the underlying disk(s), you'd have to open the volume and get the disk extents via [`IOCTL_VOLUME_GET_VOLUME_DISK_EXTENTS`](https://msdn.microsoft.com/en-us/library/aa365194), and open the corresponding `\\.\PhysicalDrive[N]`. That's all without any need to refer to the native object namespace, which should be avoided in Windows programming. Microsoft doesn't support it. – Eryk Sun Dec 31 '16 at 22:22
  • @eryksun - about how/which names use- depend from how OP got (or calculate) `\Device\Harddisk0\Partition1` or he simply hardcode it ? i not try cover here how need enumerate/open disks, partition, volumes. what is difference between this objects. i only explain the different in name format for *concrete hardcoded name* – RbMm Dec 31 '16 at 22:32
  • I'm just explaining that these native object paths shouldn't be used in Windows user-mode programming unless there's no other way to get something done. In this case it's not necessary. – Eryk Sun Dec 31 '16 at 22:35
  • @eryksun - yes, i listen this already many time :) i nothing concrete advice to use (nt or win32 api) simply show code for both case and different in names ( `\\?\globalroot` prefix) however main question here - what is goal of OP, how correct enumerate disks or partitions (volumes).. i not cover this. may be better delete my answer at all ? – RbMm Dec 31 '16 at 22:45