資料目錄中的表是分散在各個節裡的,如果對節進行加密,作業系統找不到表,就無法引導程式。因此加密前要先把表移動到新的節裡。
計算重定位表的大小,首先要遍歷重定位表,累加 sizeofblock,然後新增乙個節,大小是表的大小檔案對齊。最後把錶複製到新增節的開頭,然後更新資料目錄的virtualaddress指向新的重定位表。
// 移動重定位表到新增節,返回新緩衝區的大小
dword moverelocationtabletonewsection
(lpvoid pfilebuffer, lpvoid *pnewfilebuffer, dword dwfilebuffersize)
dword dwnewbuffersize =
addsection
(pfilebuffer, pnewfilebuffer, dwfilebuffersize, \
align
(dwrelocationtablesize, poptionheader-
>filealignment));
pdosheader =
(pimage_dos_header)
*pnewfilebuffer;
ppeheader =
(pimage_file_header)
(pdosheader-
>e_lfanew +
(dword)pdosheader +4)
; poptionheader =
(pimage_optional_header32)
((dword)ppeheader +
sizeof
(image_file_header));
psectionheader =
(pimage_section_header)
((dword)poptionheader + ppeheader-
>sizeofoptionalheader)
;// 修改新增節屬性為可讀、含已初始化資料
psectionheader[ppeheader-
>numberofsections -1]
.characteristics =
0x40000040
;// 指標指向重定位表
prelocationtable =
(pimage_base_relocation)
((dword)
*pnewfilebuffer + \
rvatofoa
(*pnewfilebuffer, poptionheader-
>datadirectory[5]
.virtualaddress));
// 定義插入點為新增節的起始位址
lpvoid pinsert =
(lpvoid)
((dword)
*pnewfilebuffer + psectionheader[ppeheader-
>numberofsections -1]
.pointertorawdata)
;// 拷貝重定位表
memcpy
(pinsert,
(lpvoid)prelocationtable, dwrelocationtablesize)
;// 更新目錄項,指向新的重定位表
poptionheader-
>datadirectory[5]
.virtualaddress =
foatorva
(*pnewfilebuffer, \
(dword)pinsert -
(dword)
*pnewfilebuffer)
;return dwnewbuffersize;
}
修改前和修改後對比
共享可寫節包含重定位 理解重定位
一 段的概念 段是程式的組成元素。將整個程式分成乙個乙個段,並且給每個段起乙個名字,然後在鏈結時就可以用這個名字來指示這些段,使得這些段排布在合適的位置。乙個程式通常包含以下五個段 段 text 存放 指令 唯讀資料段 rodata 存放有初始值並且const修飾的全域性類變數 全域性變數或stat...
基址重定位表
向程序的虛擬記憶體載入pe檔案 exe dll sys 時,問價會被載入到pe頭的imagebase所指的位址處,若載入的時dll sys 檔案,且在imagebase位置處已經載入了其他dll檔案,那麼pe裝載器就會將其載入到其他未被占用的空間,這就是pe檔案的重定位。ex a.dll被載入到te...
PE 重定位表
參考文章 重定位表 relocation table 用於在程式載入到記憶體中時,進行記憶體位址的修正。為什麼要進行記憶體位址的修正?我們舉個例子來說 test.exe可執行程式需要三個動態鏈結庫dll a.dll,b.dll,c.dll 假設test.exe的imagebase為400000h,而...