把exe裏面的資源通通取出來

一、前言
  不知大家用過exescope沒有,那是日本鬼子寫的一個很有用的東西,它能把exe等pe格式(portable executable)文件的資源(圖標、位圖、對話框、聲音等等)分析出來,並能改寫回去。當然vc的ide也有類似功能。大家是不是覺得很神祕?其實只要弄清了pe文件的結構,你也可以寫一個類似的工具出來。下面是我近 來對pe文件的分析經驗,給大家作參考。同時希望看到有中國人能寫出比日本鬼子更牛的分析工具來。

二、重要的數據結構
    PE格式簡要說明:(更詳細的資料見http://vcangle.8u8.com文件格式專頁)

PE文件總結構如下表:

DOS MZ header  ; dos頭
DOS stub            ; dos附加段
PE header          ; NT頭
Section table      ; 節表
Section 1            ; 第一節
Section 2            ;
Section ...
Section n            ;第n節

  其中NT頭:

typedef struct _IMAGE_NT_HEADERS {
      DWORD                                        Signature;               // PE文件頭標誌 :"PE\0\0"。
      IMAGE_FILE_HEADER                  FileHeader;             // PE文件物理分佈的信息
      IMAGE_OPTIONAL_HEADER32   OptionalHeader;      // PE文件邏輯分佈的信息
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

  節表數據結構:(可參考winnt.h)

typedef struct _IMAGE_SECTION_HEADER {
    BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];    // 節表名稱,如“.text”
    union {  DWORD   PhysicalAddress;       // 物理地址
                 DWORD   VirtualSize;               // 真實長度
    } Misc;

    DWORD    VirtualAddress;                  // RVA
    DWORD    SizeOfRawData;                // 物理長度
    DWORD    PointerToRawData;           // 節基於文件的偏移量
    DWORD    PointerToRelocations;       // 重定位的偏移
    DWORD    PointerToLinenumbers;     // 行號表的偏移
    WORD      NumberOfRelocations;       // 重定位項數目
    WORD      NumberOfLinenumbers;     // 行號表的數目
    DWORD   Characteristics;                  // 節屬性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

2.2位圖文件格式。由文件頭,位圖信息和數據段組成。
typedef struct tagBITMAPFILEHEADER {                       // bmfh文件頭
      WORD      bfType;               //"BM"
      DWORD   bfSize;
      WORD     bfReserved1;
      WORD     bfReserved2;
      DWORD   bfOffBits;
} BITMAPFILEHEADER;

typedef struct tagBITMAPINFO {                 // bmi----位圖信息
      BITMAPINFOHEADER   bmiHeader;     //  ----位圖信息頭
      RGBQUAD          bmiColors[1];            // ----調色板*
} BITMAPINFO;

typedef struct tagBITMAPINFOHEADER {      // bmih 位圖信息頭
      DWORD  biSize;                         // 該結構大小
      LONG   biWidth;
      LONG   biHeight;
      WORD   biPlanes;
      WORD   biBitCount;
      DWORD  biCompression;
      DWORD  biSizeImage;               // 位圖數據大小
      LONG   biXPelsPerMeter;
      LONG   biYPelsPerMeter;
      DWORD  biClrUsed;
      DWORD  biClrImportant;
} BITMAPINFOHEADER;                  // 該結構後緊接着就是DATA了。


三、取資源主要思路
先要判斷是否PE文件。文件頭兩byte應爲0x4d5a即("MZ"),然後到地址0x3c中讀出PE文件頭(_IMAGE_NT_HEADERS)。判斷文件頭結構的Signature是否爲17744(即"PE\0\0")。
  讀出節表(_IMAGE_SECTION_HEADER),判斷有沒有資源節。我採用了一個簡單的方法:節表名爲".rsrc\0\0"即是資源節。(注:據說該法不定可靠)
  如有資源節,則讀取資源目錄(_IMAGE_RESOURCE_DIRECTORY)和資源入口(_IMAGE_RESOURCE_DIRECTORY_ENTRY)。資源在pe文件中處一樹型結構中,可有三層。在資源目錄根部,如果資源入口的資源名是一個id,那麼它代表一種資源類型。否則,它指向下一層資源入口。(祥見例程)
  讀出具體資源的數據來。具體資源的入口(_IMAGE_RESOURCE_DATA_ENTRY)在就是資源樹的葉子。它的OffsetToData成員指明瞭具體資源的物理位置。不過特別要注意的是,OffsetToData並不是具體資源在文件中的實際偏移,具體見我的例程。具體資源的長度則由Size成員指定。
  導出bmp資源。pe文件裏的bmp資源由BITMAPINFO部分和BITMAPDATA部分組成。我們只要爲它構造一個文件頭(BITMAPFILEHEADER),就可以寫成bmp文件了。這裏特別要注意的是BITMAPINFO的bmiColors成員是未定長的。你要爲它指明長度,以申請內存。
好了,我不說了,有什麼不明白就看例程吧。


四、例子程序簡介
  我的例子程序基本實現了讀取pe文件的資源信息,並能把位圖顯示、導出。其它資源的操作還在研究中。由於作者水平有限,在分析有些文件時可能會不成功。歡迎指正!主頁: http://vcangle.8u8.com,郵箱:[email protected]
五、參考資料
http://www.csdn.net/dev/Format/
http://mantousoft.51.net

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章