Forum > Windows

Getting File Size from PE Header Fails with Lazarus

(1/8) > >>

msintle:
So here's an odd one. Code like this works beautifully in Delphi:


--- Code: Pascal  [+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i < x.length; i++) { x[i].style.maxHeight='none'; x[i].style.height = Math.min(x[i].clientHeight+15,306)+'px'; x[i].style.resize = "vertical";}};} ---{ call passing HInstance as the Executable parameter, add Windows to uses }function GetExeSize(Executable: THandle): Cardinal;type  PImageDosHeader = ^TImageDosHeader;  TImageDosHeader = packed record    e_magic: Word;    e_ignore: packed array [0..28] of Word;    _lfanew: Longint;  end;var  i, NumSections: Integer;  p: PAnsiChar;begin  Result := 0;  p := Pointer(Executable);  Inc(p, PImageDosHeader(p)^._lfanew + SizeOf(DWORD));  NumSections := PImageFileHeader(p)^.NumberOfSections;  Inc(p, SizeOf(TImageFileHeader) + SizeOf(TImageOptionalHeader));  for i := 1 to NumSections do  begin    with PImageSectionHeader(p)^ do      if PointerToRawData+SizeOfRawData > Result then        Result := PointerToRawData + SizeOfRawData;    Inc(p, SizeOf(TImageSectionHeader));  end;end;
But it fails in Lazarus.

To clarify, it does still compile and run - but returns the wrong file size (always falling short a bit).

Is Lazarus constructing the PE header differently somehow, perhaps?

Fibonacci:
Works 100% fine if reading 32bit i386.

For 64bit the code will be differet. eg TImageOptionalHeader default is TImageOptionalHeader32, and for 64bit you need to use TImageOptionalHeader64

BTW. Remove debug info, this is non standard and weird method to get "file size"

msintle:

--- Quote from: Fibonacci on October 24, 2023, 09:11:32 pm ---Works 100% fine if reading 32bit i386.

--- End quote ---

Not for me. I am building x86 targets. Happy to upload both a console and a GUI test app if people would like. Reproduces instantly.


--- Quote from: Fibonacci on October 24, 2023, 09:11:32 pm ---For 64bit the code will be differet. eg TImageOptionalHeader default is TImageOptionalHeader32, and for 64bit you need to use TImageOptionalHeader64

--- End quote ---

Thanks for noting that, will definitely come in handy in the future.


--- Quote from: Fibonacci on October 24, 2023, 09:11:32 pm ---BTW. Remove debug info, this is non standard and weird method to get "file size"

--- End quote ---

How do you mean? In Delphi, it works properly even with debug info. Is the way Lazarus is adding debug information then non-standard and breaking the standard header based file size calculation process?

Regarding your comment that this is a weird method to get file size, it is the only method to get file size when you are building a stub application (such as a self-extractor which would have an archive of variable size appended to its end, for example).

440bx:
@msintle,

For a general utility your code will _not_ work because sizeof(TImageOptionalHeader) is likely determined at compile time (otherwise the code you showed would not compile.)

if that code has to deal with executables other than itself then it will only be right when the executable it is dealing with happens to be the same bitness as the program.  If the bitness  between them differ then the result will be wrong due to the wrong size of TImageOptionalHeader.

On a different note, why do you calculate the file size that way instead of simply asking the O/S for the file size ?

HTH.

KodeZwerg:
I do use something similar in my Advanced-Properties app that was compiled with Delphi.
It is very handy to detect anything that in my app I declared as "overlay" (or extract/strip such data)
It is also very reliable used in stubs (no matter what bitness when using correct header translation) to detect the end of stub in a 100% accurate way.
Many oldschool and also newschool archivers that do produce executable files, like WinRAR, are using this way to know where streaming of archive begin.

To OP:
I will try to port my way, pure WinAPI, to Lazarus and send source here.

Navigation

[0] Message Index

[#] Next page

Go to full version