一、前言 |
不知大家用過exescope沒有,那是日本鬼子寫的一個很有用的東西,它能把exe等pe格式(portable executable)文件的資源(圖標、位圖、對話框、聲音等等)分析出來,并能改寫回去。當然vc的ide也有類似功能。大家是不是覺得很神秘?其實只要弄清了pe文件的結構,你也可以寫一個類似的工具出來。下面是我近 來對pe文件的分析經(jīng)驗,給大家作參考。同時希望看到有中國人能寫出比日本鬼子更牛的分析工具來。 |
二、重要的數(shù)據(jù)結構 |
PE格式簡要說明:(更詳細的資料見http://vcangle.文件格式專頁)
PE文件總結構如下表: |
01. 02. DOS MZ header ;dos頭 03. DOS stub ;dos附加段 04. PE header ;NT頭 05. Section table ;節(jié)表 06. Section 1 ;第一節(jié) 07. Section 2 ; 08. Section ... 09. Section n ;第n節(jié) 10. 其中NT頭: 11. typedef struct _IMAGE_NT_HEADERS { 12. DWORD Signature; //PE文件頭標志 :"PE\0\0"。 13. IMAGE_FILE_HEADER FileHeader; //PE文件物理分布的信息 14. IMAGE_OPTIONAL_HEADER32 OptionalHeader; //PE文件邏輯分布的信息 15. } IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32; 16. 節(jié)表數(shù)據(jù)結構:(可參考winnt.h) 17. typedef struct _IMAGE_SECTION_HEADER { 18. BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; //節(jié)表名稱,如“.text” 19. union { DWORD PhysicalAddress; //物理地址 20. DWORD VirtualSize; //真實長度 21. } Misc; 22. DWORD VirtualAddress; //RVA 23. DWORD SizeOfRawData; //物理長度 24. DWORD PointerToRawData; //節(jié)基于文件的偏移量 25. DWORD PointerToRelocations; //重定位的偏移 26. DWORD PointerToLinenumbers; //行號表的偏移 27. WORD NumberOfRelocations; //重定位項數(shù)目 28. WORD NumberOfLinenumbers; //行號表的數(shù)目 29. DWORD Characteristics; //節(jié)屬性 30. } IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER; 31. 32. 2.2位圖文件格式。由文件頭,位圖信息和數(shù)據(jù)段組成。 33. typedef struct tagBITMAPFILEHEADER { // bmfh文件頭 34. WORD bfType; //"BM" 35. DWORD bfSize; 36. WORD bfReserved1; 37. WORD bfReserved2; 38. DWORD bfOffBits; 39. } BITMAPFILEHEADER; 40. typedef struct tagBITMAPINFO { // bmi----位圖信息 41. BITMAPINFOHEADER bmiHeader; // ----位圖信息頭 42. RGBQUAD bmiColors[1]; // ----調(diào)色板* 43. } BITMAPINFO; 44. typedef struct tagBITMAPINFOHEADER{ // bmih 位圖信息頭 45. DWORD biSize; //該結構大小 46. LONG biWidth; 47. LONG biHeight; 48. WORD biPlanes; 49. WORD biBitCount; 50. DWORD biCompression; 51. DWORD biSizeImage; //位圖數(shù)據(jù)大小 52. LONG biXPelsPerMeter; 53. LONG biYPelsPerMeter; 54. DWORD biClrUsed; 55. DWORD biClrImportant; 56. } BITMAPINFOHEADER; //該結構后緊接著就是DATA了。 三、取資源主要思路 先要判斷是否PE文件。文件頭兩byte應為0x4d5a即("MZ"),然后到地址0x3c中讀出PE文件頭(_IMAGE_NT_HEADERS)。判斷文件頭結構的Signature是否為17744(即"PE\0\0")。 讀出節(jié)表(_IMAGE_SECTION_HEADER),判斷有沒有資源節(jié)。我采用了一個簡單的方法:節(jié)表名為".rsrc\0\0"即是資源節(jié)。(注:據(jù)說該法不定可靠) 如有資源節(jié),則讀取資源目錄(_IMAGE_RESOURCE_DIRECTORY)和資源入口(_IMAGE_RESOURCE_DIRECTORY_ENTRY)。資源在pe文件中處一樹型結構中,可有三層。在資源目錄根部,如果資源入口的資源名是一個id,那么它代表一種資源類型。否則,它指向下一層資源入口。(祥見例程) 讀出具體資源的數(shù)據(jù)來。具體資源的入口(_IMAGE_RESOURCE_DATA_ENTRY)在就是資源樹的葉子。它的OffsetToData成員指明了具體資源的物理位置。不過特別要注意的是,OffsetToData并不是具體資源在文件中的實際偏移,具體見我的例程。具體資源的長度則由Size成員指定。 導出bmp資源。pe文件里的bmp資源由BITMAPINFO部分和BITMAPDATA部分組成。我們只要為它構造一個文件頭(BITMAPFILEHEADER),就可以寫成bmp文件了。這里特別要注意的是BITMAPINFO的bmiColors成員是未定長的。你要為它 好了,我不說了,有什么不明白就看例程吧。 |
四、例子程序簡介
我的例子程序基本實現(xiàn)了讀取pe文件的資源信息,并能把位圖顯示、導出。其它資源的操作還在研究中。由于作者水平有限,在分析有些文件時可能會不成功。歡迎指正!主頁: http://vcangle.,郵箱:king_koo@163.net. |
五、參考資料 http://www.csdn.net/dev/Format/ http://mantousoft. |
|