Solved

Query if a file is compiled as 32 or 64 bit

Posted on 2013-06-15
4
467 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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

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

Suggested Solutions

A lot of questions regard threads in Delphi.   One of the more specific questions is how to show progress of the thread.   Updating a progressbar from inside a thread is a mistake. A solution to this would be to send a synchronized message to the…
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…
This Micro Tutorial demonstrates using Microsoft Excel pivot tables, how to reverse engineer competitors' marketing strategies through backlinks.
Microsoft Active Directory, the widely used IT infrastructure, is known for its high risk of credential theft. The best way to test your Active Directory’s vulnerabilities to pass-the-ticket, pass-the-hash, privilege escalation, and malware attacks …

813 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

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now