libPeConv
A library to load, manipulate, dump PE files.
Loading...
Searching...
No Matches
pe_raw_to_virtual.cpp
Go to the documentation of this file.
2
3#include "peconv/util.h"
5
6#include <iostream>
7
8using namespace peconv;
9
10// Map raw PE into virtual memory of local process:
12{
13 if (!payload || !destBuffer) return false;
14
16 if (payload_nt_hdr == NULL) {
17 std::cerr << "Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
18 return false;
19 }
20
21 const bool is64b = is64bit(payload);
22
24 DWORD hdrsSize = 0;
26 if (is64b) {
28 fileHdr = &(payload_nt_hdr64->FileHeader);
29 hdrsSize = payload_nt_hdr64->OptionalHeader.SizeOfHeaders;
30 secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr64->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
31 }
32 else {
34 fileHdr = &(payload_nt_hdr32->FileHeader);
35 hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders;
36 secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
37 }
38 DWORD first_raw = 0;
39 //copy all the sections, one by one:
40 for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
42 if (!validate_ptr((const LPVOID)payload, payloadSize, next_sec, IMAGE_SIZEOF_SECTION_HEADER) // check if fits in the source size
43 || !validate_ptr((const LPVOID)payload, destBufferSize, next_sec, IMAGE_SIZEOF_SECTION_HEADER)) // check if fits in the destination size
44 {
45 return false;
46 }
47 if (next_sec->PointerToRawData == 0 || next_sec->SizeOfRawData == 0) {
48 continue; //skipping empty
49 }
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
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;
58 }
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;
61 return false;
62 }
63 if (next_sec->PointerToRawData + sec_size > destBufferSize) {
64 std::cerr << "[-] Raw section size is out ouf bounds: " << std::hex << sec_size << std::endl;
65 return false;
66 }
67 // validate source:
69 std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
70 continue;
71 }
72 // validate destination:
74 std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
75 continue;
76 }
78 if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
79 first_raw = next_sec->PointerToRawData;
80 }
81 }
82
83 //copy payload's headers:
84 if (hdrsSize == 0) {
86#ifdef _DEBUG
87 std::cout << "hdrsSize not filled, using calculated size: " << std::hex << hdrsSize << "\n";
88#endif
89 }
91 return false;
92 }
94 return true;
95}
96
98 IN const BYTE* payload,
99 IN size_t in_size,
100 OUT size_t &out_size,
103)
104{
105 //check payload:
107 if (nt_hdr == NULL) {
108 std::cerr << "Invalid payload: " << std::hex << (ULONGLONG) payload << std::endl;
109 return nullptr;
110 }
112
113 bool is64 = is64bit(payload);
114 if (is64) {
116 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
117 }
118 else {
120 payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
121 }
122
124
125 //first we will prepare the payload image in the local memory, so that it will be easier to edit it, apply relocations etc.
126 //when it will be ready, we will copy it into the space reserved in the target process
128 if (localCopyAddress == NULL) {
129 std::cerr << "Could not allocate memory in the current process" << std::endl;
130 return NULL;
131 }
132 //printf("Allocated local memory: %p size: %x\n", localCopyAddress, payloadImageSize);
134 std::cerr << "Could not copy PE file" << std::endl;
135 return NULL;
136 }
138 return localCopyAddress;
139}
bool parse_delayed_desc(BYTE *modulePtr, const size_t moduleSize, const ULONGLONG img_base, LPSTR lib_name, const T_FIELD ordinal_flag, IMAGE_DELAYLOAD_DESCRIPTOR *desc, peconv::t_function_resolver *func_resolver)
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.