2012-05-25 21 views
2

是否可以在運行前檢查二進制文件的位數(EXE)?這可以很容易地在Linux上完成,但我不熟悉Windows二進制格式。檢查Windows上的應用程序二進制位(C/C++)

謝謝。

+0

是的,這是可能的。我不確定這些信息是否直接存儲在PE頭中,但它肯定存儲在EXE,DLL等文件中。 – Wormbo

+0

你知道如何檢索它嗎?是否有某種類型的API?我似乎無法找到任何Windows二進制格式的文檔... – user1416562

+0

[如何檢測給定的PE文件(exe或dll)是64位還是32位]可能的重複(http://stackoverflow.com/questions/1153090 /如何對檢測 - 即-A-給定-PE-文件EXE-或-DLL-IS-64位或32位) – shf301

回答

1

既然你給這個問題加了標籤C,有一個Win32 API函數GetBinaryType。但它不適用於DLL。

if (GetBinaryType(argv[i], &bintype)) { 
    switch(bintype) { 
    case SCS_32BIT_BINARY: typename = TEXT("Windows 32 Bit"); break; 
    case SCS_64BIT_BINARY: typename = TEXT("Windows 64 Bit"); break; 
    case SCS_DOS_BINARY: typename = TEXT("DOS-Programm"); break; 
    case SCS_OS216_BINARY: typename = TEXT("OS/2-Programm"); break; 
    case SCS_PIF_BINARY: typename = TEXT("PIF-Datei");  break; 
    case SCS_POSIX_BINARY: typename = TEXT("POSIX-Programm"); break; 
    case SCS_WOW_BINARY: typename = TEXT("Windows 16 Bit"); break; 
    default:    typename = TEXT("unknown");  break; 
    } 
} 
else { 
    typename = TEXT("not executable"); 
} 
0

看看答案here 它說,這些信息都可以通過使用dumpbin /headers從被得到Windows平臺SDK

0

有許多工具可以幫助你發現的應用程序(如WinDbg的或PeStudio)的位數。

enter image description here

0

讀頭:

IMAGE_FILE_HEADER structure

作爲開始,你可以做這樣的事情,(應該工作的DLL和EXE):
(僅在幾檔測試 - 那些給出的結果)

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

/* Runtime Byteorder detection - Motorola or Intel (Does not catch mixed) */ 
static int byteorder_mm(void) 
{ 
    union {double d; unsigned int i[2];} u; 

    u.d = 1.0; 

    return (u.i[0] != 0); 
} 

/* Char to unsigned int */ 
static unsigned int chr_to_ui(unsigned char *buf, int mm) 
{ 
    if (mm) 
     return buf[0] << 24 | buf[1] << 16 | buf[2] << 8 | buf[3]; 
    return buf[3] << 24 | buf[2] << 16 | buf[1] << 8 | buf[0]; 

} 

/* Char to unsigned short */ 
static unsigned short chr_to_us(unsigned char *buf, int mm) 
{ 
    if (mm) 
     return buf[0] << 8 | buf[1]; 
    return buf[1] << 8 | buf[0]; 
} 

int main(int argc, char *argv[]) 
{ 
    FILE *fh; 
    unsigned char buf[128] = {0}; 
    char tmpstr[64]; 
    unsigned int tmp_ui; 
    unsigned short tmp_us; 

    time_t tt; 

    int mm = byteorder_mm(); 

    if (argc < 2) { 
     fprintf(stderr, 
      "Missing input file.\n"); 
     return 1; 
    } 

    if ((fh = fopen(argv[1], "rb")) == NULL) { 
     fprintf(stderr, 
      "Unable to open %s.\n", 
      argv[1]); 
     perror(0); 
     return 1; 
    } 

    /* Read MS-DOS Segment */ 
    if (!fread(buf, 64, 1, fh)) { 
     fprintf(stderr, 
      "Unable to read %d bytes, @%ld.\n", 
      2, ftell(fh)); 
     perror(0); 
     fclose(fh); 
     return 1; 
    } 

    /* Check header mark : MZ */ 
    if (buf[0] != 0x4d || buf[1] != 0x5a) { 
     fprintf(stderr, 
      "%s is missing Mark Zbikowski header.\n", 
      argv[1]); 
     fclose(fh); 
     return 2; 
    } 

    /* Get offset (from 0) to IMAGE_NT_HEADERS */ 
    tmp_ui = chr_to_ui(buf+60, mm); 

    fseek(fh, tmp_ui - 64, SEEK_CUR); 

    /* Read IMAGE_NT_HEADER signature */ 
    if (!fread(buf, 4, 1, fh)) { 
     fprintf(stderr, 
      "Unable to read %d bytes, @%ld.\n", 
      4, ftell(fh)); 
     perror(0); 
     fclose(fh); 
     return 1; 
    } 

    /* Check signature : PE'x0'x0 */ 
    if (buf[0] != 0x50 || buf[1] != 0x45 || 
     buf[2] != 0x00 || buf[3] != 0x00) { 
     fprintf(stderr, 
      "%s is missing valid Portable Executable signature.\n", 
      argv[1]); 
     fclose(fh); 
     return 2; 
    } 


    /* Read IMAGE_FILE_HEADER: 
    typedef struct _IMAGE_FILE_HEADER { 
     WORD Machine; 
     WORD NumberOfSections; 
     DWORD TimeDateStamp; 
     DWORD PointerToSymbolTable; 
     DWORD NumberOfSymbols; 
     WORD SizeOfOptionalHeader; 
     WORD Characteristics; 
    } IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER; 
    */ 
    if (!fread(buf, 20, 1, fh)) { 
     fprintf(stderr, 
      "Unable to read %d bytes, @%ld.\n", 
      4, ftell(fh)); 
     perror(0); 
     fclose(fh); 
     return 1; 
    } 

    /* Bittype */ 
    tmp_us = chr_to_us(buf, mm); 

    switch (tmp_us) { 
    case 0x014c: fprintf(stdout, "Machine: x86 (I386)\n"); break; 
    case 0x0200: fprintf(stdout, "Machine: IA64 (Intel Itanium)\n"); break; 
    case 0x8664: fprintf(stdout, "Machine: x64 (AMD64)\n"); break; 
    default: fprintf(stderr, 
      "Unable to recognize machine type 0x%04x\n", 
      tmp_us); 
     fclose(fh); 
     return 2; 
    } 

    /* Timestamp */ 
    tmp_ui = chr_to_ui(buf+4, mm); 

    tt = tmp_ui; 
    strftime(tmpstr, 31, "%a %Y-%m-%d %H:%M:%S", localtime(&tt)); 
    fprintf(stdout, 
     "Time : %s (%d)\n", 
     tmpstr, tmp_ui); 

    /* ... */ 

    fclose(fh); 
    return 0; 
} 
相關問題