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);
42 for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
43 PIMAGE_SECTION_HEADER next_sec = (PIMAGE_SECTION_HEADER)((ULONGLONG)secptr + (IMAGE_SIZEOF_SECTION_HEADER * i));
44 if (!
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;
53 raw_end = next_sec->SizeOfRawData + next_sec->PointerToRawData;
55 if ((next_sec->VirtualAddress + sec_size) > destBufferSize) {
56 std::cerr <<
"[!] Virtual section size is out ouf bounds: " << std::hex << sec_size << std::endl;
57 sec_size = (destBufferSize > next_sec->VirtualAddress) ? SIZE_T(destBufferSize - next_sec->VirtualAddress) : 0;
58 std::cerr <<
"[!] Truncated to maximal size: " << std::hex << sec_size <<
", buffer size:" << destBufferSize << std::endl;
60 if (next_sec->VirtualAddress >= destBufferSize && sec_size != 0) {
61 std::cerr <<
"[-] VirtualAddress of section is out ouf bounds: " << std::hex << next_sec->VirtualAddress << std::endl;
64 if (next_sec->PointerToRawData + sec_size > destBufferSize) {
65 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 std::cerr <<
"[-] Section " << i <<
": out ouf bounds, skipping... " << std::endl;
75 std::cerr <<
"[-] Section " << i <<
": out ouf bounds, skipping... " << std::endl;
78 memcpy(section_mapped, section_raw_ptr, sec_size);
79 if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
80 first_raw = next_sec->PointerToRawData;
88 std::cout <<
"hdrsSize not filled, using calculated size: " << std::hex << hdrsSize <<
"\n";
91 if (!
validate_ptr((
const LPVOID)payload, destBufferSize, (
const LPVOID)payload, hdrsSize)) {
94 memcpy(destBuffer, payload, hdrsSize);
99 IN
const BYTE* payload,
101 OUT
size_t &out_size,
102 IN OPTIONAL
bool executable,
103 IN OPTIONAL ULONGLONG desired_base
108 if (nt_hdr == NULL) {
109 std::cerr <<
"Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
112 DWORD payloadImageSize = 0;
116 IMAGE_NT_HEADERS64* payload_nt_hdr = (IMAGE_NT_HEADERS64*)nt_hdr;
117 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
120 IMAGE_NT_HEADERS32* payload_nt_hdr = (IMAGE_NT_HEADERS32*)nt_hdr;
121 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
124 DWORD protect = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;
128 BYTE* localCopyAddress =
alloc_pe_buffer(payloadImageSize, protect, desired_base);
129 if (localCopyAddress == NULL) {
130 std::cerr <<
"Could not allocate memory in the current process" << std::endl;
135 std::cerr <<
"Could not copy PE file" << std::endl;
138 out_size = payloadImageSize;
139 return localCopyAddress;
bool validate_ptr(IN const void *buffer_bgn, IN SIZE_T buffer_size, IN const void *field_bgn, IN SIZE_T field_size)
ALIGNED_BUF alloc_pe_buffer(size_t buffer_size, DWORD protect, ULONGLONG desired_base=NULL)
BYTE * pe_raw_to_virtual(IN const BYTE *rawPeBuffer, IN size_t rawPeSize, OUT size_t &outputSize, IN OPTIONAL bool executable=true, IN OPTIONAL ULONGLONG desired_base=0)
bool is64bit(IN const BYTE *pe_buffer)
BYTE * get_nt_hdrs(IN const BYTE *pe_buffer, IN OPTIONAL size_t buffer_size=0)
Wrappers over various fields in the PE header. Read, write, parse PE headers.
bool sections_raw_to_virtual(IN const BYTE *payload, IN SIZE_T payloadSize, OUT BYTE *destBuffer, IN SIZE_T destBufferSize)
Converting PE from raw to virtual format.
Miscellaneous utility functions.