源代碼如下: typedef struct _IMAGE_BASE_RELOCATION { DWORD VirtualAddress; DWORD SizeOfBlock; // WORD TypeOffset[1]; } IMAGE_BASE_RELOCATION; typedef IMAGE_... ...
源代碼如下:
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 的
.DataDirectory[IMAGE_DIRECTORY_ENTRY_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反彙編查看: