libPeConv
A library to load, manipulate, dump PE files.
Loading...
Searching...
No Matches
pe_virtual_to_raw.cpp
Go to the documentation of this file.
2
3#include "peconv/util.h"
5#include "peconv/relocate.h"
6
7#include <iostream>
8
9using namespace peconv;
10
12{
13 if (!payload || !destAddress) 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 } else {
33 fileHdr = &(payload_nt_hdr32->FileHeader);
34 hdrsSize = payload_nt_hdr32->OptionalHeader.SizeOfHeaders;
35 secptr = (LPVOID)((ULONGLONG)&(payload_nt_hdr32->OptionalHeader) + fileHdr->SizeOfOptionalHeader);
36 }
37
38 //copy all the sections, one by one:
39#ifdef _DEBUG
40 std::cout << "Coping sections:" << std::endl;
41#endif
42 DWORD first_raw = 0;
44 for (WORD i = 0; i < fileHdr->NumberOfSections; i++) {
47 return false;
48 }
49
50 LPVOID section_mapped = (BYTE*) payload + next_sec->VirtualAddress;
51 LPVOID section_raw_ptr = destAddress + next_sec->PointerToRawData;
52 SIZE_T sec_size = next_sec->SizeOfRawData;
53
54 size_t new_end = sec_size + next_sec->PointerToRawData;
56
57 if ((next_sec->VirtualAddress + sec_size) > payload_size) {
58#ifdef _DEBUG
59 std::cerr << "[!] Virtual section size is out ouf bounds: " << std::hex << sec_size << std::endl;
60#endif
61 sec_size = (payload_size > next_sec->VirtualAddress) ? SIZE_T(payload_size - next_sec->VirtualAddress) : 0;
62#ifdef _DEBUG
63 std::cerr << "[!] Truncated to maximal size: " << std::hex << sec_size << ", buffer size: " << payload_size << std::endl;
64#endif
65 }
66 if (next_sec->VirtualAddress > payload_size && sec_size != 0) {
67#ifdef _DEBUG
68 std::cerr << "[-] VirtualAddress of section is out ouf bounds: " << std::hex << next_sec->VirtualAddress << std::endl;
69#endif
70 return false;
71 }
72 if (next_sec->PointerToRawData + sec_size > payload_size) {
73#ifdef _DEBUG
74 std::cerr << "[-] Raw section size is out ouf bounds: " << std::hex << sec_size << std::endl;
75#endif
76 return false;
77 }
78#ifdef _DEBUG
79 std::cout << "[+] " << next_sec->Name << " to: " << std::hex << section_raw_ptr << std::endl;
80#endif
81 //validate source:
83#ifdef _DEBUG
84 std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
85#endif
86 continue;
87 }
88 //validate destination:
90#ifdef _DEBUG
91 std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
92#endif
93 continue;
94 }
96 if (first_raw == 0 || (next_sec->PointerToRawData < first_raw)) {
97 first_raw = next_sec->PointerToRawData;
98 }
99 }
101 if (raw_size_ptr != NULL) {
102 (*raw_size_ptr) = raw_end;
103 }
104
105 //copy payload's headers:
106 if (hdrsSize == 0) {
108#ifdef _DEBUG
109 std::cout << "[!] hdrsSize not filled, using calculated size: " << std::hex << hdrsSize << "\n";
110#endif
111 }
113 return false;
114 }
116 return true;
117}
118
120 IN BYTE* payload,
121 IN size_t in_size,
123 OUT size_t &out_size,
124 IN OPTIONAL bool rebuffer
125)
126{
128 if (out_buf == NULL) return NULL; //could not allocate output buffer
129
131 if (rebuffer) {
133 if (in_buf == NULL) {
135 return NULL;
136 }
138 }
139
141 bool isOk = true;
142 // from the loadBase go back to the original base
143 if (!relocate_module(in_buf, in_size, oldBase, loadBase)) {
144 //Failed relocating the module! Changing image base instead...
146 std::cerr << "[-] Failed relocating the module!" << std::endl;
147 isOk = false;
148 } else {
149#ifdef _DEBUG
150 std::cerr << "[!] WARNING: The module could not be relocated, so the ImageBase has been changed instead!" << std::endl;
151#endif
152 }
153 }
154 SIZE_T raw_size = 0;
155 if (isOk) {
157 isOk = false;
158 }
159 }
160 if (rebuffer && in_buf != NULL) {
162 in_buf = NULL;
163 }
164 if (!isOk) {
166 out_buf = NULL;
167 raw_size = 0;
168 }
170 return out_buf;
171}
172
174 IN const BYTE* payload,
175 IN size_t in_size,
177 OUT size_t &out_size
178)
179{
182 if (!out_buf) {
183 out_size = 0;
184 return nullptr;
185 }
187
189 bool isOk = true;
190 // from the loadBase go back to the original base
191 if (!relocate_module(out_buf, out_size, oldBase, loadBase)) {
192 //Failed relocating the module! Changing image base instead...
194 std::cerr << "[-] Failed relocating the module!" << std::endl;
195 isOk = false;
196 } else {
197#ifdef _DEBUG
198 std::cerr << "[!] WARNING: The module could not be relocated, so the ImageBase has been changed instead!" << std::endl;
199#endif
200 }
201 }
202 //---
203 //set raw alignment the same as virtual
206 isOk = false;
207 }
208 //set Raw pointers and sizes of the sections same as Virtual
210 for (size_t i = 0; i < sections_count; i++) {
212 if (!sec) break;
213
214 sec->Misc.VirtualSize = peconv::get_virtual_sec_size(out_buf, sec, true);
215 sec->SizeOfRawData = sec->Misc.VirtualSize;
216 sec->PointerToRawData = sec->VirtualAddress;
217 }
219 if (!isOk) {
221 out_buf = nullptr;
222 out_size = 0;
223 }
224 return out_buf;
225}
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 set_sec_alignment(IN OUT BYTE *pe_buffer, IN bool is_raw, IN DWORD new_alignment)
DWORD get_virtual_sec_size(IN const BYTE *pe_hdr, IN const PIMAGE_SECTION_HEADER sec_hdr, IN bool rounded)
bool update_image_base(IN OUT BYTE *payload, IN ULONGLONG destImageBase)
ULONGLONG get_image_base(IN const BYTE *pe_buffer)
bool validate_ptr(IN const void *buffer_bgn, IN size_t buffer_size, IN const void *field_bgn, IN size_t field_size)
PIMAGE_SECTION_HEADER get_section_hdr(IN const BYTE *pe_buffer, IN const size_t buffer_size, IN size_t section_num)
BYTE * pe_virtual_to_raw(IN BYTE *payload, IN size_t in_size, IN ULONGLONG loadBase, OUT size_t &outputSize, IN OPTIONAL bool rebuffer=true)
bool free_pe_buffer(ALIGNED_BUF buffer, size_t buffer_size=0)
ALIGNED_BUF alloc_pe_buffer(size_t buffer_size, DWORD protect, ULONGLONG desired_base=NULL)
DWORD get_sec_alignment(IN const BYTE *modulePtr, IN bool is_raw)
bool is64bit(IN const BYTE *pe_buffer)
size_t get_sections_count(IN const BYTE *buffer, IN const size_t buffer_size)
bool relocate_module(IN BYTE *modulePtr, IN SIZE_T moduleSize, IN ULONGLONG newBase, IN ULONGLONG oldBase=0)
Definition relocate.cpp:158
BYTE * pe_realign_raw_to_virtual(IN const BYTE *payload, IN size_t in_size, IN ULONGLONG loadBase, OUT size_t &outputSize)
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_virtual_to_raw(BYTE *payload, SIZE_T payload_size, OUT BYTE *destAddress, OUT SIZE_T *raw_size_ptr)
Converting PE from virtual to raw format.
Operating on PE file's relocations table.
Miscellaneous utility functions.