一、前言
不知大家用過exescope沒有,那是日本鬼子寫的乙個很有用的東西,它能把exe等pe格式(portable executable)檔案的資源(圖示、位圖、對話方塊、聲音等等)分析出來,並能改寫回去。當然vc的ide也有類似功能。大家是不是覺得很神秘?其實只要弄清了pe檔案的結構,你也可以寫乙個類似的工具出來。下面是我近 來對pe檔案的分析經驗,給大家作參考。同時希望看到有中國人能寫出比日本鬼子更牛的分析工具來。
二、重要的資料結構
pe格式簡要說明:(更詳細的資料見檔案格式專頁)
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 image_nt_headers32, *pimage_nt_headers32;
節表資料結構:(可參考winnt.h)
typedef struct _image_section_header 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 bitmapfileheader;
typedef struct tagbitmapinfo bitmapinfo;
typedef struct tagbitmapinfoheader 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成員是未定長的。你要為它
指明長度,以申請記憶體。
好了,我不說了,有什麼不明白就看例程吧。
五、參考資料
怎麼把PDF中的文字提取出來
pdf文件大家也都見過,這種格式的文件編輯起來不像word文件那樣方便。在使用裡面的內容的時候也比較繁瑣。若要提取裡面的一些文字內容,一般都會想到複製,但是一次只能複製少量的文字內容,而且複製到word或者txt文件中後排版可能會亂。那有什麼高效的方法呢。首先是我們用來開啟檢視pdf檔案都會用到的a...
在oracle裡面為讀取出來的資料新增乙個序號
在oracle裡面為讀取出來的資料新增乙個序號 我們在給客戶演示報表的時候,有時候客戶會提出在報表的第一列,能不能新增乙個序號 www.2cto.com 但是如果通過修改程式 的方式來做,是可以實現,不過做起來會比較麻煩,有個比較實用的方式可以解決,那就是通過oracle裡面的rownum,函式來取...
從VC工程的rc資源中將資源檔案取出來或讀出來
對於rc資源中常見的型別 bitmap cursor和icon,可以用loadbitmap loadcursor和loadicon將它們載入到記憶體中,或者統一使用loadimage api函式也可以。但是對於自定義型別的png zip 在新增檔案到資源中時會提示設定資源型別 則沒有專門的函式來使用...