Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people, just like you, are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
Solved

Query if a file is compiled as 32 or 64 bit

Posted on 2013-06-15
4
468 Views
Last Modified: 2013-06-19
Hi Experts.

Here I got a example on how to query header in file path, but its of type TStream.
So I ask you experts is there any way to detect if a file is compiled as 32 or 64 bit file?
And the routine must be able to take FileName path as parameter and return boolean if its a 64 bit file, and false if its a 32 bit file.

function Isx64(const Strm: TStream): Boolean;
const
  IMAGE_FILE_MACHINE_I386     = $014c; // Intel x86
  IMAGE_FILE_MACHINE_IA64     = $0200; // Intel Itanium Processor Family (IPF)
  IMAGE_FILE_MACHINE_AMD64    = $8664; // x64 (AMD64 or EM64T)
  // You'll unlikely encounter the things below:
  IMAGE_FILE_MACHINE_R3000_BE = $160;  // MIPS big-endian
  IMAGE_FILE_MACHINE_R3000    = $162;  // MIPS little-endian, 0x160 big-endian
  IMAGE_FILE_MACHINE_R4000    = $166;  // MIPS little-endian
  IMAGE_FILE_MACHINE_R10000   = $168;  // MIPS little-endian
  IMAGE_FILE_MACHINE_ALPHA    = $184;  // Alpha_AXP }
  IMAGE_FILE_MACHINE_POWERPC  = $1F0;  // IBM PowerPC Little-Endian
var
  Header: TImageDosHeader;
  ImageNtHeaders: TImageNtHeaders;
begin
  Strm.ReadBuffer(Header, SizeOf(Header));
  if (Header.e_magic <> IMAGE_DOS_SIGNATURE) or
     (Header._lfanew = 0) then
    raise Exception.Create('Invalid executable');
  Strm.Position := Header._lfanew;

  Strm.ReadBuffer(ImageNtHeaders, SizeOf(ImageNtHeaders));
  if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
    raise Exception.Create('Invalid executable');

  Result := ImageNtHeaders.FileHeader.Machine <> IMAGE_FILE_MACHINE_I386;
end;
0
Comment
Question by:DelphiEmil
  • 2
4 Comments
 

Author Comment

by:DelphiEmil
ID: 39251600
Any Delphi expert here?
0
 
LVL 22

Accepted Solution

by:
Ferruccio Accalai earned 500 total points
ID: 39252682
You can use your function this way

function Isx64(const Strm: TStream): Boolean;
const
  IMAGE_FILE_MACHINE_I386 = $014C; // Intel x86
  IMAGE_FILE_MACHINE_IA64 = $0200; // Intel Itanium Processor Family (IPF)
  IMAGE_FILE_MACHINE_AMD64 = $8664; // x64 (AMD64 or EM64T)
  // You'll unlikely encounter the things below:
  IMAGE_FILE_MACHINE_R3000_BE = $160; // MIPS big-endian
  IMAGE_FILE_MACHINE_R3000 = $162; // MIPS little-endian, 0x160 big-endian
  IMAGE_FILE_MACHINE_R4000 = $166; // MIPS little-endian
  IMAGE_FILE_MACHINE_R10000 = $168; // MIPS little-endian
  IMAGE_FILE_MACHINE_ALPHA = $184; // Alpha_AXP }
  IMAGE_FILE_MACHINE_POWERPC = $1F0; // IBM PowerPC Little-Endian
var
  Header: TImageDosHeader;
  ImageNtHeaders: TImageNtHeaders;
begin
  Strm.ReadBuffer(Header, SizeOf(Header));
  if (Header.e_magic <> IMAGE_DOS_SIGNATURE) or (Header._lfanew = 0) then
    raise Exception.Create('Invalid executable');
  Strm.Position := Header._lfanew;
  Strm.ReadBuffer(ImageNtHeaders, SizeOf(ImageNtHeaders));
  if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
    raise Exception.Create('Invalid executable');
  Result := ImageNtHeaders.FileHeader.Machine <> IMAGE_FILE_MACHINE_I386;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  Stream: TStream;
  OpenDialog: TOpenDialog;
  i: Integer;
begin
  OpenDialog := TOpenDialog.Create(nil);
  with OpenDialog do
    try
      Filter := 'Executable files|*.exe';
      if execute then
      begin
        Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
        try
          if Isx64(Stream) then
            i := 64
          else
            i := 32;
          showmessage(Format('%s was compiled as %d bit', [OpenDialog.FileName, i]));
        finally
          Stream.Free;
        end;
      end;
    finally
      OpenDialog.Free;
    end;
end;

Open in new window

0
 
LVL 32

Expert Comment

by:ewangoya
ID: 39258550
You could simply write a second overloaded function

function Isx64(const Strm: TStream): Boolean; overload;
function Isx64(const AFileName: string): Boolean; overload;

implementation

function Isx64(const Strm: TStream): Boolean;
const
  IMAGE_FILE_MACHINE_I386 = $014C; // Intel x86
  IMAGE_FILE_MACHINE_IA64 = $0200; // Intel Itanium Processor Family (IPF)
  IMAGE_FILE_MACHINE_AMD64 = $8664; // x64 (AMD64 or EM64T)
  // You'll unlikely encounter the things below:
  IMAGE_FILE_MACHINE_R3000_BE = $160; // MIPS big-endian
  IMAGE_FILE_MACHINE_R3000 = $162; // MIPS little-endian, 0x160 big-endian
  IMAGE_FILE_MACHINE_R4000 = $166; // MIPS little-endian
  IMAGE_FILE_MACHINE_R10000 = $168; // MIPS little-endian
  IMAGE_FILE_MACHINE_ALPHA = $184; // Alpha_AXP }
  IMAGE_FILE_MACHINE_POWERPC = $1F0; // IBM PowerPC Little-Endian
var
  Header: TImageDosHeader;
  ImageNtHeaders: TImageNtHeaders;
begin
  Strm.ReadBuffer(Header, SizeOf(Header));
  if (Header.e_magic <> IMAGE_DOS_SIGNATURE) or (Header._lfanew = 0) then
    raise Exception.Create('Invalid executable');
  Strm.Position := Header._lfanew;
  Strm.ReadBuffer(ImageNtHeaders, SizeOf(ImageNtHeaders));
  if ImageNtHeaders.Signature <> IMAGE_NT_SIGNATURE then
    raise Exception.Create('Invalid executable');
  Result := ImageNtHeaders.FileHeader.Machine <> IMAGE_FILE_MACHINE_I386;
end;

function Isx64(const AFileName: string): Boolean; overload;
var
  Stream: TFileStream;
begin
  if not FileExists(AFileName) then
    raise Exception.Create('Invalid file');
  Stream := TFileStream.Create(AFileName, fmOpenRead);
  try
    Result := Isx64(Stream);
  finally
    Stream.Free;
  end;
end;

Open in new window

0
 

Author Closing Comment

by:DelphiEmil
ID: 39258949
Yes it works very good.
0

Featured Post

Announcing the Most Valuable Experts of 2016

MVEs are more concerned with the satisfaction of those they help than with the considerable points they can earn. They are the types of people you feel privileged to call colleagues. Join us in honoring this amazing group of Experts.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

This article explains how to create forms/units independent of other forms/units object names in a delphi project. Have you ever created a form for user input in a Delphi project and then had the need to have that same form in a other Delphi proj…
Have you ever had your Delphi form/application just hanging while waiting for data to load? This is the article to read if you want to learn some things about adding threads for data loading in the background. First, I'll setup a general applica…
The Email Laundry PDF encryption service allows companies to send confidential encrypted  emails to anybody. The PDF document can also contain attachments that are embedded in the encrypted PDF. The password is randomly generated by The Email Laundr…
In a recent question (https://www.experts-exchange.com/questions/29004105/Run-AutoHotkey-script-directly-from-Notepad.html) here at Experts Exchange, a member asked how to run an AutoHotkey script (.AHK) directly from Notepad++ (aka NPP). This video…

809 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question