与 CreateFile Handle 相关的 512 字节数组中的值的 IntToHex 总是返回相同的输出? FreePascal\Delphi 语法。

发布于 2025-01-01 11:59:42 字数 1883 浏览 0 评论 0原文

长话短说,我的程序允许对事物进行哈希处理。它目前缺乏的一件事是 Windows 版本中散列物理磁盘的能力(Linux 版本允许用户选择 /dev/sda 等)。

我创建了一个按钮,单击该按钮时,会列出连接的设备,给我“\.\PHYSICALDISKX”(感谢 SO 用户回复我之前的帖子的建议)。然后,当用户双击该值时,我可以将该值传递给 Windows API 函数 CreateFile,以创建它的句柄作为 ListBox 双击事件。所以我已经完成了所有这些。下面的代码参考。

但是,我想检查我建立的 CreateFile 句柄是否正在工作 - if 语句表明它正在工作,但我需要检查我是否可以实际读取数据以传递给我的其他函数。为了测试这一点,我尝试读取任何给定磁盘的前 512 个字节,并“quickyl”将其显示在备忘录框中。然而,我一生都无法弄清楚为什么我的输出不正确,但事实确实如此。我得到一些十六进制值,但它们与前 512 字节中存在的十六进制值不同。而且无论我查看哪个磁盘,它们始终是相同的十六进制值列表!所以我不知道这些值从哪里来,也不知道为什么它们总是相同的。整个想法是让我检查我的句柄是否正常,并且我实际上可以从磁盘读取数据,然后传递给我的哈希函数。

谁能看出我哪里出了问题吗?

procedure TForm1.ListBox1DblClick(Sender: TObject);
var
   listBox : TListBox;
   index   : Integer;
   hDiskToHash, i : integer;
   DiskHashValue, DiskToHashFileName, TmpStr : string;
   RawMBR : array [0..511] of byte;
   bytesread : DWORD;
 begin
   i := 0;
   // Cast the passed object to its correct type
   listBox := TListBox(Sender);

   // Get the index of the selected list item
   index   := listBox.ItemIndex;

   // Display the selected list item value
   ShowMessage(listBox.Items[index]);

   // sValue1 is a global variable containing string '\\.\PHYSICALDISKX', populated by procedure TForm1.GetWin32_DiskDriveInfo;
   hDiskToHash := Windows.CreateFile(PChar(sValue1), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
   if hDiskToHash <> INVALID_HANDLE_VALUE then
   begin
      SetFilePointer(hDiskToHash,512 * 0,nil,FILE_BEGIN); // replace 0 with sector that you wish to read
      ReadFile(hDiskToHash, RawMBR[0], SizeOf(RawMBR), bytesread, nil);
      for i := Low(RawMBR) to High(RawMBR) do
        begin
        Memo2.Lines.Add(IntToHex(RawMBR[i],2)); // Add each hex byte on a new line
        end;
      CloseHandle(hDiskToHash);
   end
   else
   begin
    ShowMessage('Failed to open '+sValue1);
   end;
 end; 

Long story short, my program allows the hashing of things. The one thing it currently lacks is the ability to hash physical disks in Windows version (the Linux version allows the user to select /dev/sda etc).

I have created a button that, when clicked, lists the attached devices to give me "\.\PHYSICALDISKX" (thanks to suggestions from SO users in reply to my earlier posts). I can then pass that value to the Windows API function, CreateFile, when the user double clicks it, to create a handle to it as a ListBox double click event. So I've done all of that. Code below refers.

However, I want to check that the CreateFile handle that I've established is working - the if statement suggests that it is, but I need to check I can actually read data to pass to my other functions. To test that, I am trying to read in the first 512 bytes of any given disk and "quickyl" display it in a memo box. However, I can't for the life of me work out why my output is incorrect, which it is. I get some hex values, but they are not the same hex values that are present in the the first 512 bytes. And they are always the same list of hex values, regardless of what disk I look at! So I have no clue where these values are coming from or why theey are always the same. The whole idea is for me to check my handle is OK and that I can in fact read data from the disk for me to then pass to my hashing functions.

Can anyone see where I am going wrong please?

procedure TForm1.ListBox1DblClick(Sender: TObject);
var
   listBox : TListBox;
   index   : Integer;
   hDiskToHash, i : integer;
   DiskHashValue, DiskToHashFileName, TmpStr : string;
   RawMBR : array [0..511] of byte;
   bytesread : DWORD;
 begin
   i := 0;
   // Cast the passed object to its correct type
   listBox := TListBox(Sender);

   // Get the index of the selected list item
   index   := listBox.ItemIndex;

   // Display the selected list item value
   ShowMessage(listBox.Items[index]);

   // sValue1 is a global variable containing string '\\.\PHYSICALDISKX', populated by procedure TForm1.GetWin32_DiskDriveInfo;
   hDiskToHash := Windows.CreateFile(PChar(sValue1), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0);
   if hDiskToHash <> INVALID_HANDLE_VALUE then
   begin
      SetFilePointer(hDiskToHash,512 * 0,nil,FILE_BEGIN); // replace 0 with sector that you wish to read
      ReadFile(hDiskToHash, RawMBR[0], SizeOf(RawMBR), bytesread, nil);
      for i := Low(RawMBR) to High(RawMBR) do
        begin
        Memo2.Lines.Add(IntToHex(RawMBR[i],2)); // Add each hex byte on a new line
        end;
      CloseHandle(hDiskToHash);
   end
   else
   begin
    ShowMessage('Failed to open '+sValue1);
   end;
 end; 

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

双手揣兜 2025-01-08 11:59:42

您运行的是哪个版本的 Windows? CreateFile() 文档指出:

对磁盘或卷的直接访问受到限制。了解更多
信息,请参阅“对文件系统和存储堆栈的更改
限制 Windows 中的直接磁盘访问和直接卷访问
Vista 和 Windows Server 2008 中的“帮助和支持知识”
基地位于http://support.microsoft.com/kb/942448

话虽如此,试试这个:

procedure TForm1.ListBox1DblClick(Sender: TObject); 
var 
  listBox : TListBox; 
  index   : Integer; 
  hDiskToHash: THandle;
  i : integer; 
  RawMBR : array [0..511] of Byte; 
  Offset, BytesRead : DWORD; 
begin 
  // Cast the passed object to its correct type 
  listBox := TListBox(Sender); 

  // Get the index of the selected list item 
  index := listBox.ItemIndex; 
  if index = -1 then Exit;

  // Display the selected list item value 
  ShowMessage(listBox.Items[index]); 

  // sValue1 is a global variable containing string '\\.\PHYSICALDISKX',
  // populated by procedure TForm1.GetWin32_DiskDriveInfo; 
  hDiskToHash := Windows.CreateFile(PChar(sValue1), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0); 
  if hDiskToHash = INVALID_HANDLE_VALUE then RaiseLastOSError;
  try
    Offset := 512 * 0; // replace 0 with sector that you wish to read 

    if (SetFilePointer(hDiskToHash, Offset, nil, FILE_BEGIN) <> Offset) then raise Exception.Create("Did not seek to sector 0 correctly!");

    if not ReadFile(hDiskToHash, RawMBR[0], SizeOf(RawMBR), BytesRead, nil) then RaiseLastOSError;
    if BytesRead <> SizeOf(RawMBR) then raise Exception.Create("Did not read the full MBR!");

    for i := 0 to BytesRead-1 do 
    begin 
      Memo2.Lines.Add(IntToHex(RawMBR[i], 2)); // Add each hex byte on a new line 
    end; 
  finally
    CloseHandle(hDiskToHash); 
  end;
end;  

Which version of Windows are you running on? The CreateFile() documentation states:

Direct access to the disk or to a volume is restricted. For more
information, see "Changes to the file system and to the storage stack
to restrict direct disk access and direct volume access in Windows
Vista and in Windows Server 2008" in the Help and Support Knowledge
Base at http://support.microsoft.com/kb/942448.

With that said, try this:

procedure TForm1.ListBox1DblClick(Sender: TObject); 
var 
  listBox : TListBox; 
  index   : Integer; 
  hDiskToHash: THandle;
  i : integer; 
  RawMBR : array [0..511] of Byte; 
  Offset, BytesRead : DWORD; 
begin 
  // Cast the passed object to its correct type 
  listBox := TListBox(Sender); 

  // Get the index of the selected list item 
  index := listBox.ItemIndex; 
  if index = -1 then Exit;

  // Display the selected list item value 
  ShowMessage(listBox.Items[index]); 

  // sValue1 is a global variable containing string '\\.\PHYSICALDISKX',
  // populated by procedure TForm1.GetWin32_DiskDriveInfo; 
  hDiskToHash := Windows.CreateFile(PChar(sValue1), GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_FLAG_RANDOM_ACCESS, 0); 
  if hDiskToHash = INVALID_HANDLE_VALUE then RaiseLastOSError;
  try
    Offset := 512 * 0; // replace 0 with sector that you wish to read 

    if (SetFilePointer(hDiskToHash, Offset, nil, FILE_BEGIN) <> Offset) then raise Exception.Create("Did not seek to sector 0 correctly!");

    if not ReadFile(hDiskToHash, RawMBR[0], SizeOf(RawMBR), BytesRead, nil) then RaiseLastOSError;
    if BytesRead <> SizeOf(RawMBR) then raise Exception.Create("Did not read the full MBR!");

    for i := 0 to BytesRead-1 do 
    begin 
      Memo2.Lines.Add(IntToHex(RawMBR[i], 2)); // Add each hex byte on a new line 
    end; 
  finally
    CloseHandle(hDiskToHash); 
  end;
end;  
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文