2016-07-14 5 views
0

Проблема: Я не могу получить воспроизводимый файл, объем или хэши даже физических дисков (например, SHA1), даже с EWF включен Win 7 Embedded и используя методы CreateFile/ReadFile API Win32. Мне кажется, что ReadFile читает из оверлей ОЗУ EWF, но мне нужно, чтобы получить байты с диска.Как получить последовательную SHA1 жесткого диска или тома, что позволило EWF (Win 7 встроенных)

фон: Мы обновляем регулируемый аппаратный + программный продукт с Windows XP Embedded (FAT32) для Windows 7 Embedded (NTFS). Код приложения написан на C# .Net и VC++.

Нормативным требованием является проверка того, что все файлы, включая файлы ОС, присутствующие на жестком диске, являются точными копиями файлов ссылок, которые были предоставлены регулятору. Регулятор должен иметь возможность выполнять эту проверку, пока аппаратное устройство функционирует (в процессе производства), не останавливая приложения, запущенные на устройстве.

В дни встроенной памяти XP мы смогли получить согласованные хэши-файлы, когда EWF был включен, а с помощью устройства - путем разбора файловой системы FAT32 и чтения дисковых кластеров через ReadFile (Win 32 API, kernel32.dll) , Хэши не были согласованы, если мы читаем файл как, скажем, FileStream.

Наша ОС и приложения развернуты как неизменный образ главного диска. Мы клонируем жесткие диски от мастера, используя байт для байтового оборудования для клонирования. Мы также выполнили клонирование через OSFClone (dd) в Linux.

Мы пытаемся воспроизвести этот (то есть проверяемый хэш файлов) в Windows 7 Embedded (x64), для которого требуется раздел NTFS для ОС.

Test Environment:

  • ОС Windows Embedded Standard 7 EWF включен в режиме RAM на наших томов (C :, D :)
  • NTFSLastAccessUpdate был установлен в "1" в реестра под SYSTEM \ Control \
  • Все Bootstat.dat файлы были удалены с диска до включения EWF и изменения совершаются с помощью ewfmgr

Раньше, чтобы проверить, является ли диск неизменен, я сделал следующее:

  • ботинке устройство с ого диском и остановкой Win после внесения изменений (включен EWF)
  • Подключите Win7e жесткий диск в системе Kali Linux и использовать dd | sha1sum, чтобы получить хэш всего диска
  • Подключите диск Win7e в устройство и загрузитесь, внесите изменения (EWF включен) и повторите dd | Шаг sha1sum на Kali Linux снова (например, dd if =/dev/sda1 | sha1sum), где/dev/sda1 является защищенным EWF разделом Windows.

Подписи, соответствующие этому тесту между различными ботинками. Я снова запускаю тест выше, но это требует времени. [Изменить: я снова запустил тест: EWF работает, и Linux возвращает точные хэши для/dev/sda1 между перезагрузками диска Win7e].NTFSLib и тестовый код, вставленные ниже, НЕ воспроизводят одинаковые сигнатуры защищенного диска EWF.

Проблема: Мы пытались использовать методы CreateFile/ReadFile, а также как «NtfsLib» (https://github.com/LordMike/NtfsLib) читать отдельные файлы, объем и \ \ PhysicalDriveN, но мы не получаем воспроизводимые хэши между перезагрузками из. устройство. То есть мы получаем разные хэши SHA1 для файла Windows (C: \ windows \ windowsupdate.log) каждый раз; мы получаем разные хэши для \. \ C: каждый раз, и каждый раз мы получаем разные хэши для \. \ PhysicalDrive0.

Я вставляю код C# ниже, который я использую для расчета подписей. Я не против переписывать вещь на другом языке, скажем C или C++, если я могу получить необработанные байты с жесткого диска. Скажите, пожалуйста, если я делаю что-то неправильно в чтении необработанных байтов. Мне не нужно читать и хешировать отдельные файлы как таковые. Я могу прочитать весь диск или весь том и хэш его, пока этот хеш совпадает между перезагрузкой устройства. Хеширование всего накопителя или объема будет соответствовать нормативным требованиям. Мне кажется, что байты, которые я получаю от ReadFile, показывают представление EWF о файловой системе.

Я хотел бы получить любые подсказки, которые могут дать мне. Я читал разные сообщения о ReadFile, но не нашел никаких подсказок к этому поведению с EWF.

Я запускаю код ниже в качестве администратора в Windows, и мой app.manifest имеет набор requireAdmin.

using System; 
using System.Runtime.InteropServices; 
using System.Security.Cryptography; 
using Microsoft.Win32.SafeHandles; 


namespace CSharpReadDisk 
{ 
    class DiskReader 
    { 
     public const uint GenericRead = 0x80000000; 
     public const uint FileShareRead = 1; 
     public const uint FileShareWrite = 2; 
     public const uint OpenExisting = 3; 

     [DllImport("kernel32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
     static extern unsafe IntPtr CreateFile(string lpFileName, uint dwDesiredAccess, 
      uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition, 
      uint dwFlagsAndAttributes, IntPtr hTemplateFile); 

     [DllImport("kernel32.dll", SetLastError = true)] 
     static extern unsafe bool ReadFile(IntPtr hFile, void* lpBuffer, 
      uint nNumberOfBytesToRead, uint* lpNumberOfBytesRead, IntPtr lpOverlapped); 

     [DllImport("kernel32", SetLastError = true)] 
     static extern unsafe bool CloseHandle(IntPtr hObject); 


     public unsafe IntPtr Open(string filename) 
     { 
      // open the existing file for reading  
      IntPtr handle = CreateFile(filename, GenericRead, FileShareRead | FileShareWrite, IntPtr.Zero, OpenExisting, 0, IntPtr.Zero); 
      return handle; 
     } 

     public unsafe uint Read(IntPtr handle, byte[] buffer, uint count) 
     { 
      uint n = 0; 
      fixed (byte* p = buffer) 
      { 
       if (!(ReadFile(handle, p, count, &n, IntPtr.Zero))) 
       { 
        return 0; 
       } 
      } 
      return n; 
     } 

     public unsafe bool Close(IntPtr handle) 
     { 
      return CloseHandle(handle); 
     } 
    } 

    class Test 
    { 
     static void Main(string[] args) 
     { 
      DiskReader dr = new DiskReader(); 

      Console.Write("Enter path to drive, volume or file: "); 
      string path = Console.ReadLine(); 
      IntPtr fh = dr.Open(path); 

      try 
      { 
       SafeFileHandle sfh = new SafeFileHandle(fh, true); 
       if (sfh.IsInvalid) 
       { 
        Marshal.ThrowExceptionForHR(Marshal.GetHRForLastWin32Error()); 
       } 

       Console.WriteLine("Enter read buffer size (MB): "); 
       int bs = Console.Read(); 

       byte[] lpBuffer = new byte[bs * 1024 * 1024]; 

       uint bytesRead = 0; 
       SHA1Managed sha1 = new SHA1Managed(); 
       while ((bytesRead = dr.Read(fh, lpBuffer, (uint)lpBuffer.Length)) > 0) 
       { 
        sha1.TransformBlock(lpBuffer, 0, (int)bytesRead, null, 0); 
        Console.Write("."); 
       } 
       sha1.TransformFinalBlock(lpBuffer, 0, (int)bytesRead); 
       Console.WriteLine("\nSHA1: {0}", BitConverter.ToString(sha1.Hash)); 
      } 
      catch (Exception e) 
      { 
       Console.WriteLine("An exception occurred:\n HResult: {0}\n Message: {1}\n InnerException: {2}\n Source: {3}\n TargetSite: {4}\n StackTrace: {5}", 
        e.HResult, e.Message, e.InnerException, e.Source, e.TargetSite, e.StackTrace); 
      } 
      dr.Close(fh); // close filehandle 


      Console.WriteLine("\nPress any key to exit..."); 
      Console.ReadKey(); 
     } 
    } 
} 
+0

Оказывается, EWF является фильтром записи, перенаправляет диск на собственный том EWF. Поведение было изменено между XPe и Win7e, и именно это приводит к тому, что хеши будут отличаться в Win7e. Ссылка: https://msdn.microsoft.com/en-us/library/ms912909(v=winembedded.5).aspx – user3837690

+0

Обновление для любого, кто заинтересован, вы действительно можете перейти под EWF через CreateFile/ReadFile из Win32 API. Вы должны использовать дескриптор \\. \ PhysicalDriveN, а затем читать определенные смежные байты, которые соответствуют интересующему вас тому. Конечно, если вы хотите хэш всего диска, вам не нужно будет читать конкретные байты, соответствующие громкость. – user3837690

+0

Если приложение изменилось во время работы EWF, оно будет выполняться из наложения EWF, а не на диске. Поэтому проверка файлов во время выполнения не представляет собой хороший тест для запускаемого приложения. – leetibbett

ответ

0

Обновление для всех, кто заинтересован, вы действительно можете перейти под EWF через CreateFile/ReadFile из Win32 API. Вы должны использовать дескриптор \. \ PhysicalDriveN, а затем читать определенные байты, соответствующие интересующему вас тому. Это можно сделать с помощью функции SetFilePointer, также предоставляемой Win32 API. Конечно, если вы хотите хэшировать весь диск, вам не нужно будет читать конкретные байты, соответствующие тому. Документы MSDN по этому вопросу не очень ясны, и документы не учитывают конкретный вариант использования EWF.

 Смежные вопросы

  • Нет связанных вопросов^_^