[PE结构分析] 10.基址重定位

源代码如下:

typedef struct _IMAGE_BASE_RELOCATION {
    DWORD   VirtualAddress;
    DWORD   SizeOfBlock;
//  WORD    TypeOffset[1];
} IMAGE_BASE_RELOCATION;
typedef IMAGE_BASE_RELOCATION UNALIGNED * PIMAGE_BASE_RELOCATION;

重定位表是一个数组,这个数组的大小记载在 _IMAGE_OPTIONAL_HEADER 的

.DataDirect??ory[IMAGE_DIRECTORY_E??NTRY_BASERELOC].Size 成员中

结构图如下,图片中 0 和 000 都表示16进制数,转换到二进制是  0000 和 0000 0000 0000:

每个元素的大小都记载在 SizeOfBlock 中,这个元素是由 一个 _IMAGE_BASE_RELOCATION 结构体和一个TypeOffset 数组组成的。TypeOffset 数组的每个元素占2个字节,其中,高4位是偏移类型(type),低12位表示需要重定位的地址(Offset),即,它与 VirtualAddress 相加即是指向 PE 映像中需要修改的那个代码的RVA。

偏移类型的含义如下:


Constant


Value


Description


IMAGE_REL_BASED_ABSOLUTE


0


The base relocation is skipped. This type can be used to pad a block.


IMAGE_REL_BASED_HIGH


1


The base relocation adds the high 16 bits of the difference to the 16bit field at offset. The 16-bit field represents the high value of a 32-bit word.


IMAGE_REL_BASED_LOW


2


The base relocation adds the low 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the low half of a 32-bit word.


IMAGE_REL_BASED_HIGHLOW


3


The base relocation applies all 32 bits of the difference to the 32-bit field at offset.


IMAGE_REL_BASED_HIGHADJ


4


The base relocation adds the high 16 bits of the difference to the 16-bit field at offset. The 16-bit field represents the high value of a 32-bit word. The low 16 bits of the 32-bit value are stored in the 16-bit word that follows this base relocation. This means that this base relocation occupies two slots.


IMAGE_REL_BASED_MIPS_JMPADDR


5


The relocation interpretation is dependent on the machine type.

When the machine type is MIPS, the base relocation applies to a MIPS jump instruction.


IMAGE_REL_BASED_ARM_MOV32


5


This relocation is meaningfull only when the machine type is ARM or Thumb. The base relocation applies the 32-bit address of a symbol across a consecutive MOVW/MOVT instruction pair.


IMAGE_REL_BASED_RISCV_HIGH20


5


This relocation is only meaningful when the machine type is RISC-V. The base relocation applies to the high 20 bits of a 32-bit absolute address.


6


Reserved, must be zero.


IMAGE_REL_BASED_THUMB_MOV32


7


This relocation is meaningful only when the machine type is Thumb. The base relocation applies the 32-bit address of a symbol to a consecutive MOVW/MOVT instruction pair.


IMAGE_REL_BASED_RISCV_LOW12I


7


This relocation is only meaningful when the machine type is RISC-V. The base relocation applies to the low 12 bits of a 32-bit absolute address formed in RISC-V I-type instruction format.


IMAGE_REL_BASED_RISCV_LOW12S


8


This relocation is only meaningful when the machine type is RISC-V. The base relocation applies to the low 12 bits of a 32-bit absolute address formed in RISC-V S-type instruction format.


IMAGE_REL_BASED_MIPS_JMPADDR16


9


The relocation is only meaningful when the machine type is MIPS. The base relocation applies to a MIPS16 jump instruction.


IMAGE_REL_BASED_DIR64


10


The base relocation applies the difference to the 64-bit field at offset.

其他中文翻译:

常量 描述
IMAGE_REL_BASED_ABSOLUTE       0x0 使块按照32位对齐,位置为0。
IMAGE_REL_BASED_HIGH 0x1 高16位必须应用于偏移量所指高字16位。
IMAGE_REL_BASED_LOW 0x2 低16位必须应用于偏移量所指低字16位。
IMAGE_REL_BASED_HIGHLOW 0x3 全部32位应用于所有32位。
IMAGE_REL_BASED_HIGHADJ 0x4 需要32位,高16位位于偏移量,低16位位于下一个偏移量数组元素,组合为一个带符号数,加上32位的一个数,然后加上8000然后把高16位保存在偏移量的16位域内。

例子:

分析常见的dll:在QQ中的 zlib.dll 文件 (在QQ安装目录下的bin文件夹中):

首先找到重定位表,这里使用工具:

找到数据:

VirtualAddress 为 0x1000,SizeOfBlock 为 0x64。第一个条目为 0x338C,高四位为 0x3,offset为 0x38C,即偏移地址为 0x138C (由 0x1000 + 0x38C得来)应用于此地址上全部32位。打开C32Asm反汇编查看:

时间: 2024-08-10 23:19:15

[PE结构分析] 10.基址重定位的相关文章

小甲鱼PE详解之基址重定位详解(PE详解10)

今天有一个朋友发短消息问我说“老师,为什么PE的格式要讲的这么这么细,这可不是一般的系哦”.其实之所以将PE结构放在解密系列继基础篇之后讲并且尽可能细致的讲,不是因为小甲鱼没事找事做,主要原因是因为PE结构非常重要,再说做这个课件的确是很费神的事哈.在这里再次强调一下,只要是windows操作程序,其就要遵循PE格式,再说人家看雪的网址就是www.pediy.com. 简单的讲是可以,但是怕就怕有些朋友知识点遗漏了或者错误理解意思.不能深刻体会等,这样的效果是不好的~所以,小甲鱼尽管这系列视频可

PE文件结构(五)基址重定位

PE文件结构(五) 参考 书:<加密与解密> 视频:小甲鱼 解密系列 视频 基址重定位 链接器生成一个PE文件时,它会假设程序被装入时使用的默认ImageBase基地址(VC默认exe基地址00400000h,dll基地址10000000h),并且会把代码中所有指令中用到的地址都使用默认的基地址(例如 程序代码中 push 10001000,就是把10000000h当做了基地址,把push 10001000写入到文件中).如果一个exe程序中一个dll装载时的地址与其它dll地址发生冲突(因为

解析PE资源表与重定位表

#include<Windows.h> #include<iostream> #include<stdio.h> #include<stdlib.h> #include<commdlg.h> using namespace std; DWORD dwFileSize; BYTE* g_pFileImageBase = 0; PIMAGE_NT_HEADERS g_pNt = 0; DWORD RVAtoFOA(DWORD dwRVA); //显示

基址重定位

一.需要重定位的原因 http://blog.sohu.com/s/NDg4ODAyODQ/179103126.html 二.需要重定位的指令 但凡涉及到直接寻址的指令都需要进行重定位处理 http://blog.sohu.com/s/NDg4ODAyODQ/179103126.html 三.参考 http://blog.csdn.net/misskissc/article/details/43063419 http://www.52pojie.cn/thread-101281-1-1.html

PE文件结构详解(六)重定位

前面两篇 PE文件结构详解(四)PE导入表 和 PE文件结构详解(五)延迟导入表 介绍了PE文件中比较常用的两种导入方式,不知道大家有没有注意到,在调用导入函数时系统生成的代码是像下面这样的: 在这里,IE的iexplorer.exe导入了Kernel32.dll的GetCommandLineA函数,可以看到这是个间接call,00401004这个地址的内存里保存了目的地址, 根据图中显示的符号信息可知,00401004这个地址是存在于iexplorer.exe模块中的,实际上也就是一项IAT的

程序地址重定位和模块绑定

1.程序的构建 在构建程序的时候,链接器都会给程序设置一个默认的加载地址,即首选基地址,它表示该模块被映射到进程地址空间时最佳的内存地址.默认情况下,对于EXE程序而言,windows链接器会将它的首选基地址设置为0X400000(四十万),而DLL程序的首选基地址则被设置为0X10000000(1千万),然后链接器将该地址以及一些相关数据和代码的地址写入到PE文件中.首选基地址的是为了系统程序加载器设计的,作用是告诉加载器把程序优选加载到该首选基地址,然后就可以直接将其他的数据和代码加载到内存

重定位引入和链接脚本

1.一个事实:大部分指令是位置有关编码位置无关编码(PIC,position independent code):汇编源文件被编码成二进制可执行程序时编码方式与位置(内存地址)无关.位置有关编码:汇编源码编码成二进制可执行程序后和内存地址是有关的. 我们在设计一个程序时,会给这个程序指定一个运行地址(链接地址).就是说我们在编译程序时其实心里是知道我们程序将来被运行时的地址(运行地址)的,而且必须给编译器链接器指定这个地址(链接地址)才行.最后得到的二进制程序理论上是和你指定的运行地址有关的,将

PE知识复习之PE的重定位表

PE知识复习之PE的重定位表 一丶何为重定位 重定位的意思就是修正偏移的意思.  如一个地址位 0x401234 ,Imagebase = 0x400000 . 那么RVA就是 1234.  如果Imagebase 变了成了0x300000, 那么修正之后就是 ImageBase + RVA = 0X300000+1234 = 0x301234. 首先我们知道.一个EXE文件.会调用很多DLL(PE) 有多个PE文件组成. exe文件启动的基址 (ImageBase) 是0x40000. 假设我

也谈PE重定位表

最近研究脱壳,遇到了dll,所以不可避免的需要修复重定位表.以前研究过也脱过不少壳,但都是exe从来没有手工修过重定位表,于是搜索之,恩有这么一篇:<PE重定位表学习手记>,有刚巧手上有看雪段钢等编著的<加密与解密>,一并阅读. <PE重定位表学习手记>中说到: 每个块的首部是如下定义: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; } IMAGE_BAS