11bool sections_raw_to_virtual(IN
const BYTE* payload, IN SIZE_T payloadSize, OUT BYTE* destBuffer, IN SIZE_T destBufferSize)
13 if (!payload || !destBuffer)
return false;
15 BYTE* payload_nt_hdr =
get_nt_hdrs(payload, payloadSize);
16 if (!payload_nt_hdr) {
17 LOG_ERROR(
"Invalid PE at 0x%llx.", (
unsigned long long)payload);
21 const bool is64b =
is64bit(payload);
23 IMAGE_FILE_HEADER *fileHdr =
nullptr;
25 void* secptr =
nullptr;
27 IMAGE_NT_HEADERS64* payload_nt_hdr64 = (IMAGE_NT_HEADERS64*)payload_nt_hdr;
28 fileHdr = &(payload_nt_hdr64->FileHeader);
29 hdrsSize = payload_nt_hdr64->OptionalHeader.SizeOfHeaders;
30 secptr = (
void*)((ULONG_PTR)&(payload_nt_hdr64->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
33 IMAGE_NT_HEADERS32* payload_nt_hdr32 = (IMAGE_NT_HEADERS32*)payload_nt_hdr;
34 fileHdr = &(payload_nt_hdr32->FileHeader);
35 hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders;
36 secptr = (
void*)((ULONG_PTR)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
40 for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
41 PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)((ULONG_PTR)secptr + ((ULONG_PTR)IMAGE_SIZEOF_SECTION_HEADER * i));
42 if (!
validate_ptr(
static_cast<const void*
>(payload), payloadSize, next_sec, IMAGE_SIZEOF_SECTION_HEADER)) {
45 const BYTE* next_sec_dest = destBuffer + (
reinterpret_cast<const BYTE*
>(next_sec) - payload);
46 if (!
validate_ptr(
static_cast<const void*
>(destBuffer), destBufferSize, next_sec_dest, IMAGE_SIZEOF_SECTION_HEADER)) {
49 if (next_sec->PointerToRawData == 0 || next_sec->SizeOfRawData == 0) {
52 void* section_mapped = destBuffer + next_sec->VirtualAddress;
53 void* section_raw_ptr = (BYTE*)payload + next_sec->PointerToRawData;
54 size_t sec_size = next_sec->SizeOfRawData;
56 if ((next_sec->VirtualAddress + sec_size) > destBufferSize) {
57 sec_size = (destBufferSize > next_sec->VirtualAddress) ? SIZE_T(destBufferSize - next_sec->VirtualAddress) : 0;
58 LOG_WARNING(
"Section %u: virtual size exceeds buffer, truncating to 0x%zx (buffer: 0x%zx).", i, sec_size, destBufferSize);
60 if (next_sec->VirtualAddress >= destBufferSize && sec_size != 0) {
61 LOG_ERROR(
"Section %u: VirtualAddress 0x%lx is out of bounds.", i, next_sec->VirtualAddress);
64 if (next_sec->PointerToRawData + sec_size > destBufferSize) {
65 LOG_ERROR(
"Section %u: raw data exceeds buffer (size: 0x%zx).", i, sec_size);
70 if (!
validate_ptr(
static_cast<const void*
>(payload), payloadSize, section_raw_ptr, sec_size)) {
71 if (next_sec->PointerToRawData > payloadSize) {
72 LOG_WARNING(
"Section %u: PointerToRawData out of bounds, skipping.", i);
76 sec_size = payloadSize - (next_sec->PointerToRawData);
80 LOG_WARNING(
"Section %u: destination out of bounds, skipping.", i);
83 memcpy(section_mapped, section_raw_ptr, sec_size);
84 if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
85 first_raw = next_sec->PointerToRawData;
92 LOG_INFO(
"SizeOfHeaders not set, using first section raw offset as fallback: 0x%lx.", hdrsSize);
94 if (!
validate_ptr((
const LPVOID)payload, destBufferSize, (
const LPVOID)payload, hdrsSize)) {
97 memcpy(destBuffer, payload, hdrsSize);
102 IN
const BYTE* payload,
104 OUT
size_t &out_size,
105 IN OPTIONAL
bool executable,
106 IN OPTIONAL ULONG_PTR desired_base
112 LOG_ERROR(
"Invalid PE at 0x%llx.", (
unsigned long long)(ULONG_PTR)payload);
115 DWORD payloadImageSize = 0;
117 const bool is64 =
is64bit(payload);
119 IMAGE_NT_HEADERS64* payload_nt_hdr = (IMAGE_NT_HEADERS64*)nt_hdr;
120 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
123 IMAGE_NT_HEADERS32* payload_nt_hdr = (IMAGE_NT_HEADERS32*)nt_hdr;
124 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
128 DWORD protect = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
131 BYTE* localCopyAddress =
alloc_pe_buffer(payloadImageSize, protect,
reinterpret_cast<void*
>(desired_base));
132 if (!localCopyAddress) {
133 LOG_ERROR(
"Could not allocate memory in the current process.");
136 LOG_DEBUG(
"Allocated local memory: %p size: %x", localCopyAddress, payloadImageSize);
138 LOG_ERROR(
"Could not copy PE file into virtual buffer.");
142 out_size = payloadImageSize;
143 return localCopyAddress;