static
LPVOID
RDILoadXCDllByRes()
{
char
* dll_bytes = NULL;
DWORD
dll_size = 0;
dll_bytes = ReleaseFile2(g_hModule, IDR_DATA1,
"DATA"
, &dll_size);
PIMAGE_DOS_HEADER dosheaders = (PIMAGE_DOS_HEADER)dll_bytes;
PIMAGE_NT_HEADERS ntheaders = (PIMAGE_NT_HEADERS)((
DWORD64
)dll_bytes + dosheaders->e_lfanew);
SIZE_T
dllImage_size = ntheaders->OptionalHeader.SizeOfImage;
LPVOID
dllbase = VirtualAlloc(NULL, dllImage_size, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE);
DWORD64
delta_image_base = (
DWORD64
)dllbase - (
DWORD64
)ntheaders->OptionalHeader.ImageBase;
memcpy
(dllbase, dll_bytes, ntheaders->OptionalHeader.SizeOfHeaders);
PIMAGE_SECTION_HEADER section = IMAGE_FIRST_SECTION(ntheaders);
for
(
size_t
i = 0; i < ntheaders->FileHeader.NumberOfSections; i++, section++)
{
LPVOID
section_destination = (
LPVOID
)((
DWORD64
)dllbase + (
DWORD64
)section->VirtualAddress);
LPVOID
section_bytes = (
LPVOID
)((
DWORD64
)dll_bytes + (
DWORD64
)section->PointerToRawData);
memcpy
(section_destination, section_bytes, section->SizeOfRawData);
}
IMAGE_DATA_DIRECTORY relocations = ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC];
DWORD64
relocation_table = relocations.VirtualAddress + (
DWORD64
)dllbase;
DWORD64
relocations_processed = 0;
while
(relocations_processed < relocations.Size)
{
PBASE_RELOCATION_BLOCK relocation_block = (PBASE_RELOCATION_BLOCK)(relocation_table + relocations_processed);
relocations_processed +=
sizeof
(BASE_RELOCATION_BLOCK);
DWORD
relocations_count = (relocation_block->block_size -
sizeof
(BASE_RELOCATION_BLOCK)) /
sizeof
(BASE_RELOCATION_ENTRY);
PBASE_RELOCATION_ENTRY relocation_entries = (PBASE_RELOCATION_ENTRY)(relocation_table + relocations_processed);
for
(
DWORD
i = 0; i < relocations_count; i++)
{
relocations_processed +=
sizeof
(BASE_RELOCATION_ENTRY);
if
(relocation_entries[i].type == 0)
{
continue
;
}
DWORD64
relocation_rva = relocation_block->page_addr + relocation_entries[i].offset;
DWORD64
address_2_patch = 0;
ReadProcessMemory(GetCurrentProcess(), (
LPCVOID
)((
DWORD64
)dllbase + relocation_rva), &address_2_patch,
sizeof
(
DWORD64
), NULL);
address_2_patch += delta_image_base;
memcpy
((
PVOID
)((
DWORD64
)dllbase + relocation_rva), &address_2_patch,
sizeof
(
DWORD64
));
}
}
IMAGE_DATA_DIRECTORY imports_directory = ntheaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
PIMAGE_IMPORT_DESCRIPTOR import_descriptor = (PIMAGE_IMPORT_DESCRIPTOR)(imports_directory.VirtualAddress + (
DWORD64
)dllbase);
LPCSTR
libraryname =
""
;
HMODULE
library = NULL;
while
(import_descriptor->Name != NULL)
{
libraryname = (
LPCSTR
)import_descriptor->Name + (
DWORD64
)dllbase;
library = LoadLibraryA(libraryname);
if
(library)
{
PIMAGE_THUNK_DATA thunk = NULL;
thunk = (PIMAGE_THUNK_DATA)((
DWORD64
)dllbase + import_descriptor->FirstThunk);
while
(thunk->u1.AddressOfData != NULL)
{
if
(IMAGE_SNAP_BY_ORDINAL(thunk->u1.Ordinal))
{
LPCSTR
functionOrdinal = (
LPCSTR
)IMAGE_ORDINAL(thunk->u1.Ordinal);
thunk->u1.Function = (
DWORD64
)GetProcAddress(library, functionOrdinal);
}
else
{
PIMAGE_IMPORT_BY_NAME functionName = (PIMAGE_IMPORT_BY_NAME)((
DWORD64
)dllbase + thunk->u1.AddressOfData);
DWORD64
functionAddress = (
DWORD64
)GetProcAddress(library, functionName->Name);
thunk->u1.Function = functionAddress;
}
++thunk;
}
}
import_descriptor++;
}
DLLEntry dllentry = (DLLEntry)((
DWORD64
)dllbase + ntheaders->OptionalHeader.AddressOfEntryPoint);
(*dllentry)((
HINSTANCE
)dllbase, DLL_PROCESS_ATTACH, 0);
HeapFree(GetProcessHeap(), 0, dll_bytes);
return
dllbase;
}