Windows PE 第十章 加载配置信息
加載配置信息
? ? 加載配置信息最初最用在Windows?NT操作系統中,作為文件頭部的延伸部分,后來被用作異常處理。加載配置信息表中存放了基于結構化異常處理(SEH)技術的各項異常句柄。當程序運行發生異常后,操作系統會根據異常處理類別對異常進行分發處理,并依據這些句柄實施程序流程的轉向,保證系統能從異常中全身而退。
10.1?何為加載配置信息
? ? 加載配置信息結構是PE中定義的一種基本數據類型,最初僅用于Windows?NT操作系統,定義一些供Windows?NT操作系統加載PE時用到的一些附加信息。后來該部分含義發生了變化。不再定義加載用的配置信息,而是被專門用來定義基于SEH技術的相關數據。
????如果PE中的該部分表中沒有對應的異常類別處理函數句柄,操作系統將會調用其內核模式的異常分發函數終止應用程序的運行。這種安全設置主要是為了阻止因異常句柄導致的溢出被惡意程序利用,從而造成對系統的破壞。
通常情況下,連接器會提供一個默認的加載配置信息結構,該結構包含了預留的SEH數據。如果用戶代碼中提供了該結構,則必須由用戶來完成設置新的預留SEH字段,否則連接器不會講SEH數據加入到加載配置信息中。
10.2??Windows?結構化異常處理
? ? 就是說SEH的原理和調用,之前寫核心編程筆記的時候整理過:
http://blog.csdn.net/u013761036/article/details/54234212?這里只說當時沒有整理的部分。
Windows?異常分類
? ? 由于SEH使用了與硬件平臺如果的數據指針,所以在不同的硬件平臺上,SEH的實現方法是不同的。在X86平臺上的SEH處理框架中,把異常分為兩大類:
硬異常(系統異常)和軟異常(程序自己拋出的異常)
1.硬異常,即系統異常,可以細分為三類:
(1)故障異常:因執行指令失敗引起,比如除以0引發的異常,一起eip指向了不可執行的頁面等。這一類異常是系統異常中最常見的。此類異常有一個共同點,那就是發生異常時自動壓入棧的是失敗指令的地址,而不是它的嚇一跳指令地址,這樣做的原因是:當從異常遍歷過程返回時,可以重新執行一遍這條指令。
(2)陷阱異常:發生這類異常通常是因為執行了自陷指令,如使用指令”INT?3”而引發的異常。這一類異常的返回地址是自陷指令的下一條指令所在的地址。
(3)終止異常:硬件或者其他不可恢復的因素導致的異常等。通常只能重啟。
2.軟異常,所謂軟異常,就是以函數調用的手段累模擬一次異常,即通過Windows提供的API函數RaiseException,執行函數引發軟異常,實際上,在高級語言的異常處理模型中的大部分拋出異常的操作,最終都是對RaiseException函數的調用。
然后就是各種對SEH的使用啥的,之前總結過就不說了。但是在書上看到了一個概念區分,就是區分?中斷和異常,異常可以理解成是程序內部的自發行為,中斷則是外部導致的被動行為,所以我個人對?缺頁中斷的這個詞的理解是,缺頁異常導致的中斷。
10.3?PE中的加載配置信息
? ? 這本書講的是PE結構,自然這個才是他要說的重點,分析一個EXE的結構:
通過PE數據目錄表定位到加載配置信息;然后,分析該部分數據對應的數據結構;最后,通過一個實例分析,描述了數據結構中每個字段與提取的字節碼之間一一對應的關系。
10.3.1?加載配置信息定位
? ? 加載配置數據為數據目錄注冊的數據類型之一,其描述信息處于數據目錄第11個目錄項中。
? ? 為了避免SEH框架緩沖區溢出執行用戶代碼導致安全隱患,自XP系統以后的大部分系統中PE文件,如常見的記事本程序、kernel32.dll、user32.dll等都附加了加載配置信息。通常情況下,操作系統的加載器會根據數據目錄表中定義的大小,來判斷加載配置信息的類別。為了保持對Windows?XP操作系統和以前的操作系統的兼容,通常此處的大小為64字節,即0x40。
10.3.2??加載配置信息目錄IMAGE_LOAD_CONFIG_DIRECTORY
看下頭文件里的定義:
10.3.3?加載配置信息實例分析
? ? 書上是直接分析的例子的一個文件,我這里沒有,我就自己隨便找一個文件分析吧,得到的數據不一樣,但是思路和結構一樣。
隨便找一個平時的測試項目,注釋了些代碼:
OK先從PE頭開始
得到兩個東西,配置表地址RVA是0xF2C8,大小0x40。
然后計算FOA:
FOA=0xDCC8
然后直接看二進制信息:
? ? 得到這一步的時候我有點困惑,什么情況,大小是40的話定位到上面的黑色區域應該是啊,不過這數據也不科學啊,然后我以為是因為我自己沒寫SEH導致的,然后我就改了下代碼:
同樣的方式進行操作發現得到這個:
還是不對,然后就又看了下這個定義:
18*4=72=0x48??額...這也不是0x40啊!,但是
額...先不管這些,繼續往下走。從這個繼續走吧:
從最后safehandle地址是0x40F6E0(注意這個是VA)?個數是7。
按照這個:
那RVA應該是F6E0了,然后計算FOA.
到E0E0處找到這7個數據:
這七個數據是RVA,對應轉換成VA然后在內存里直接看這些數據:
得到的是類似這樣的東西,把這些機器碼翻譯成匯編然后再翻譯成c的話對應的是7個異常處理回調函數的代碼,注意和我上面寫的那個__try..沒關系。
然后我又嘗試注冊了一個SetUnhandledExceptionFilter(ExceptionFilter);??還是不行,難道是那個在__except里劫持異常類型的那個毀掉函數?這個之后在測試吧。今天沒時間了。
下一章是講動態加載,下一章不單獨總結了,沒什么新東西。
唯一設計到一個新東西就是?硬編碼加載,其實就是直接通過偏移量加載?其他函數,也可以加載內部未導出的函數,這個在這里又更充分的總結:http://blog.csdn.net/u013761036/article/details/53933350里面我寫了一個?把DLL私有函數導出的思路。里面有這方面相關。So下一章就直接跳過了,下次整理就直接整理PE變形那一章。
總結
以上是生活随笔為你收集整理的Windows PE 第十章 加载配置信息的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Windows PE第九章 线程局部存储
- 下一篇: 1.简单认识PHP和环境搭建