?
Solved

Query if a file is compiled as 32 or 64 bit

Posted on 2013-06-15
4
Medium Priority
?
497 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
[X]
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
  • 2
4 Comments
 

Author Comment

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

Accepted Solution

by:
Ferruccio Accalai earned 2000 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:Ephraim Wangoya
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

Free Tool: SSL Checker

Scans your site and returns information about your SSL implementation and certificate. Helpful for debugging and validating your SSL configuration.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Objective: - This article will help user in how to convert their numeric value become words. How to use 1. You can copy this code in your Unit as function 2. than you can perform your function by type this code The Code   (CODE) The Im…
Introduction I have seen many questions in this Delphi topic area where queries in threads are needed or suggested. I know bumped into a similar need. This article will address some of the concepts when dealing with a multithreaded delphi database…
Do you want to know how to make a graph with Microsoft Access? First, create a query with the data for the chart. Then make a blank form and add a chart control. This video also shows how to change what data is displayed on the graph as well as form…
In response to a need for security and privacy, and to continue fostering an environment members can turn to for support, solutions, and education, Experts Exchange has created anonymous question capabilities. This new feature is available to our Pr…
Suggested Courses

719 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