21 const size_t vBufSize = this->
peBuffer.vBufSize;
22 if (vBuf ==
nullptr)
return 0;
24 if (!this->
artefacts.hasNtHdrs())
return 0;
26 const size_t dos_pe_size =
sizeof(IMAGE_DOS_HEADER) +
sizeof(IMAGE_NT_SIGNATURE);
32 if (!this->
artefacts.hasSectionHdrs())
return 0;
34 size_t shift_size = dos_pe_size - nt_offset;
35 size_t hdrs_end = this->
artefacts.secHdrsOffset + (this->
artefacts.secCount + 1)*
sizeof(IMAGE_SECTION_HEADER);
36 if (!peconv::is_padding(vBuf + hdrs_end, shift_size, 0)) {
39 size_t hdrs_size = this->
artefacts.dropPeBase(hdrs_end);
40 BYTE *new_nt_ptr = vBuf + this->
artefacts.peBaseOffset + shift_size;
41 if (!peconv::validate_ptr(vBuf, vBufSize, new_nt_ptr, hdrs_size)) {
44 if (nt_offset <
sizeof(IMAGE_NT_SIGNATURE)) {
47 const size_t pe_offset = nt_offset -
sizeof(IMAGE_NT_SIGNATURE);
48 IMAGE_DOS_HEADER dos_template = { 0 };
49 dos_template.e_magic = IMAGE_DOS_SIGNATURE;
50 dos_template.e_lfanew = LONG(pe_offset + shift_size);
53 BYTE *mz_ptr = vBuf + this->
artefacts.peBaseOffset;
54 if (!peconv::validate_ptr(vBuf, vBufSize, mz_ptr,
sizeof(IMAGE_DOS_HEADER))) {
58 DWORD* pe_ptr = (DWORD*)(vBuf + this->
artefacts.peBaseOffset + dos_template.e_lfanew);
59 if (!peconv::validate_ptr(vBuf, vBufSize, pe_ptr,
sizeof(DWORD))) {
63 memmove(new_nt_ptr, (vBuf + this->
artefacts.peBaseOffset), hdrs_size);
66 memcpy(mz_ptr, &dos_template,
sizeof(IMAGE_DOS_HEADER));
69 *pe_ptr = IMAGE_NT_SIGNATURE;
106 const size_t vBufSize = this->
peBuffer.vBufSize;
107 if (!vBuf)
return false;
113 BYTE *hdr_ptr = (sec_offset + vBuf);
115 size_t max_sec_size = 0;
117 IMAGE_SECTION_HEADER* prev_sec =
nullptr;
118 IMAGE_SECTION_HEADER* curr_sec = (IMAGE_SECTION_HEADER*)(hdr_ptr);
120 const ULONGLONG pe_img_base = (ULONGLONG)
artefacts.peImageBase();
122 const size_t hdr_sec_count = peconv::get_sections_count(vBuf, vBufSize);
123 const size_t sec_count =
artefacts.secCount > hdr_sec_count ?
artefacts.secCount : hdr_sec_count;
126 for (i = 0; i < sec_count; i++, curr_sec++) {
127 if (!peconv::validate_ptr(vBuf, vBufSize, curr_sec,
sizeof(IMAGE_SECTION_HEADER))) {
131 const DWORD sec_rva = curr_sec->VirtualAddress;
132 const DWORD sec_size = curr_sec->Misc.VirtualSize;
134 const ULONGLONG sec_va = pe_img_base + sec_rva;
135 size_t real_sec_size = peconv::fetch_region_size(processHandle, (PBYTE)sec_va);
138 if (!peconv::validate_ptr(vBuf, vBufSize, vBuf + sec_rva,
sizeof(BYTE)) && !real_sec_size) {
140 std::cout << i <<
"# Invalid section found: " << std::hex
141 << sec_rva <<
" of size: " << sec_size << std::endl;
146 if (sec_size > real_sec_size) {
147 curr_sec->Misc.VirtualSize = DWORD(real_sec_size);
149 std::cout << i <<
"# Fixed section " << std::hex << sec_rva <<
" size: " << std::hex
150 << sec_size <<
" vs real: " << real_sec_size << std::endl;
154 max_sec_size = (real_sec_size > max_sec_size) ? real_sec_size : max_sec_size;
156 if (prev_sec && curr_sec->Misc.VirtualSize > 0) {
157 ULONGLONG prev_sec_end = prev_sec->VirtualAddress + prev_sec->Misc.VirtualSize;
158 if (prev_sec_end > curr_sec->VirtualAddress) {
159 if (curr_sec->VirtualAddress > prev_sec->VirtualAddress) {
160 DWORD diff = curr_sec->VirtualAddress - prev_sec->VirtualAddress;
161 prev_sec->Misc.VirtualSize = diff;
163 std::cout <<
"Trimmed section: " << std::dec << i << std::endl;
168 if (curr_sec->Misc.VirtualSize > 0) {
173 IMAGE_FILE_HEADER* file_hdr =
const_cast<IMAGE_FILE_HEADER*
>(peconv::get_file_hdr(vBuf, vBufSize));
174 if (file_hdr && (i > 0)) {
176 file_hdr->NumberOfSections = MASK_TO_WORD(i);
179 if (max_sec_size == 0) {
188 const size_t vBufSize = this->
peBuffer.vBufSize;
189 if (!vBuf)
return false;
196 const BYTE *hdr_ptr = (sec_offset + vBuf);
197 IMAGE_SECTION_HEADER* curr_sec = (IMAGE_SECTION_HEADER*)(hdr_ptr);
199 const DWORD sec_all_flags = IMAGE_SCN_TYPE_NO_PAD
200 | IMAGE_SCN_CNT_CODE | IMAGE_SCN_CNT_INITIALIZED_DATA | IMAGE_SCN_CNT_UNINITIALIZED_DATA
201 | IMAGE_SCN_LNK_NRELOC_OVFL | IMAGE_SCN_MEM_DISCARDABLE | IMAGE_SCN_MEM_NOT_CACHED
202 | IMAGE_SCN_MEM_NOT_PAGED | IMAGE_SCN_MEM_SHARED | IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_MEM_READ
203 | IMAGE_SCN_MEM_WRITE
204 | IMAGE_SCN_NO_DEFER_SPEC_EXC | IMAGE_SCN_GPREL;
206 for (
size_t i = 0; i <
artefacts.secCount; i++, curr_sec++) {
211 const DWORD charact = curr_sec->Characteristics;
212 curr_sec->Characteristics = charact & sec_all_flags;
214 if (charact != curr_sec->Characteristics) {
215 std::cout <<
"Section characteristics overwriten\n";
225 const size_t vBufSize = this->
peBuffer.vBufSize;
226 if (!vBuf)
return false;
232 BYTE* nt_ptr = (BYTE*)((ULONGLONG)vBuf + nt_offset);
236 IMAGE_FILE_HEADER* hdr_candidate = (IMAGE_FILE_HEADER*)nt_ptr;
237 if (!peconv::validate_ptr(vBuf, vBufSize, hdr_candidate,
sizeof(IMAGE_FILE_HEADER))) {
242 size_t opt_hdr_size = 0;
244 hdr_candidate->Machine = IMAGE_FILE_MACHINE_AMD64;
245 opt_hdr_size =
sizeof(IMAGE_OPTIONAL_HEADER64);
248 hdr_candidate->Machine = IMAGE_FILE_MACHINE_I386;
249 opt_hdr_size =
sizeof(IMAGE_OPTIONAL_HEADER32);
253 size_t calc_offset = sec_offset - (nt_offset +
sizeof(IMAGE_FILE_HEADER));
255 if (calc_offset != opt_hdr_size) {
256 std::cout <<
"[WARNING] Calculated sections header offset is different than the saved one!\n";
258 hdr_candidate->NumberOfSections = WORD(this->
artefacts.secCount);
259 hdr_candidate->SizeOfOptionalHeader = WORD(calc_offset);
261 hdr_candidate->NumberOfSymbols = 0;
262 hdr_candidate->PointerToSymbolTable = 0;
269 const size_t vBufSize = this->
peBuffer.vBufSize;
270 if (!vBuf)
return false;
276 BYTE* nt_ptr = (BYTE*)((ULONGLONG)vBuf + nt_offset);
277 BYTE *pe_ptr = nt_ptr -
sizeof(DWORD);
279 if (!peconv::validate_ptr(vBuf, vBufSize, pe_ptr,
sizeof(DWORD))) {
282 IMAGE_NT_HEADERS32 *nt32 = (IMAGE_NT_HEADERS32*)pe_ptr;
284 nt32->Signature = IMAGE_NT_SIGNATURE;
285 IMAGE_FILE_HEADER *file_hdr = &nt32->FileHeader;
287 bool is64bit = (file_hdr->Machine == IMAGE_FILE_MACHINE_AMD64) ?
true :
false;
289 if (nt32->FileHeader.SizeOfOptionalHeader == 0) {
290 nt32->FileHeader.SizeOfOptionalHeader = is64bit ?
sizeof(IMAGE_OPTIONAL_HEADER64) :
sizeof(IMAGE_OPTIONAL_HEADER32);
292 LONG pe_offset = LONG((ULONGLONG)pe_ptr - (ULONGLONG)vBuf);
293 IMAGE_DOS_HEADER* dosHdr = (IMAGE_DOS_HEADER*) vBuf;
294 dosHdr->e_magic = IMAGE_DOS_SIGNATURE;
295 dosHdr->e_lfanew = pe_offset;
297 bool is_fixed =
false;
307 if (!peconv::get_nt_hdrs(vBuf, vBufSize)) {