void fixRelocTable(DWORD pFileBufferSrc, DWORD AOffset) {
PIMAGE_DOS_HEADER pIDH
=
(PIMAGE_DOS_HEADER)pFileBufferSrc;
PIMAGE_FILE_HEADER pIFH
=
(PIMAGE_FILE_HEADER)(pFileBufferSrc
+
pIDH
-
>e_lfanew
+
4
);
PIMAGE_OPTIONAL_HEADER pIOH
=
(PIMAGE_OPTIONAL_HEADER)(pFileBufferSrc
+
pIDH
-
>e_lfanew
+
0x18
);
PIMAGE_SECTION_HEADER pISH
=
(PIMAGE_SECTION_HEADER)(pFileBufferSrc
+
pIDH
-
>e_lfanew
+
sizeof(IMAGE_NT_HEADERS));
DWORD pRelocationDirectoryVirtual
=
NULL;
PIMAGE_BASE_RELOCATION pRelocationDirectory
=
NULL;
IMAGE_DATA_DIRECTORY
*
dataDirectories
=
NULL;
DWORD FOA, NumberOfRelocation;
PWORD Location;
DWORD RVA_Data;
WORD reloData;
dataDirectories
=
pIOH
-
>DataDirectory;
pRelocationDirectoryVirtual
=
(DWORD) dataDirectories[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress;
if
(pRelocationDirectoryVirtual) {
RVA_To_FOA(pFileBufferSrc, pRelocationDirectoryVirtual, &FOA);
pRelocationDirectory
=
(PIMAGE_BASE_RELOCATION)((DWORD)pFileBufferSrc
+
FOA);
while
(pRelocationDirectory
-
>SizeOfBlock && pRelocationDirectory
-
>VirtualAddress) {
NumberOfRelocation
=
(pRelocationDirectory
-
>SizeOfBlock
-
8
)
/
2
;
/
/
每个重定位块中的数据项的数量
Location
=
(PWORD)((DWORD)pRelocationDirectory
+
8
);
/
/
加上
8
个字节
for
(DWORD i
=
0
; i < NumberOfRelocation; i
+
+
) {
if
(Location[i] >>
12
!
=
0
) {
/
/
判断是否是垃圾数据
/
/
WORD类型的变量进行接收
reloData
=
(Location[i] &
0xFFF
);
/
/
这里进行与操作 只取
4
字节 二进制的后
12
位
RVA_Data
=
pRelocationDirectory
-
>VirtualAddress
+
reloData;
/
/
这个是RVA的地址
RVA_To_FOA(pFileBufferSrc, RVA_Data, &FOA);
/
/
修复步骤的核心操作,这里镜像加载时偏移了 AOffset 字节,所以重定项的地址也要偏移这么多
*
(PDWORD)((DWORD)pFileBufferSrc
+
(DWORD)FOA)
=
*
(PDWORD)((DWORD)pFileBufferSrc
+
(DWORD)FOA)
+
AOffset;
}
}
pRelocationDirectory
=
(PIMAGE_BASE_RELOCATION)((DWORD)pRelocationDirectory
+
(DWORD)pRelocationDirectory
-
>SizeOfBlock);
/
/
上面的
for
循环完成之后,跳转到下个重定位块 继续如上的操作
}
}
}