4

私は今日、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;
4

1 に答える 1

11
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 をデクリメントし、場合によっては配列を解放しようとします。そして、その部分は、配列が指すデータの前にあるrefcount情報にアクセスしますが、これはあなたの場合には有効ではありません.

私の記憶が正しければ、動的配列のメモリ レイアウトは次のようになります。

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

これは、refcount/length フィールドにゴミが含まれているため、問題が発生することを意味します。


次のように宣言したいと思います:

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

(私のデルフィは少し錆びているので、小さな構文エラーがあるかもしれません)

于 2011-06-29T10:13:52.570 に答える