PE重定位
向進程的虛擬內(nèi)存加載PE文件時鲜漩,文件會被加載到PE頭的ImageBase所指向的地址處,若IB位置已經(jīng)加載了其他文件腋寨,PE裝載器就會將其加載到去其他未被占用的空間顽耳,這就涉及到PE地址重定位的問題亥揖。
創(chuàng)建好進程之后,EXE文件會首先加載到內(nèi)存杈湾,因此在EXE文件無需考慮地址重定位問題
ASLR安全機制:每次運行時EXE文件都會被加載到隨機地址解虱。
此機制也適用于DLL/SYS文件,對于個OS的主要系統(tǒng)DLL漆撞,微軟會根據(jù)不同版本分別賦予不同的IB地址殴泰。同意系統(tǒng)的kernel32.dll于宙、user32.dll等會被加載到自身固有的IB,所以系統(tǒng)的DLL實際上并不會發(fā)生重定位問題悍汛。
PE重定位操作原理
- 在應用程序中查找硬編碼的地址位置
- 讀取值后捞魁,減去ImageBase(VA->RVA)(原本這些值是以IB為基準的硬編碼值)
- 加上實際加載的地址(RVA->VA)
基址重定位表
基址重定位表的地址位于PE頭的Datadirectory數(shù)組的第六個元素
基址重定位表是一個IMAGE_BASE_RELOCATION結構體數(shù)組
IMAGE_BASE_RELOCATION
成員:
- VirtualAddress: 這是一個基準地址,實際上是RVA值
- SizeOfBlock:指重定位塊的大小
- TypeOffset:不是結構體成員离咐,以注釋方式存在谱俭,表示在該結構體之下會出現(xiàn)WORD類型的數(shù)組,并且該數(shù)組的值就是硬編碼在程序中的地址偏移
基址重定位表的分析方法
例:
RVA | 數(shù)據(jù) | 注釋 |
---|---|---|
0002F000 | 00001000 | VirtualAddress |
0002F004 | 00000150 | SizeOfBlock |
0002F008 | 3420 | TypeOffset |
0002F00A | 342D | TypeOffset |
0002F00C | 3436 | TypeOffset |
... | ... | ... |
注釋:RVA是在文件當中這些數(shù)據(jù)所存儲的RVA宵蛀,注釋是自己加的昆著,文件里是沒有的
解讀:VirtualAddress成員的值為1000,說明TypeOffset數(shù)組的基準地址為RVA1000术陶,SizeOfBlock的值為150凑懂,TypeOffset數(shù)組的大小(不是長度)為150瞳别。TypeOffset的值為2B大小征候,是由4位的Type與12位的Offset合成的,如3420--->
類型(4位) | 偏移(12位) |
---|---|
3 | 420 |
低12位的偏移才是真正的位移祟敛,它是基于VA成員的偏移疤坝,因此
RVA = VirtualSize + Offset
等程序真正在內(nèi)存中運行時,RVA=1420的地址處所存的硬編碼地址馆铁,就會被替換成新的地址跑揉。
注釋:TypeOffset項中指向位移的低12位所擁有的最大地址值為1000,為了表示更大的地址埠巨,要添加一個與其對應的塊(使用結構體的原因)历谍,這些塊以數(shù)組形式羅列(就是結構體數(shù)組),故稱為重定位表辣垒。