PE手動重定位


本文已在看雪論壇發佈。

工具:RadAsm,010 Editor,LordPE。

源碼

	.386
	.model flat,stdcall
	option casemap:none

include		msvcrt.inc
includelib	msvcrt.lib

.data
szText	db	'welcome', 0ah, 00h
szPause db	'pause', 00h
.code

main:
	
	push offset szText
	call crt_printf
	add esp, 4
	
	push offset szPause
	call crt_system
	add esp, 4

	ret
end main

end

輸出一句“welcome”,然後執行system(pause)

運行

在這裏插入圖片描述

然後。用010Editor打開,開啓重定位。

在這裏插入圖片描述
在這裏插入圖片描述

關於這兩個屬性,文件頭中的IMAGE_FILE_RELOCS_STRIPPED是去除重定位信息的意思,可選頭中的IMAGE_DLLCHARACTERISTICS_DYNAMIC_BASE是動態基址的意思,前者置0,不去除信息;後者置1,開啓動態基址。

再次用OD加載。

在這裏插入圖片描述

可以看到,加載基址變了,但是兩個字符串還有兩個函數的地址還是沒有變,導致程序不能運行。下面就要添加重定位信息,讓它們一塊改變。

添加重定位信息

要分清楚區段和數據目錄表的關係。添加重定位信息要修改的是數據目錄表下標爲5那一項,不是添加.reloc區段(而且添加了也沒法加載)。區段是規定了屬性,真正用來找到重定位信息的是數據目錄表。

在PE中找個位置,我選擇了700H,然後計算它的RVA。

在這裏插入圖片描述
根據LordPE,700H位於rdata段,RVA==700h-600h+2000h==2100h

我們有兩個字符串和兩個函數需要重定位,也就是4個WORD,加上兩個DWORD,大小SizeOfBlock == 10H。數據目錄表中的size還要算上結尾兩個0,所以是12h.

在這裏插入圖片描述

//
// Based relocation format.
//
typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;		//RVA
    DWORD   SizeOfBlock;
//  WORD    TypeOffset[1];	//end with [00 00]
} IMAGE_BASE_RELOCATION;

struct {
    WORD Offset:12;     //lower 12 bit relocation offset
    WORD Type:4;	//higher 4 bit relocation type value : Based relocation types above
}TypeOffset;

因爲我們的程序是32位,所以重定位項的最高位Type爲3(IMAGE_REL_BASED_HIGHLOW),64位的PE通常爲A(IMAGE_REL_BASED_DIR64)。

根據第一張OD加載截圖,VirualAddress==1000H,4個偏移分別爲001h, 007h, 00fh, 015h

這樣,重定位信息就完成了。

00000700: 00 10 00 00 10 00 00 00 01 30 07 30 0F 30 15 30

再次用OD加載看一下。

在這裏插入圖片描述

4個位置的opcode都有了下劃線,說明有重定位,運行也沒有問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章