我目前无法理解PE Base Relocations的构建方式。
我知道可以有多个重定位,我也理解为什么以及如何完成,但我只是不能以编程方式理解它:
以下哪项是正确的(WinNT.h中的IMAGE_BASE_RELOCATION)?
// Base relocation #1
DWORD VirtualAddress;
DWORD SizeOfBlock; // size of current relocation
WORD TypeOffset[1];
// Base relocation #2
DWORD VirtualAddress;
DWORD SizeOfBlock; // size of current relocation
WORD TypeOffset[1];
// Base relocation #3
DWORD VirtualAddress;
DWORD SizeOfBlock; // size of current relocation
WORD TypeOffset[1];
或者
DWORD VirtualAddress;
DWORD SizeOfBlock; // size of all relocations
WORD TypeOffset[1]; // relocation #1
WORD TypeOffset[1]; // relocation #2
WORD TypeOffset[1]; // relocation #3
或两者都不正确?我该如何以编程方式遍历所有基址重定位?
目前我有这个代码,在某处似乎不正确:
DWORD baseRelocationSize = imageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
unsigned int baseRelocationCount = baseRelocationSize / sizeof(IMAGE_BASE_RELOCATION);
DWORD baseDelta = (DWORD_PTR)moduleBase - (DWORD_PTR)imageNtHeaders->OptionalHeader.ImageBase;
IMAGE_BASE_RELOCATION* baseRelocation = (IMAGE_BASE_RELOCATION*)((DWORD_PTR)moduleBase + (DWORD_PTR)imageNtHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
for(unsigned int i = 0; i != baseRelocationCount; ++i)
{
unsigned int entryCount = (baseRelocation->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
for(unsigned int j = 0; j != entryCount; ++j)
{
WORD* entry = (WORD*)((DWORD_PTR)baseRelocation + (DWORD_PTR)sizeof(IMAGE_BASE_RELOCATION));
if((*entry >> 12) & IMAGE_REL_BASED_HIGHLOW)
{
DWORD* pdw = (PDWORD)((DWORD_PTR)moduleBase + (DWORD_PTR)baseRelocation->VirtualAddress + ((*entry) & 0xfff));
(*pdw) += baseDelta;
}
entry++;
}
baseRelocation += baseRelocation->SizeOfBlock;
}
答案 0 :(得分:17)
您指出的选项都不完全正确/无效。
这篇关于How to inject code in a PE file的优秀教程表明,实际的IMAGE_BASE_RELOCATION
结构是:
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress;
DWORD SizeOfBlock;
} IMAGE_BASE_RELOCATION, *PIMAGE_BASE_RELOCATION;
本document的第4.2和5.6节描述了结构。 SizeOfBlock-8
实际上表示在WORD TypeOffset
和VirtualAddress
之后跟随了多少SizeOfBlock
。
我想您也会对本教程的表7感兴趣,该表显示了重定位表中块的结构。我将这里的表格复制粘贴以供快速参考。
答案 1 :(得分:4)
从某些代码.. aldo检查出反应:)
BOOL FixRelocs(void *base, void *rBase, IMAGE_NT_HEADERS *ntHd, IMAGE_BASE_RELOCATION *reloc,
unsigned int size) {
unsigned long ImageBase = ntHd->OptionalHeader.ImageBase;
unsigned int nBytes = 0;
unsigned long delta = MakeDelta(unsigned long, rBase, ImageBase);
unsigned long *locBase;
unsigned int numRelocs;
unsigned short *locData;
unsigned int i;
while(1) {
locBase =
(unsigned long *)GetPtrFromRVA((DWORD)(reloc->VirtualAddress), ntHd, (PBYTE)base);
numRelocs = (reloc->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
if(nBytes >= size) break;
locData = MakePtr(unsigned short *, reloc, sizeof(IMAGE_BASE_RELOCATION));
for(i = 0; i < numRelocs; i++) {
if(((*locData >> 12) == IMAGE_REL_BASED_HIGHLOW))
*MakePtr(unsigned long *, locBase, (*locData & 0x0FFF)) += delta;
locData++;
}
nBytes += reloc->SizeOfBlock;
reloc = (IMAGE_BASE_RELOCATION *)locData;
}
return TRUE;
}