Cum pot determina pentru care platforma un executabil este compilat?

voturi
46

Am nevoie de a lucra cu executabilele Windows, care sunt făcute pentru x86, x64 și IA64. Aș vrea să dau programatic pe platforma prin examinarea dosarelor în sine.

Limba mea țintă este PowerShell, dar un exemplu C # va face. În lipsa uneia dintre acestea, dacă știți logica necesară, care ar fi grozav.

Întrebat 13/10/2008 la 16:16
sursa de către utilizator
În alte limbi...                            


10 răspunsuri

voturi
0

Sistemul de operare Unix au un utilitar numit „dosar“, care identifică fișierele. Regulile de identificare sunt păstrate într-un fișier de descriere numit „magic“. Ai putea încerca fișier pentru a vedea dacă acesta este capabil să identifice fișierele în mod corect și apuca normele corespunzătoare din fișierul magie.

Publicat 13/10/2008 la 16:23
sursa de către utilizator

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

Mașina țintă ar trebui să fie apoi în mașină.

Asta va funcționa doar cu ansambluri NET, deși.

Publicat 13/10/2008 la 16:33
sursa de către utilizator

voturi
11

Ai nevoie de funcția win32 GetBinaryType. Acest lucru va reveni părțile relevante ale executabil PE-format.

De obicei, veți obține fie SCS_32BIT_BINARY sau SCS_64BIT_BINARY în domeniul BinaryType,

Alternativaly puteți verifica formatul PE în sine pentru a vedea ce arhitectura executabil este compilat pentru.

Câmpul IMAGE_FILE_HEADER.Machine va avea "IMAGE_FILE_MACHINE_IA64" stabilit pentru binarele IA64, IMAGE_FILE_MACHINE_I386 pentru 32 de biți și IMAGE_FILE_MACHINE_AMD64 pentru 64-biți (de exemplu x86_64).

Există un articol de revista MSDN pentru a vă ajuta să obțineți merge.

Addendum: Acest lucru vă poate ajuta un pic mai mult. Ai citit binar ca un fișier: verificați primele 2 octeți spun „MZ“, apoi săriți peste următorii 58 de octeți și pentru a citi valoarea magică pe 32 de biți la 60 biți în imagine (care este egal cu 0x00004550 pentru executabilele PE). Următorii octeți sunt acest antet , primele 2 bytes de care vă spun ce masina binar este proiectat pentru (0x8664 = X86_64, 0x0200 = IA64, 0x014c = i386).

(Rezumat: bytes citit 65 și 66 din dosar pentru a obține tipul de imagine)

Publicat 13/10/2008 la 16:34
sursa de către utilizator

voturi
1

Pot oferi un link către unele cod C # pentru accesarea IMAGE_FILE_HEADER, care cred că ar putea fi (ușor) compilate într - un cmdlet PowerShell. Sunt destul de sigur că nu se poate utiliza această metodă în script PowerShell direct, deoarece îi lipsesc indicii și capacitatea de PInvoke.

Cu toate acestea, ar trebui să fie în măsură să vă folosiți de cunoștințe acum extinse a PE format antet ;-) pentru a merge doar „direct“ la bytes dreapta și dau seama. Acest lucru va lucra în script - ul PowerShell, și ar trebui să fie capabil de a converti doar acest cod C # de la blog - ul Tasos' la script - ul. Nu voi deranja repetarea codul aici , deoarece nu este a mea.

Publicat 13/10/2008 la 17:37
sursa de către utilizator

voturi
21

(De la un alt Q, deoarece eliminat)

Tipul mașinii: Acesta este un pic rapid de cod am bazat pe unele care devine timestamp-ul de legătură. Acest lucru este în același antet, și se pare să funcționeze - returnează I386 atunci când sunt compilate CPU- -orice și x64 atunci când sunt compilate cu faptul că platforma ca țintă.

Exploring PE Cap (K. Stanton, MSDN) intrare de blog care mi-a arătat offset, ca un alt răspuns menționat.

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;
}
Publicat 20/05/2009 la 00:11
sursa de către utilizator

voturi
36

Dacă aveți Visual Studio instalat puteți utiliza dumpbin.exe. Există , de asemenea, Get-PEHeadercmdlet în Extensii PowerShell comunitare care pot fi utilizate pentru a testa pentru imagini executabile.

Dumpbin va raporta ca DLL - uri machine (x86)saumachine (x64)

Ia-PEHeader va raporta DLL - uri , fie PE32sauPE32+

Publicat 18/01/2011 la 02:04
sursa de către utilizator

voturi
0

Aici este propria mea punerea în aplicare a prezentului, care are mai multe mai multe controale în loc și întotdeauna returnează un rezultat.

// 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;
}

Cum să utilizați:

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

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

Pentru valorile ENUM folosite aici, au fost obținute de la pe.go . Motivul acestei lucrări este faptul că pentru fiecare binar de distribuție de „du - te“ , trebuie să aibă steagul corect în adunarea pentru a lăsa să treacă sistemele de operare „poți rula aici?“ Verifica. Din moment ce „merge“ este platforma transversală (toate platformele), aceasta este o bază bună pentru a obține aceste informații. Există , probabil , alte surse pentru aceste informații, dar ele par a fi imbricate genunchi în Google ca-ca necesita un al 10 - lea dan negru centura în Google-fu pentru a localiza.

Publicat 06/08/2016 la 16:58
sursa de către utilizator

voturi
1

Conform acestui postare , puteți verifica dacă un DLL sau EXE este de 32 sau 64 prin deschiderea acestuia cu bloc notes și caută „PE“ , la început, în cazul în care litera următoare este „L“ platforma este pe 32 de biți, este litera este „D“ este platforma pe 64 de biți.

Am încercat pe DLL-uri și mi se pare a fi corecte.

Publicat 05/03/2018 la 12:05
sursa de către utilizator

voturi
0

Aici este o punere în aplicare în C.

// 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;
}
Publicat 22/05/2018 la 15:50
sursa de către utilizator

voturi
0

dumpbin.exedisponibil sub bindirectorul de Visual Studio funcționează atât .libși.dll

 dumpbin.exe /headers *.dll |findstr machine
 dumpbin.exe /headers *.lib |findstr machine
Publicat 11/07/2018 la 05:55
sursa de către utilizator

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more