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 == NULL) {
17 std::cerr <<
"Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
21 const bool is64b =
is64bit(payload);
23 IMAGE_FILE_HEADER *fileHdr = NULL;
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 = (LPVOID)((ULONGLONG)&(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 = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
40 for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
41 PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)((ULONGLONG)secptr + ((ULONGLONG)IMAGE_SIZEOF_SECTION_HEADER * i));
42 if (!
validate_ptr((
const LPVOID)payload, payloadSize, next_sec, IMAGE_SIZEOF_SECTION_HEADER)
43 || !
validate_ptr((
const LPVOID)payload, destBufferSize, next_sec, IMAGE_SIZEOF_SECTION_HEADER))
47 if (next_sec->PointerToRawData == 0 || next_sec->SizeOfRawData == 0) {
50 LPVOID section_mapped = destBuffer + next_sec->VirtualAddress;
51 LPVOID section_raw_ptr = (BYTE*)payload + next_sec->PointerToRawData;
52 size_t sec_size = next_sec->SizeOfRawData;
54 if ((next_sec->VirtualAddress + sec_size) > destBufferSize) {
55 std::cerr <<
"[!] Virtual section size is out ouf bounds: " << std::hex << sec_size << std::endl;
56 sec_size = (destBufferSize > next_sec->VirtualAddress) ? SIZE_T(destBufferSize - next_sec->VirtualAddress) : 0;
57 std::cerr <<
"[!] Truncated to maximal size: " << std::hex << sec_size <<
", buffer size:" << destBufferSize << std::endl;
59 if (next_sec->VirtualAddress >= destBufferSize && sec_size != 0) {
60 std::cerr <<
"[-] VirtualAddress of section is out ouf bounds: " << std::hex << next_sec->VirtualAddress << std::endl;
63 if (next_sec->PointerToRawData + sec_size > destBufferSize) {
64 std::cerr <<
"[-] Raw section size is out ouf bounds: " << std::hex << sec_size << std::endl;
69 if (!
validate_ptr((
const LPVOID)payload, payloadSize, section_raw_ptr, sec_size)) {
70 if (next_sec->PointerToRawData > payloadSize) {
71 std::cerr <<
"[-] Section " << i <<
": out ouf bounds, skipping... " << std::endl;
75 sec_size = payloadSize - (next_sec->PointerToRawData);
79 std::cerr <<
"[-] Section " << i <<
": out ouf bounds, skipping... " << std::endl;
82 memcpy(section_mapped, section_raw_ptr, sec_size);
83 if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
84 first_raw = next_sec->PointerToRawData;
92 std::cout <<
"hdrsSize not filled, using calculated size: " << std::hex << hdrsSize <<
"\n";
95 if (!
validate_ptr((
const LPVOID)payload, destBufferSize, (
const LPVOID)payload, hdrsSize)) {
98 memcpy(destBuffer, payload, hdrsSize);
103 IN
const BYTE* payload,
105 OUT
size_t &out_size,
106 IN OPTIONAL
bool executable,
107 IN OPTIONAL ULONGLONG desired_base
112 if (nt_hdr == NULL) {
113 std::cerr <<
"Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
116 DWORD payloadImageSize = 0;
118 const bool is64 =
is64bit(payload);
120 IMAGE_NT_HEADERS64* payload_nt_hdr = (IMAGE_NT_HEADERS64*)nt_hdr;
121 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
124 IMAGE_NT_HEADERS32* payload_nt_hdr = (IMAGE_NT_HEADERS32*)nt_hdr;
125 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
129 DWORD protect = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
132 BYTE* localCopyAddress =
alloc_pe_buffer(payloadImageSize, protect, desired_base);
133 if (localCopyAddress == NULL) {
134 std::cerr <<
"Could not allocate memory in the current process" << std::endl;
139 std::cerr <<
"Could not copy PE file" << std::endl;
142 out_size = payloadImageSize;
143 return localCopyAddress;