Чтение MBR

Discussion in 'С/С++, C#, Rust, Swift, Go, Java, Perl, Ruby' started by tim-oleksii, 25 Jul 2011.

  1. tim-oleksii

    tim-oleksii Member

    Joined:
    14 Mar 2011
    Messages:
    199
    Likes Received:
    10
    Reputations:
    0
    Здравствуйте.
    Решил прочитать свой MBR на Windows XP.
    Открыл как полгается \\.\PhysicalDrive0, получил данные. В них оказался странный мусор.

    Так для первого раздела, я решил считать количество секторов по адресу 446+12. Для загрузочного раздела там оказалось значение 0. Не понятно почему.

    Решил скачать WinHEX и открыть через него диск С, чтобы воочию посмотреть на MBR. По адресу 446 там находилась строка (A disk read error occurred...), а не начало таблицы разделов.

    Не понятно что я все-таки читаю, и что показывается в WinHEX?
     
  2. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    Code:
    program Project2;
    
    {$APPTYPE CONSOLE}
    
    uses
      SysUtils,windows;
    Procedure ReadMBR(x: Integer; // номер устройства
                      OutName: String;  // файл 
                      SecCount: Integer // кол.секторов
                     );
    const
     FILE_DEVICE_DISK = 7;
     METHOD_BUFFERED = 0;
     FILE_ANY_ACCESS = 0;
    
    type
     _MEDIA_TYPE = DWORD;
    
     _DISKG_GEOMETRY = packed record
       Cylinders: LARGE_INTEGER;
       MediaType: _MEDIA_TYPE;
       TracksPerCylinder: DWORD;
       SectorsPerTrack: DWORD;
       BytesPerSector: DWORD;
     end;
    
    var
     DiskString: String;
     H,HOut: THandle;
     IOCTL_DISK_GET_DRIVE_GEOMETRY: Cardinal;
     DiskGeometry: _DISKG_GEOMETRY;
     BytesReturned: Cardinal;
     Res: BOOL;
     Posit: Int64;
    
     Buff: PChar;
     BuffSize, BytesRead, BytesWritten: Cardinal;
    
    function GetCtlCode (_DeviceType, _Function, _Method, _Access: WORD): Cardinal;
    begin
     Result := (_DeviceType shl 16) or (_Access shl 14)
       or (_Function shl 2) or _Method;
    end;
    
    begin
     DiskString := Format ('\\.\PHYSICALDRIVE%s',[IntToStr(x)]);
    
     H := CreateFile(
         PChar(DiskString),
         GENERIC_READ,
         FILE_SHARE_WRITE,
         nil,
         OPEN_EXISTING,
         FILE_ATTRIBUTE_NORMAL,
         0
       );
    
     if H <> 0 then
      begin
       
        IOCTL_DISK_GET_DRIVE_GEOMETRY :=
          GetCtlCode(FILE_DEVICE_DISK,0,METHOD_BUFFERED,FILE_ANY_ACCESS);
    
        Res := DeviceIoControl(
          H,
          IOCTL_DISK_GET_DRIVE_GEOMETRY,
          nil,
          0,
          @DiskGeometry,
          SizeOf(DiskGeometry),
          BytesReturned,
          nil
        );
    
     
       if Res then
        begin
      
          BuffSize := SecCount * DiskGeometry.BytesPerSector;
          Buff := AllocMem(BuffSize);
    
    
          ReadFile (H, Buff^, BuffSize, BytesRead, nil);
    
    
          HOut := CreateFile(
             PChar(OutName),
             GENERIC_WRITE,
             FILE_SHARE_READ,
             nil,
             CREATE_ALWAYS,
             FILE_ATTRIBUTE_ARCHIVE,
             0
          );
       
          if HOut <> 0 then
           begin
         
            WriteFile (HOut, Buff^, SecCount * DiskGeometry.BytesPerSector, BytesWritten, nil);
       
            CloseHandle (HOut);
           end;
       end;
       FreeMem(Buff);
       CloseHandle(H);
     end;
    end;
    begin
    readmbr(0,'123.txt',1);
    end. 
    
     
  3. tim-oleksii

    tim-oleksii Member

    Joined:
    14 Mar 2011
    Messages:
    199
    Likes Received:
    10
    Reputations:
    0
    Спасибо, этот код я видел в MSDN, но на С.

    Интерес составляет загрузочный флаг. Где его взять?
     
  4. slesh

    slesh Elder - Старейшина

    Joined:
    5 Mar 2007
    Messages:
    2,702
    Likes Received:
    1,224
    Reputations:
    455
    1) ты читаешь MBR а в WinHex зачем-то смотрим содержимое диска С. (по факту это Boot серктор смотришь ты)
    2) MBR - это не раздел винта, это самый начальный загрузчик + таблица разделов.
    3) Таблица разделов - это вспомогательная вешь, которая по факту вообще ничего не значит. Можно жить и без неё. Она нужна только для самой ОС (и её файловых систем) + MBR загрузчик из неё берет номер активного раздела, с которого грузиться надо.
    4) Данные в MBR могут вообще не совпадать с реальностью для некоторых резделов.

    Сам же MBR имеет следующий вид (данные на основе стандартного его вида от Microsoft):
    1) оффсет 0 длинна 0x1B8 - код загрузчика
    2) начиная с 0x1BE идут таблицы разделов. Максимум 4 штуки.

    Неиспользуемая таблица имеет все нули. Если это расширенный раздел, то в его начале (которое указано в таблице) находится еще одна такая таблица.
     
  5. tim-oleksii

    tim-oleksii Member

    Joined:
    14 Mar 2011
    Messages:
    199
    Likes Received:
    10
    Reputations:
    0
    Спасибо, я понял, я смотрел bootmgr, открыв диск C.
     
  6. heks

    heks Banned

    Joined:
    24 Aug 2007
    Messages:
    713
    Likes Received:
    95
    Reputations:
    12
    один знакомый говорил что у него есть вирусняк чистящий мбр ни у кого нету ? такого ?
     
  7. xophet

    xophet Member

    Joined:
    16 Apr 2011
    Messages:
    617
    Likes Received:
    49
    Reputations:
    5
    у твоего "одного знакомого" есть
     
  8. DooD

    DooD Elder - Старейшина

    Joined:
    30 Sep 2010
    Messages:
    1,168
    Likes Received:
    450
    Reputations:
    288
    делал что то на подобии,когда в сектор писался 0
     
  9. tim-oleksii

    tim-oleksii Member

    Joined:
    14 Mar 2011
    Messages:
    199
    Likes Received:
    10
    Reputations:
    0
    Запиши туда одни нули, а по адресу 0x1FE пиши 0xAA55