windows - Win32 API for at fortælle om en given binær (EXE eller DLL) er x86, x64 eller ia64

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg forsøger at finde en programmatisk måde at fortælle om et binært er x86, x64 eller ia64.


Platform: Windows.
Sprog: c/c ++.


Baggrund: Før jeg forsøger at indlæse en tredjeparts dll, skal jeg finde ud af dens vidnesbyrd.


Værdsætter nogle pointers.

Bedste reference


For EXE'er



brug GetBinaryType (...) [4]


Her er det samme spørgsmål for manged exe.


For DLL'er (og EXE'er)



Brug ImageNtHeader (...) for at hente PE data af filen og derefter tjekke IMAGE\_FILE\_HEADER.Machine feltet. [6]


Her er en kode, jeg fandt ved hjælp af Google Code Search [7]


Ingen oprydning og ingen fejl kontrol


// map the file to our address space
// first, create a file mapping object
hMap = CreateFileMapping( 
  hFile, 
  NULL,           // security attrs
  PAGE\_READONLY,  // protection flags
  0,              // max size - high DWORD
  0,              // max size - low DWORD      
  NULL );         // mapping name - not used

// next, map the file to our address space
void* mapAddr = MapViewOfFileEx( 
  hMap,             // mapping object
  FILE\_MAP\_READ,  // desired access
  0,              // loc to map - hi DWORD
  0,              // loc to map - lo DWORD
  0,              // #bytes to map - 0=all
  NULL );         // suggested map addr

peHdr = ImageNtHeader( mapAddr );

Andre referencer 1


Jeg har åbnet et projekt på Github, der kontrollerer specifikt VC + + -fordelbare DLL'er, og der er 'en kodestykke, jeg oprettede baseret på funktionen i Shays svar, der med succes finder, laster og inspicerer DLL'er til x86/x64-kompatibilitet. [8] [9]


Fuld kodestykke nedenfor:


/******************************************************************
Function Name:  CheckProductUsingCurrentDirectory
Description:    Queries the current working directory for a given binary.
Inputs:         pszProductFolderToCheck - the product name to look up.
pBinaryArchitecture - the desired processor architecture
of the binary (x86, x64, etc..).
Results:        true if the requested product is installed
false otherwise
******************************************************************/
bool CheckProductUsingCurrentDirectory(const LPCTSTR pszProductBinaryToCheck, Architecture pBinaryArchitecture){
        bool bFoundRequestedProduct = false;

        //Get the length of the buffer first
        TCHAR currentDirectory[MAX\_PATH];
        DWORD currentDirectoryChars = GetCurrentDirectory(MAX\_PATH, currentDirectory);

        //exit if couldn't get current directory
        if (currentDirectoryChars <= 0) return bFoundRequestedProduct;

        TCHAR searchPath[MAX\_PATH];
        //exit if we couldn't combine the path to the requested binary
        if (PathCombine(searchPath, currentDirectory, pszProductBinaryToCheck) == NULL) return bFoundRequestedProduct;

        WIN32\_FIND\_DATA FindFileData;
        HANDLE hFind= FindFirstFile(searchPath, &FindFileData);

        //exit if the binary was not found
        if (hFind == INVALID\_HANDLE\_VALUE) return bFoundRequestedProduct;

        HANDLE hFile = CreateFile(searchPath, GENERIC\_READ, FILE\_SHARE\_READ, NULL, OPEN\_EXISTING, FILE\_ATTRIBUTE\_READONLY, NULL);
        if (hFile == INVALID\_HANDLE\_VALUE) goto cleanup;

        HANDLE hMapping = CreateFileMapping(hFile, NULL, PAGE\_READONLY | SEC\_IMAGE, 0, 0, pszProductBinaryToCheck);
        if (hMapping == INVALID\_HANDLE\_VALUE) goto cleanup;

        LPVOID addrHeader = MapViewOfFile(hMapping, FILE\_MAP\_READ, 0, 0, 0);
        if (addrHeader == NULL) goto cleanup; //couldn't memory map the file

        PIMAGE\_NT\_HEADERS peHdr = ImageNtHeader(addrHeader);
        if (peHdr == NULL) goto cleanup; //couldn't read the header

        //Found the binary, AND its architecture matches. Success!
        if (peHdr->FileHeader.Machine == pBinaryArchitecture){
                bFoundRequestedProduct = true;
        }

cleanup: //release all of our handles
        FindClose(hFind);
        if (hFile != INVALID\_HANDLE\_VALUE)
                CloseHandle(hFile);
        if (hMapping != INVALID\_HANDLE\_VALUE)
                CloseHandle(hMapping);
        return bFoundRequestedProduct;
}


Dette spørgsmål og Shays svar var nyttige for mig, mens jeg skabte dette, så jeg troede, at jeg ville skrive projektet her.

Andre referencer 2


Du kan selv kontrollere PE-overskriften for at læse feltet IMAGE\_FILE\_MACHINE. Her er en C # implementering, der ikke bør være for svært at tilpasse sig til C ++.