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