PE文件结构(五岁以下儿童)基地搬迁
PE文件結構(五歲以下兒童)
參考
書:《加密與解密》
視頻:小甲魚 解密系列 視頻
基址重定位
??????? 鏈接器生成一個PE文件時,它會如果程序被裝入時使用的默認ImageBase基地址(VC默認exe基地址00400000h。dll基地址10000000h),而且會把代碼中全部指令中用到的地址都使用默認的基地址(比如 程序代碼中 push 10001000,就是把10000000h當做了基地址,把push 10001000寫入到文件里)。如果一個exe程序中一個dll裝載時的地址與其他dll地址發生沖突(由于windows程序是虛擬地址空間,exe一般不會有地址沖突,載入dll時可能會有地址沖突),就須要改動代碼中的地址,如push 10001000。call 10002000等。
這時就須要用進行基址重定位。而基址重定位表中存放了,假設默認地址被改。須要改動的代碼的地址。在PE文件里。基址重定位表一般放在一個單獨的 ".reloc" 區。能夠通過IMAGE_OPTIONAL_HEADER 中 的DataDirectory[5] 查看?基址重定位表 的RVA。
比如:
??????? 用W32Dasm 查看 Demo.dll? (下載地址:http://pan.baidu.com/s/1qWDepo4)
圖片1
??????? 能夠發現MyMessageBox 這個函數,看看它的代碼中的push 10006040 。 push 10006030 中的地址是指向字符串的。
假設一個程序在載入Demo.dll時由于Demo.dll 默認的地址被占用了。而使用其他的基地址,比如使用20000000h作為基地址,Demo.dll就從20000000h開始裝載。這樣字符串“Demo”和“Hello World!” 就不是在10006040h跟10006030h中了,這時就須要把push 10006040 。 push 10006030改成push 20006040 , push 20006030 。
??????? 基址重定位表是由一個一個IMAGE_BASE_RELOCATION結構? 構成的。
圖片2
IMAGE_BASE_RELOCATION 結構:
typedef struct _IMAGE_BASE_RELOCATION {DWORD VirtualAddress;DWORD SizeOfBlock; // WORD TypeOffset[]; } IMAGE_BASE_RELOCATION; typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;
??????? 當中 VirtualAddress? 表示 這一組地址的起始RVA。
SizeOfBlock表示當前這個IMAGE_BASE_RELOCATION 結構的大小。TypeOffset是一個數組,它的元素個數就是( SizeOfBlock - 8 ) / 2 ,TypeOffset 每個元素占用兩個字節即16位。當中高4位表示重定位類型(一般都為3)。低12位表示重定位地址。
實例分析:
??????? 查看Demo.dll的第一個 IMAGE_BASE_RELOCATION 結構
圖片3
能夠發現:
VirtualAddress? 為1000h
SizeOfBlock????? 為 0164h
TypeOffset[0]?? 0333h? 即 3是重定位類型? 33h為重定位地址
TypeOffset[1]?? 0338h
TypeOffset[2]?? 0340h
???? ........
通過Type低12位+VirtualAddress 能夠知道前三個的地址為1033h,1038h。1040h 。
再來看看圖片1中Demo.dll的代碼,能夠發現1033h就是圖片1中的push 10006040中的10006040,1038h就是push 10006030中的10006030 。
??? 假設載入dll,發現不是使用默認的基地址,PE載入器就會把基址重定位表中所寫的地址的值改掉。
改掉方法是把原先的值加上 實際基地址 - 默認基地址 的值。
版權聲明:本文博客原創文章,博客,未經同意,不得轉載。
總結
以上是生活随笔為你收集整理的PE文件结构(五岁以下儿童)基地搬迁的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在js中使用createElement创
- 下一篇: 组件名简单改了