Почему этот код генерирует исключение? - PullRequest
4 голосов
/ 29 июня 2011

Сегодня я написал некоторый код, который перечислит все разделы в 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;

1 Ответ

11 голосов
/ 29 июня 2011
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, когда массив выходит из области видимости 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;

(Мой delphi немного ржавый, поэтому там могут быть небольшие синтаксические ошибки)

...