it-swarm.dev

Yürütülebilir bir platformun hangi platform için derlendiğini nasıl belirleyebilirim?

X86, x64 ve IA64 için yapılan Windows çalıştırılabilir dosyaları ile çalışmaya ihtiyacım var. Dosyaları program aracılığıyla inceleyerek platformu kendim çözmek istiyorum.

Hedef dilim PowerShell, ancak bir C # örneği yapacak. İkisini birden başarısız, eğer gerekli mantığı biliyorsanız, bu harika olurdu.

47
halr9000

(kaldırıldığından beri başka bir Q'dan)

Makine tipi: Bu, bağlayıcı zaman damgasını alan bazılarına göre hızlı bir kod parçası. Bu aynı başlıkta ve işe yaramış gibi görünüyor - derlediğimizde cpu- derlendiğinde I386'yı ve hedef platformla derlendiğinde x64'ü döndürüyor.

Keşfetmek PE Başlıkları (K. Stanton, MSDN) blog girişi, başka bir yanıt belirtildiği gibi, bana ofset gösterdi.

public enum MachineType {
    Native = 0, I386 = 0x014c, Itanium = 0x0200, x64 = 0x8664
}

public static MachineType GetMachineType(string fileName)
{
    const int PE_POINTER_OFFSET = 60;            
    const int MACHINE_OFFSET = 4;
    byte[] data = new byte[4096];
    using (Stream s = new FileStream(fileName, FileMode.Open, FileAccess.Read)) {
        s.Read(data, 0, 4096);
    }
    // dos header is 64 bytes, last element, long (4 bytes) is the address of the PE header
    int PE_HEADER_ADDR = BitConverter.ToInt32(data, PE_POINTER_OFFSET);
    int machineUint = BitConverter.ToUInt16(data, PE_HEADER_ADDR + MACHINE_OFFSET);
    return (MachineType)machineUint;
}
23
Andrew Backer

Visual Studio'yu yüklediyseniz dumpbin.exe kullanabilirsiniz. Yürütülebilir görüntüleri test etmek için kullanılabilecek PowerShell Topluluk Uzantıları içinde Get-PEHeader cmdlet'i var.

Dumpbin, DLL dosyalarını machine (x86) ya da machine (x64) olarak rapor eder.

Get-PEHeader, DLL'leri PE32 veya PE32+ olarak bildirir.

36
Keith Hill

GetBinaryType win32 işlevine ihtiyacınız vardır. Bu, PE formatının yürütülebilir bölümlerinin ilgili kısımlarını döndürür.

Genellikle, BinaryType alanında SCS_32BIT_BINARY veya SCS_64BIT_BINARY'yi alırsınız, 

Alternatif olarak, çalıştırılabilir dosyanın derlendiği mimariyi görmek için PE formatının kendisini kontrol edebilirsiniz.

IMAGE_FILE_HEADER.Machine alanı, IA64 ikili dosyaları için ayarlanmış "IMAGE_FILE_MACHINE_IA64", 32 bit için IMAGE_FILE_MACHINE_I386 ve 64 bit için IMAGE_FILE_MACHINE_AMD64 (yani x86_64) olacaktır.

Gitmenizde size yardımcı olacak bir MSDN dergisi makalesi var.

Ek: Bu size biraz daha yardımcı olabilir. İkili dosyayı bir dosya olarak okursunuz: ilk 2 baytın "MZ" olduğunu söyleyin, ardından bir sonraki 58 baytı atlayın ve sihirsel 32-bit değerini 60 baytta görüntüye (ki bu çalıştırılabilir PE için 0x00004550'ye eşittir) okuyun. Aşağıdaki baytlar bu başlık , ilk 2 baytı size hangi ikili makinenin tasarlandığını söyler (0x8664 = x86_64, 0x0200 = IA64, 0x014c = i386).

(yönetici özeti: resim türünü elde etmek için dosyanın 65 ve 66 baytlarını okuyun)

11
gbjbaanb
Assembly assembly = Assembly.LoadFile(Path.GetFullPath("ConsoleApplication1.exe"));
Module manifestModule = Assembly.ManifestModule;
PortableExecutableKinds peKind;
ImageFileMachine machine;
manifestModule.GetPEKind(out peKind, out machine);

Hedef makine daha sonra makinede olmalıdır.

Ancak, yalnızca .NET derlemeleri ile çalışır.

8
ICR

Buna göre - , DLL veya EXE dosyasının 32 veya 64 olup olmadığını, NotePad ile açarak ve başında "PE" yi arayarak kontrol edebilirsiniz. sonraki harf "L", platformun 32-bit, platformun 64-bit olduğu "D" harfidir.

Benim görevlerimde denedim ve doğru görünüyor.

2
mrelva

IMAGE_FILE_HEADER'e erişmek için (kolayca) bir PowerShell cmdlet'inde derlenebileceğini düşündüğüm bir bazı C # kodlarına bağlantı sunabilirim. Pointers ve PInvoke yeteneği olmadığı için bu yöntemi doğrudan PowerShell betiğinde kullanamayacağınıza eminim.

Bununla birlikte, şu an için geniş kapsamlı PE başlık formatı ;-) bilgilerinizi kullanabilmelisiniz ;-), yalnızca doğru baytlara "dümdüz" gidip onu bulmak. Bu will PowerShell betiğinde çalışır ve sadece Tasos'un blogundan bu C # kodunu betiğine dönüştürebilirsiniz. Buradaki benim olmadığından kodu tekrar etmekten rahatsız olmayacağım.

1
Jaykul

dumpbin.exe, Visual Studio'nun bin dizini altında kullanılabilir .lib ve .dll için çalışıyor 

 dumpbin.exe /headers *.dll |findstr machine
 dumpbin.exe /headers *.lib |findstr machine
0
Saad Saadi

Unix OS, dosyaları tanımlayan "dosya" adında bir yardımcı programa sahiptir. Tanımlama kuralları "sihir" adlı bir açıklama dosyasında tutulur. Dosyalarınızı doğru tanımlayıp tanımlayamadığınızı görmek için dosyayı deneyebilir ve uygun dosyalardan sihirli dosyadan çıkarabilirsiniz.

0
Sec

İşte C'de bir uygulama.

// Determines if DLL is 32-bit or 64-bit.
#include <stdio.h>

int sGetDllType(const char *dll_name);

int main()
{
  int ret;
  const char *fname = "sample_32.dll";
  //const char *fname = "sample_64.dll";
  ret = sGetDllType(fname);
}

static int sGetDllType(const char *dll_name) {
  const int PE_POINTER_OFFSET = 60;
  const int MACHINE_TYPE_OFFSET = 4;
  FILE *fp;
  unsigned int ret = 0;
  int peoffset;
  unsigned short machine;

  fp = fopen(dll_name, "rb");
  unsigned char data[4096];
  ret = fread(data, sizeof(char), 4096, fp);
  fclose(fp);
  if (ret == 0)
    return -1;

  if ( (data[0] == 'M') && (data[1] == 'Z') ) {
    // Initial magic header is good
    peoffset = data[PE_POINTER_OFFSET + 3];
    peoffset = (peoffset << 8) + data[PE_POINTER_OFFSET + 2];
    peoffset = (peoffset << 8) + data[PE_POINTER_OFFSET + 1];
    peoffset = (peoffset << 8) + data[PE_POINTER_OFFSET];

    // Check second header
    if ((data[peoffset] == 'P') && (data[peoffset + 1] == 'E')) {
      machine = data[peoffset + MACHINE_TYPE_OFFSET];
      machine = (machine)+(data[peoffset + MACHINE_TYPE_OFFSET + 1] << 8);

      if (machine == 0x014c)
        return 32;
      if (machine == 0x8664)
        return 64;

      return -1;
    }
    return -1;
  }
  else
    return -1;
}
0
Jiminion

İşte benim kendi uygulamam, bunun için birkaç kontrol daha var ve her zaman bir sonuç ortaya çıkıyor.

// the enum of known pe file types
public enum FilePEType : 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,
}

// pass the path to the file and check the return
public static FilePEType GetFilePE(string path)
{
    FilePEType pe = new FilePEType();
    pe = FilePEType.IMAGE_FILE_MACHINE_UNKNOWN;
    if(File.Exists(path))
    {
        using (var fs = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
        {
            byte[] data = new byte[4096];
            fs.Read(data, 0, 4096);
            ushort result = BitConverter.ToUInt16(data, BitConverter.ToInt32(data, 60) + 4);
            try
            {
                pe = (FilePEType)result;
            } catch (Exception)
            {
                pe = FilePEType.IMAGE_FILE_MACHINE_UNKNOWN;
            }
        }
    }
    return pe;
}

Nasıl kullanılır :

string myfile = @"c:\windows\Explorer.exe"; // the file
FilePEType pe = GetFilePE( myfile );

System.Diagnostics.WriteLine( pe.ToString() );

Burada kullanılan enum değerleri için, pe.go 'den elde edildi. Bunun işe yaramasının nedeni, 'gitme' her ikilik dağılımı için, işletim sistemlerini geçmesine izin vermek için Mecliste doğru bayrağa sahip olması gerektiğidir 'burada koşabilir misiniz?' Kontrol. 'Go' çapraz platform (tüm platformlar) olduğundan, bu bilgiyi almak için iyi bir temeldir. Muhtemelen bu bilgi için başka kaynaklar da var, ancak Google-ca’da bulmak için Google-fu’da 10. dan bir kara kuşak gerektiren go-ca-ca’nın derinliklerine yerleştirilmiş görünüyorlar. 

0
Kraang Prime