如何才能校驗指定檔案是否為一有效
pe檔案呢
? 這個問題很難回答,完全取決於想要的精準程度。您可以檢驗
pe檔案格式裡的各個資料結構,或者僅校驗一些關鍵資料結構。大多數情況下,沒有必要校驗檔案裡的每乙個資料結構,只要一些關鍵資料結構有效,我們就認為是有效的
pe檔案了。下面我們就來實現前面的假設。
我們要驗證的重要資料結構就是
pe header
。從程式設計角度看,
pe header
實際就是乙個
image_nt_headers
結構。定義如下
:image_nt_headers struct signature dd ? fileheader image_file_header <> optionalheader image_optional_header32 <> image_nt_headers ends
signature
一dword
型別,值為
50h, 45h, 00h, 00h
(pe/0/0
)。本域為
pe標記,我們可以此識別給定檔案是否為有效
pe檔案。
fileheader該結構域包含了關於
pe檔案物理分布的資訊,
比如節數目、檔案執行機器等。
optionalheader
該結構域包含了關於
pe檔案邏輯分布的資訊,雖然網域名稱有"可選
"字樣,但實際上本結構總是存在的。
我們目的很明確。如果
image_nt_headers的
signature
域值等於
"pe/0/0"
,那麼就是有效的
pe檔案。實際上,為了比較方便,
microsoft
已定義了常量
image_nt_signature供我們使用。
image_dos_signature equ 5a4dhimage_os2_signature equ 454eh image_os2_signature_le equ 454ch image_vxd_signature equ 454ch
image_nt_signature equ 4550h
接下來的問題是
: 如何定位
pe header?
答案很簡單
: dos mz header
已經包含了指向
pe header
的檔案偏移量。
dos mz header
又定義成結構
image_dos_header
。查詢windows.inc
,我們知道
image_dos_header
結構的e_lfanew成員就是指向
pe header
的檔案偏移量。
現在將所有步驟總結如下
:首先檢驗檔案頭部第乙個字的值是否等於
image_dos_signature,是則
dos mz header
有效。一旦證明檔案的
dos header
有效後,就可用
e_lfanew
來定位
pe header
了。比較
pe header
的第乙個字的值是否等於
image_nt_header。如果前後兩個值都匹配,那我們就認為該檔案是乙個有效的
pe檔案。
本例程開啟一檔案,先檢驗
dos header
是否有效,有效就接著檢驗
pe header
的有效性,
ok就認為是有效的
pe檔案了。這裡,我們還運用了結構異常處理
(seh)
,這樣就不必檢查每個可能的錯誤
: 如果有錯誤出現,就認為
pe檢測失效所致,於是給出我們的報錯資訊。其實
windows
內部普遍使用
seh來檢驗引數傳遞的有效性。若對
seh感興趣的話,可閱讀
jeremy gordon的文章
。 程式呼叫開啟檔案通用對話方塊,使用者選定執行檔案後,程式便開啟檔案並對映到記憶體。並在有效性檢驗前建立一
seh:
assume fs:nothing push fs:[0] pop seh.prevlink mov seh.currenthandler,offset sehhandler mov seh.safeoffset,offset finalexit lea eax,seh mov fs:[0], eax mov seh.prevesp,esp mov seh.prevebp,ebp
一開始就假設暫存器
fs為空(
assume fs:nothing
)。記住這一步不能省卻,因為
ma**
假設fs
暫存器為
error
。接下來儲存
windows
使用的舊
seh處理函式位址到我們自己定義的結構中,同時儲存我們的
seh處理函式位址和異常處理時的執行恢復位址,這樣一旦錯誤發生就能由異常處理函式安全地恢復執行了。同時還儲存當前
esp及
ebp的值,以便我們的
seh處理函式將堆疊恢復到正常狀態。
成功建立
seh後繼續校驗工作。置目標檔案的首位元組位址給
edi,使其指向
dos header
的首位元組。為便於比較,我們告訴編譯器可以假定
edi正指向
image_dos_header結構
(事實亦是如此
)。然後比較
dos header
的首字是否等於字串
"mz"
,這裡利用了
windows.inc
中定義的
image_dos_signature常量。若比較成功,繼續轉到
pe header
,否則設
validpe
值為false
,意味著檔案不是有效
pe檔案。
add edi, [edi].e_lfanew assume edi:ptr image_nt_headers .if [edi].signature==image_nt_signature mov validpe, true .else mov validpe, false .endif
要定位到
pe header
,需要讀取
dos header
中的e_lfanew域值。該域含有
pe header
在檔案中相對檔案首部的偏移量。
edi加上該值正好定位到
pe header
的首位元組。這兒可能會出錯,如果檔案不是
pe檔案,
e_lfanew
值就不正確,加上該值作為指標就可能導致異常。若不用
seh,我們必須校驗
e_lfanew值是否超出檔案尺寸,這不是乙個好辦法。如果一切
ok,我們就比較
pe header
的首字是否是字串
"pe"
。這裡在此用到了常量
image_nt_signature,相等則認為是有效的
pe檔案。
如果e_lfanew的值不正確導致異常,我們的
seh處理函式就得到執行控制權,簡單恢復堆疊指標和基棧指標後,就根據
safeoffset
的值恢復執行到
finalexit
標籤處。
上述**簡單明確,根據
validpe
的值顯示相應資訊。
push seh.prevlink pop fs:[0] 一旦
seh不再使用,必須從
seh鏈上斷開。
檢測PE檔案的有效性
2008年01月14日 星期一 13 41 本文刊登於2007年第8期的 黑客防線 有內容部分改動。正文如下 從防毒軟體的角度來講檢測檔案是否為pe檔案,並再進一步判斷使用何種方式對檔案進行操作。在病毒感染可執行檔案時,也是應該有這樣步驟的。那麼,就來看看防毒軟體是如何檢測pe檔案的有效性了。pe檔...
PE檔案的有效性判斷
pe 檔案格式被組織為乙個線性的資料流。開始的是 ms dos 頭,然後是實模式的程式根,再就是 pe檔案簽名,緊隨其後的便是 pe檔案頭和可選頭。在這之後,出現的是所有的節頭,再跟著的就是所有節的節身。檔案常以一些其它方面的雜項資訊,包括重定位資訊 符號表資訊 行數資訊以及字串表資料等作為結尾。所...
PE檔案的裝載過程(2)
image nt headers struct signature dword pe檔案標識 fileheader image file header optionalheader image optional header32 image nt headers ends signature為pe檔...