Skip to content

Instantly share code, notes, and snippets.

@zwetan zwetan/Test.as
Created Mar 12, 2018

Embed
What would you like to do?
Detect if Windows AIR executable is 32-bit or 64-bit by parsing the PE format
package
{
public class Test
{
private var _is64bit:Boolean;
public function Test()
{
_is64bit = false;
}
/* Usage:
when compiled with AIR_WIN_ARCH=64 should returns `true`
and when compiled with AIR_WIN_ARCH=32 should returns `false`
see: PE Format
https://msdn.microsoft.com/library/windows/desktop/ms680547(v=vs.85).aspx
https://en.wikipedia.org/wiki/Portable_Executable
*/
public function is64bit():Boolean
{
_parsePE();
return _is64bit;
}
public function hex( value:Number, length:uint = 4 ):String
{
if( value < 0 )
{
value = value * -1;
}
var h:String = "";
var v:String = value.toString( 16 );
while( v.length < length )
{
v = "0" + v;
}
h += v;
return h;
}
private function _getAIRExecutable():String
{
var na:NativeApplication = NativeApplication.nativeApplication;
var air_file:String = "";
if( na )
{
var descriptor:XML = na.applicationDescriptor;
var ns:Namespace = descriptor.namespace();
air_file = descriptor.ns::filename;
}
if( air_file != "" )
{
air_file += ".exe";
}
return air_file;
}
/* Note:
When you test locally with Flash Builder there are no `.exe` file
you will have first to "Export Release Build ..."
then copy the exe file into the bin-debug folder so it can be found in debug launch
If you are under Windows 10 or have Cygwin installed
you can alos use the `file` command-line utility to test the exe
eg. for a 32-bit
`PE32 executable (GUI) Intel 80386, for MS Windows`
and for a 64-bit
`PE32+ executable (GUI) x86-64, for MS Windows`
*/
private function _parsePE():void
{
var air_exe:String = _getAIRExecutable();
var air_file:File = File.applicationDirectory;
air_file = air_file.resolvePath( air_exe );
if( air_file.exists )
{
const AMD64:uint = 0x8664;
const I386:uint = 0x014c;
var fs:FileStream = new FileStream();
fs.endian = Endian.LITTLE_ENDIAN;
fs.open( air_file, FileMode.READ );
trace( "endian = " + fs.endian );
trace( "bytesAvailable = " + fs.bytesAvailable );
trace( "position = " + fs.position );
// MZ magic number
var peMZ:int = fs.readShort(); // 0x5a4d - MZ
trace( "peMZ = " + peMZ + " - 0x" + hex(peMZ,2) );
// PE Header offset is always at 0x3C
fs.position = 0x3c;
trace( "position = " + fs.position );
var peOffset:int = fs.readShort();
trace( "peOffset = " + peOffset + " - 0x" + hex(peOffset,2) );
fs.position = peOffset;
// PE Header Signature is always PE\0\0
var peHead:uint = fs.readUnsignedInt(); // 0x00004550 - PE\0\0
trace( "peHead = " + peHead + " - 0x" + hex(peHead,8) );
/*
public enum MachineType : ushort
{
IMAGE_FILE_MACHINE_UNKNOWN = 0x0,
IMAGE_FILE_MACHINE_AM33 = 0x1d3,
IMAGE_FILE_MACHINE_AMD64 = 0x8664,
IMAGE_FILE_MACHINE_ARM = 0x1c0,
IMAGE_FILE_MACHINE_EBC = 0xebc,
IMAGE_FILE_MACHINE_I386 = 0x14c,
IMAGE_FILE_MACHINE_IA64 = 0x200,
IMAGE_FILE_MACHINE_M32R = 0x9041,
IMAGE_FILE_MACHINE_MIPS16 = 0x266,
IMAGE_FILE_MACHINE_MIPSFPU = 0x366,
IMAGE_FILE_MACHINE_MIPSFPU16 = 0x466,
IMAGE_FILE_MACHINE_POWERPC = 0x1f0,
IMAGE_FILE_MACHINE_POWERPCFP = 0x1f1,
IMAGE_FILE_MACHINE_R4000 = 0x166,
IMAGE_FILE_MACHINE_SH3 = 0x1a2,
IMAGE_FILE_MACHINE_SH3DSP = 0x1a3,
IMAGE_FILE_MACHINE_SH4 = 0x1a6,
IMAGE_FILE_MACHINE_SH5 = 0x1a8,
IMAGE_FILE_MACHINE_THUMB = 0x1c2,
IMAGE_FILE_MACHINE_WCEMIPSV2 = 0x169,
}
*/
// 2-byte machine type
var machineType:uint = fs.readUnsignedShort();
trace( "machineType = " + machineType + " - 0x" + hex(machineType,4) );
if( machineType == AMD64 )
{
trace( "AIR is 64-bit" );
_is64bit = true;
}
else if( machineType == I386 )
{
trace( "AIR is 32-bit" );
_is64bit = false;
}
else
{
trace( "AIR is UNKNOWN" );
_is64bit = false;
}
fs.close();
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.