我正在分析一个可执行文件的格式,我在image_optional_header
中找到了基重定位表,这个基重定位表是什么?
发布于 2015-08-13 15:54:53
重定位表是一个查找表,它列出了PE文件在非默认基地址加载时需要打补丁的所有部分。
还有一篇好文章:http://web.archive.org/web/20200806080448/http://www.csn.ul.ie/~caolan/pub/winresdump/winresdump/doc/pefile2.html
发布于 2020-05-23 19:37:04
有2个重定位表。COFF重定位表,仅存在于.obj文件中,包含访问目标文件中本地/外部链接符号的所有指令的rip相对偏移量字节的地址,与符号表中它所引用的符号条目的索引配对。节的COFF重定位表由节表中COFF头之后的节的节头指向。
typedef struct {
unsigned long r_vaddr; /* address of relocation */
unsigned long r_symndx; /* symbol we're adjusting for */
unsigned short r_type; /* type of relocation */
} RELOC; //COFF relocation table entry
对于未在目标文件中定义的符号,它将是symbol table中的*UNDEF*
条目(节号为*UNDEF*
节),并且距*UNDEF*
节的偏移量始终为0。对于已定义的符号,它将在符号表中具有正确的部分和到该部分的正确偏移量,如果符号名称不能内联到字符串表条目中,它将指向字符串表中符号名称的索引。链接器将使用静态符号的这些section+offsets和它包含的外部符号的section+offsets来计算从r_vaddr
的末尾到符号的section+offset的正确偏移量。然后,它用该值替换r_vaddr
处的地址,即用正确的相对值替换call -1
或call 0
基重定位表用于运行时,在.obj文件中构建,并合并到最终的.exe中,由PE标头中的BaseRelocationTable
指向,通常在.reloc
中。如果映像加载的地址不是链接器选择的ImageBase,并将其放在PE标头中,则需要应用基重定位表中的补丁。基重定位表由基重定位块组成,每个块描述4个KiB页面。块头包含页面的RVA和块结构的大小。块的其余部分包含2字节字段的阵列,其中2字节的前4位指示重定位类型,后12位指示与需要应用重定位的页RVA的偏移量。这将是指令中地址字段的偏移量。为了重新定位,加载器只计算ImageBase和进程在PEB中的实际基地址之间的差值,并从地址中加/减它。不会有太多的基址重定位,因为代码中的大多数符号都使用了寄存器间接rip相对寻址(对于mov和dllimport调用)和直接相对寻址(对于常规调用)。在COFF对象中,相对地址和绝对地址都需要重新定位,在PE可执行文件中,只有绝对地址需要重新定位。
typedef struct _IMAGE_BASE_RELOCATION {
DWORD VirtualAddress; //Page RVA
DWORD SizeOfBlock;
WORD TypeOffset[1];
} IMAGE_BASE_RELOCATION; //base relocation table
https://stackoverflow.com/questions/31981929
复制相似问题