为什么这段代码会产生异常?

发布于 2024-11-17 19:29:24 字数 940 浏览 1 评论 0原文

我今天写了一些代码,它将列出 PE 文件中的所有部分...代码可以工作,但最后它给出一个异常:无效的指针操作...我不知道为什么...有人可以找到吗错误

这是代码

procedure TForm1.Button1Click(Sender: TObject);
var
  IDH:PImageDosHeader;
  buf:Pointer;
  INH:PImageNtHeaders;
  ISH:array of TImageSectionHeader;
  FS:TFileStream;
  i,total:Word;
begin
  if OpenDialog1.Execute then
    begin
        Self.Caption:=OpenDialog1.FileName;
        FS:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead or fmShareDenyNone);
        GetMem(buf,FS.Size);
        FS.Read(buf^,FS.Size);
        FS.Free;
        IDH:=buf;
        INH:=Ptr(Cardinal(buf)+Cardinal(IDH^._lfanew));
        ISH:=Ptr(Cardinal(buf)+Cardinal(IDH^._lfanew) + Sizeof(TImageNtHeaders));
        total:=INH^.FileHeader.NumberOfSections - 1 ;
        for i:=0 to total  do
        begin
              ListBox1.Items.Add(PAnsichar(@ISH[i].Name));
              Application.ProcessMessages;
        end;

    end;
end;

I wrote some code today that will list all the sections in a PE file...the code works but at the end it gives an exception :Invalid pointer operation... and i don't know why...could someone please find the mistake

Here is the code

procedure TForm1.Button1Click(Sender: TObject);
var
  IDH:PImageDosHeader;
  buf:Pointer;
  INH:PImageNtHeaders;
  ISH:array of TImageSectionHeader;
  FS:TFileStream;
  i,total:Word;
begin
  if OpenDialog1.Execute then
    begin
        Self.Caption:=OpenDialog1.FileName;
        FS:=TFileStream.Create(OpenDialog1.FileName,fmOpenRead or fmShareDenyNone);
        GetMem(buf,FS.Size);
        FS.Read(buf^,FS.Size);
        FS.Free;
        IDH:=buf;
        INH:=Ptr(Cardinal(buf)+Cardinal(IDH^._lfanew));
        ISH:=Ptr(Cardinal(buf)+Cardinal(IDH^._lfanew) + Sizeof(TImageNtHeaders));
        total:=INH^.FileHeader.NumberOfSections - 1 ;
        for i:=0 to total  do
        begin
              ListBox1.Items.Add(PAnsichar(@ISH[i].Name));
              Application.ProcessMessages;
        end;

    end;
end;

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

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

发布评论

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

评论(1

疑心病 2024-11-24 19:29:24
ISH:array of TImageSectionHeader;

这声明了一个动态数组。虽然动态数组是指针,但它们在指向的数据前面需要附加数据,包括长度和引用计数。

因此,使其指向 PE 标头中的某些数据是没有意义的:

ISH:=Ptr(Cardinal(buf)+Cardinal(IDH^._lfanew) + Sizeof(TImageNtHeaders));

虽然这部分似乎因某种原因而编译,但访问数组可能会出现错误:

ISH[i]//This might not work correctly since ISH does not point to a valid dynamic array.

或者如果代码在该部分中幸存下来(也许您禁用了数组边界检查或长度信息恰好足够大),然后一旦数组超出范围,delphi 就会尝试减少引用计数并可能释放数组。该部分访问数组指向的数据前面的引用计数信息,这在您的情况下无效。

如果我没记错的话,动态数组的内存布局与此类似:

--------------------------
|refcount|length|data....|
--------------------------
                ^ pointer goes here

这意味着您会遇到问题,因为引用计数/长度字段包含垃圾。


我想你想把它声明为:(

type TImageSectionHeaderArray=array[0..70000]TImageSectionHeader;//No idea what the limit on section headers is
     PImageSectionHeaderArray=^TImageSectionHeaderArray;
...
var ISH:PImageSectionHeaderArray;

我的delphi有点生疏,所以那里可能有一些小的语法错误)

ISH:array of TImageSectionHeader;

This declares a dynamic array. While dynamic arrays are pointers they require additional data in front of the data they point at, including the length and refcount.

Thus making it point to some data in the PE header makes no sense:

ISH:=Ptr(Cardinal(buf)+Cardinal(IDH^._lfanew) + Sizeof(TImageNtHeaders));

While this part seems to compile for some reason, access the array might exhibit the bug:

ISH[i]//This might not work correctly since ISH does not point to a valid dynamic array.

Or if the code survives that part(perhaps you have array bounds checks disabled or the length information happens to be big enough) then delphi once the array goes out of scope delphi tries to decrement the refcount and possibly free the array. And that part accesses the refcount information infront of the data the array points to, which won't be valid in your case.

If I remember correctly the memory layout of a dynamic array is similar to this:

--------------------------
|refcount|length|data....|
--------------------------
                ^ pointer goes here

Which means you'll get problems since the refcount/length fields contain garbage.


I think you want to declare it as:

type TImageSectionHeaderArray=array[0..70000]TImageSectionHeader;//No idea what the limit on section headers is
     PImageSectionHeaderArray=^TImageSectionHeaderArray;
...
var ISH:PImageSectionHeaderArray;

(My delphi is a bit rusty, so there might be some minor syntax errors in there)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文