Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium

x
?
Solved

Query if a file is compiled as 32 or 64 bit

Posted on 2013-06-15
4
Medium Priority
?
529 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 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

[Webinar On Demand] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

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

Introduction Raise your hands if you were as upset with FireMonkey as I was when I discovered that there was no TListview.  I use TListView in almost all of my applications I've written, and I was not going to compromise by resorting to TStringGrid…
In my programming career I have only very rarely run into situations where operator overloading would be of any use in my work.  Normally those situations involved math with either overly large numbers (hundreds of thousands of digits or accuracy re…
Integration Management Part 2
When cloud platforms entered the scene, users and companies jumped on board to take advantage of the many benefits, like the ability to work and connect with company information from various locations. What many didn't foresee was the increased risk…
Suggested Courses
Course of the Month15 days, 19 hours left to enroll

580 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