getpearch.pl 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/usr/bin/perl
  2. #
  3. # Get the appropriate variables to make an NSIS installer file
  4. # based on the PE architecture of a specific file
  5. #
  6. use strict;
  7. use bytes;
  8. my %archnames = (
  9. 0x01de => 'am33',
  10. 0x8664 => 'x64',
  11. 0x01c0 => 'arm32',
  12. 0x01c4 => 'thumb',
  13. 0xaa64 => 'arm64',
  14. 0x0ebc => 'efi',
  15. 0x014c => 'x86',
  16. 0x0200 => 'ia64',
  17. 0x9041 => 'm32r',
  18. 0x0266 => 'mips16',
  19. 0x0366 => 'mips',
  20. 0x0466 => 'mips16',
  21. 0x01f0 => 'powerpc',
  22. 0x01f1 => 'powerpc',
  23. 0x0166 => 'mips',
  24. 0x01a2 => 'sh3',
  25. 0x01a3 => 'sh3',
  26. 0x01a6 => 'sh4',
  27. 0x01a8 => 'sh5',
  28. 0x01c2 => 'arm32',
  29. 0x0169 => 'wcemipsv2'
  30. );
  31. my ($file) = @ARGV;
  32. open(my $fh, '<', $file)
  33. or die "$0: cannot open file: $file: $!\n";
  34. read($fh, my $mz, 2);
  35. exit 1 if ($mz ne 'MZ');
  36. exit 0 unless (seek($fh, 0x3c, 0));
  37. exit 0 unless (read($fh, my $pe_offset, 4) == 4);
  38. $pe_offset = unpack("V", $pe_offset);
  39. exit 1 unless (seek($fh, $pe_offset, 0));
  40. read($fh, my $pe, 4);
  41. exit 1 unless ($pe eq "PE\0\0");
  42. exit 1 unless (read($fh, my $arch, 2) == 2);
  43. $arch = $archnames{unpack("v", $arch)};
  44. if (defined($arch)) {
  45. print "!define ARCH ${arch}\n";
  46. }
  47. exit 1 unless (seek($fh, 14, 1));
  48. exit 1 unless (read($fh, my $auxheaderlen, 2) == 2);
  49. exit 1 unless (unpack("v", $auxheaderlen) >= 2);
  50. exit 1 unless (seek($fh, 2, 1));
  51. exit 1 unless (read($fh, my $petype, 2) == 2);
  52. $petype = unpack("v", $petype);
  53. if ($petype == 0x010b) {
  54. # It is a 32-bit PE32 file
  55. print "!define BITS 32\n";
  56. print "!define GLOBALINSTDIR \$PROGRAMFILES\n";
  57. } elsif ($petype == 0x020b) {
  58. # It is a 64-bit PE32+ file
  59. print "!define BITS 64\n";
  60. print "!define GLOBALINSTDIR \$PROGRAMFILES64\n";
  61. } else {
  62. # No idea...
  63. exit 1;
  64. }
  65. close($fh);
  66. exit 0;