Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why this code generates an exception?

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;
like image 528
opc0de Avatar asked Dec 21 '22 12:12

opc0de


1 Answers

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)

like image 150
CodesInChaos Avatar answered Dec 28 '22 08:12

CodesInChaos