Created
March 12, 2018 21:18
-
-
Save zwetan/d7acc5afc3584662573456a41af62dc9 to your computer and use it in GitHub Desktop.
Detect if Windows AIR executable is 32-bit or 64-bit by parsing the PE format
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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