9#define RELOC_32BIT_FIELD 3
10#define RELOC_64BIT_FIELD 0xA
23 ULONGLONG* relocateAddr = (ULONGLONG*)((ULONG_PTR)relocField);
24 ULONGLONG rva = (*relocateAddr) -
oldBase;
25 (*relocateAddr) = rva +
newBase;
28 DWORD* relocateAddr = (DWORD*)((ULONG_PTR)relocField);
29 ULONGLONG rva = ULONGLONG(*relocateAddr) -
oldBase;
30 (*relocateAddr) =
static_cast<DWORD
>(rva +
newBase);
42 if (entriesNum == 0) {
46 for (SIZE_T i = 0; i < entriesNum; i++) {
50 DWORD type = entry->
Type;
62 if (entriesNum == 0) {
67 for (i = 0; i < entriesNum; i++) {
71 DWORD offset = entry->
Offset;
72 DWORD type = entry->
Type;
78 printf(
"[-] Not supported relocations format at %d: %d\n", (
int)i, (
int)type);
82 DWORD reloc_field = page + offset;
83 if (reloc_field >= moduleSize) {
85 printf(
"[-] Malformed field: %lx\n", reloc_field);
92 std::cout <<
"[-] Failed processing reloc field at: " << std::hex << reloc_field <<
"\n";
104 if (relocDir == NULL) {
106 std::cout <<
"[!] WARNING: no relocation table found!\n";
110 if (!
validate_ptr(modulePtr, moduleSize, relocDir,
sizeof(IMAGE_DATA_DIRECTORY))) {
111 std::cerr <<
"[!] Invalid relocDir pointer\n";
114 DWORD maxSize = relocDir->Size;
115 DWORD relocAddr = relocDir->VirtualAddress;
116 bool is64b =
is64bit((BYTE*)modulePtr);
118 IMAGE_BASE_RELOCATION* reloc = NULL;
120 DWORD parsedSize = 0;
121 while (parsedSize < maxSize) {
122 reloc = (IMAGE_BASE_RELOCATION*)(relocAddr + parsedSize + (ULONG_PTR)modulePtr);
123 if (!
validate_ptr(modulePtr, moduleSize, reloc,
sizeof(IMAGE_BASE_RELOCATION))) {
125 std::cerr <<
"[-] Invalid address of relocations\n";
129 if (reloc->SizeOfBlock == 0) {
132 size_t entriesNum = (reloc->SizeOfBlock - 2 *
sizeof(DWORD)) /
sizeof(WORD);
133 DWORD page = reloc->VirtualAddress;
137 std::cerr <<
"[-] Invalid address of relocations block\n";
141 if (!
process_reloc_block(block, entriesNum, page, modulePtr, moduleSize, is64b, callback)) {
146 parsedSize += reloc->SizeOfBlock;
153 const bool is64b =
is64bit((BYTE*)modulePtr);
160 if (modulePtr == NULL) {
167 printf(
"New Base: %llx\n", newBase);
168 printf(
"Old Base: %llx\n", oldBase);
170 if (newBase == oldBase) {
172 printf(
"Nothing to relocate! oldBase is the same as the newBase!\n");
180 printf(
"Could not relocate the module!\n");
virtual bool processRelocField(ULONG_PTR relocField)
ApplyRelocCallback(bool _is64bit, ULONGLONG _oldBase, ULONGLONG _newBase)
RelocBlockCallback(bool _is64bit)
virtual bool processRelocField(ULONG_PTR relocField)=0
ULONGLONG get_image_base(IN const BYTE *pe_buffer)
bool validate_ptr(IN const void *buffer_bgn, IN size_t buffer_size, IN const void *field_bgn, IN size_t field_size)
bool process_relocation_table(IN PVOID modulePtr, IN SIZE_T moduleSize, IN RelocBlockCallback *callback)
bool is64bit(IN const BYTE *pe_buffer)
bool relocate_module(IN BYTE *modulePtr, IN SIZE_T moduleSize, IN ULONGLONG newBase, IN ULONGLONG oldBase=0)
struct peconv::_BASE_RELOCATION_ENTRY BASE_RELOCATION_ENTRY
IMAGE_DATA_DIRECTORY * get_directory_entry(IN const BYTE *pe_buffer, IN DWORD dir_id, IN bool allow_empty=false)
bool has_valid_relocation_table(IN const PBYTE modulePtr, IN const size_t moduleSize)
Wrappers over various fields in the PE header. Read, write, parse PE headers.
bool process_reloc_block(BASE_RELOCATION_ENTRY *block, SIZE_T entriesNum, DWORD page, PVOID modulePtr, SIZE_T moduleSize, bool is64bit, RelocBlockCallback *callback)
#define RELOC_64BIT_FIELD
bool apply_relocations(PVOID modulePtr, SIZE_T moduleSize, ULONGLONG newBase, ULONGLONG oldBase)
bool is_empty_reloc_block(BASE_RELOCATION_ENTRY *block, SIZE_T entriesNum, DWORD page, PVOID modulePtr, SIZE_T moduleSize)
#define RELOC_32BIT_FIELD
Operating on PE file's relocations table.