- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
- 84
- 85
- 86
- 87
- 88
- 89
- 90
- 91
- 92
- 93
- 94
- 95
- 96
- 97
- 98
- 99
- 100
#define IMAGE_BASE_RELOC_TYPE 0x0C
#define IMAGE_BASE_RELOC_OFFSET 0x0FFF
#define IMAGE_GET_BASE_RELOC_TYPE(entry) entry >> IMAGE_BASE_RELOC_TYPE
#define IMAGE_GET_BASE_RELOC_OFFSET(entry) entry & IMAGE_BASE_RELOC_OFFSET
__declspec(safebuffers) __declspec(noinline) DWORD mapping_code(LPVOID map_struct)
{
auto map = static_cast<MM_DATA*>(map_struct);
auto base = map->base;
auto dos = reinterpret_cast<PIMAGE_DOS_HEADER>(base);
auto nt_headers = reinterpret_cast<PIMAGE_NT_HEADERS>(base + dos->e_lfanew);
auto opt_header = &nt_headers->OptionalHeader;
auto file_header = &nt_headers->FileHeader;
const bool has_entry_point = opt_header->AddressOfEntryPoint != 0;
auto dll_main = reinterpret_cast<DllMainFn>(base + opt_header->AddressOfEntryPoint);
auto load_library = map->load_library;
auto get_proc_address = map->get_proc_address;
auto virtual_protect = map->virtual_protect;
auto rtl_add_function_table = map->rtl_add_function_table;
auto reloc_dir = opt_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
auto location_delta = reinterpret_cast<uintptr_t>(base) - static_cast<uintptr_t>(opt_header->ImageBase);
if (location_delta && reloc_dir.Size)
{
auto reloc_begin = reinterpret_cast<PIMAGE_BASE_RELOCATION>(base + reloc_dir.VirtualAddress);
auto reloc_end = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<std::byte*>(reloc_begin) + reloc_dir.Size);
while (reloc_begin < reloc_end && reloc_begin->SizeOfBlock)
{
auto amount_of_entries = (reloc_begin->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(WORD);
auto entries = reinterpret_cast<PWORD>(reloc_begin + 1);
for (size_t i = 0; i < amount_of_entries; i++)
{
WORD type = IMAGE_GET_BASE_RELOC_TYPE(entries[i]);
WORD offset = IMAGE_GET_BASE_RELOC_OFFSET(entries[i]);
if (type == IMAGE_REL_BASED_DIR64)
{
uintptr_t* path_at = reinterpret_cast<uintptr_t*>(base + reloc_begin->VirtualAddress + offset);
*path_at += location_delta;
}
}
reloc_begin = reinterpret_cast<PIMAGE_BASE_RELOCATION>(reinterpret_cast<std::byte*>(reloc_begin) + reloc_begin->SizeOfBlock);
}
}
auto import_dir = opt_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
if (import_dir.Size)
{
auto import_desc = reinterpret_cast<PIMAGE_IMPORT_DESCRIPTOR>(base + import_dir.VirtualAddress);
while (import_desc->Name)
{
auto module_name = reinterpret_cast<char*>(base + import_desc->Name);
HMODULE module = load_library(module_name);
if (!module)
{
map->status = LOAD_LIBRARY_FAILED;
return -2;
}
auto INT_TABLE = reinterpret_cast<PIMAGE_THUNK_DATA>(base + (import_desc->OriginalFirstThunk ? import_desc->OriginalFirstThunk : import_desc->FirstThunk));
auto IAT_TABLE = reinterpret_cast<PIMAGE_THUNK_DATA>(base + (import_desc->FirstThunk));
for (; INT_TABLE->u1.AddressOfData ; INT_TABLE++, IAT_TABLE++)
{
FARPROC address = IMAGE_SNAP_BY_ORDINAL(INT_TABLE->u1.Ordinal) ?
get_proc_address(module, reinterpret_cast<char*>(IMAGE_ORDINAL(INT_TABLE->u1.Ordinal))) :
get_proc_address(module, reinterpret_cast<PIMAGE_IMPORT_BY_NAME>(base + INT_TABLE->u1.AddressOfData)->Name);
if (!address)
{
map->status = GET_PROC_ADDRESS_FAILED;
return -3;
}
IAT_TABLE->u1.Function = reinterpret_cast<uintptr_t>(address);
}
++import_desc;
}
}
auto delay_dir = opt_header->DataDirectory[IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT];
if (delay_dir.Size)
{
auto delay_desc = reinterpret_cast<PIMAGE_DELAYLOAD_DESCRIPTOR>(base + delay_dir.VirtualAddress);
while (delay_desc->DllNameRVA)
{