Skip to content

Commit

Permalink
[BUGFIX] Trim raw section size to the actual raw size (if the section…
Browse files Browse the repository at this point in the history
… start is correct. Round up virtual size to PAGE_SIZE
  • Loading branch information
hasherezade committed Oct 29, 2024
1 parent d55874d commit ae5b66d
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 11 deletions.
14 changes: 14 additions & 0 deletions libpeconv/include/peconv/pe_hdrs_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,20 @@ namespace peconv {
*/
const ULONGLONG MAX_HEADER_SIZE = PAGE_SIZE;

template <typename INT_TYPE>
INT_TYPE round_up_to_unit(const INT_TYPE size, const INT_TYPE unit)
{
if (unit == 0) {
return size;
}
INT_TYPE units_count = size / unit;
INT_TYPE rounded_size = units_count * unit;
if (rounded_size < size) {
rounded_size += unit;
}
return rounded_size;
}

/**
Fetch image size from headers.
*/
Expand Down
8 changes: 1 addition & 7 deletions libpeconv/src/pe_hdrs_helper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -553,13 +553,7 @@ DWORD peconv::get_virtual_sec_size(IN const BYTE* pe_hdr, IN const PIMAGE_SECTIO
}
//TODO: calculate real size, round up to Virtual Alignment
DWORD alignment = peconv::get_sec_alignment((const PBYTE)pe_hdr, false);
DWORD vsize = sec_hdr->Misc.VirtualSize;
if (alignment != 0) {
DWORD units = vsize / alignment;
if ((vsize % alignment) > 0) units++;

vsize = units * alignment;
}
DWORD vsize = peconv::round_up_to_unit(sec_hdr->Misc.VirtualSize, alignment);
DWORD image_size = peconv::get_image_size(pe_hdr);
//if it is bigger than the image size, use the size from the headers
if ((sec_hdr->VirtualAddress + vsize) > image_size) {
Expand Down
13 changes: 9 additions & 4 deletions libpeconv/src/pe_raw_to_virtual.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,15 @@ bool sections_raw_to_virtual(IN const BYTE* payload, IN SIZE_T payloadSize, OUT
std::cerr << "[-] Raw section size is out ouf bounds: " << std::hex << sec_size << std::endl;
return false;
}

// validate source:
if (!validate_ptr((const LPVOID)payload, payloadSize, section_raw_ptr, sec_size)) {
std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
continue;
if (next_sec->PointerToRawData > payloadSize) {
std::cerr << "[-] Section " << i << ": out ouf bounds, skipping... " << std::endl;
continue;
}
// trim section
sec_size = payloadSize - (next_sec->PointerToRawData);
}
// validate destination:
if (!peconv::validate_ptr(destBuffer, destBufferSize, section_mapped, sec_size)) {
Expand Down Expand Up @@ -110,7 +115,7 @@ BYTE* peconv::pe_raw_to_virtual(
}
DWORD payloadImageSize = 0;

bool is64 = is64bit(payload);
const bool is64 = is64bit(payload);
if (is64) {
IMAGE_NT_HEADERS64* payload_nt_hdr = (IMAGE_NT_HEADERS64*)nt_hdr;
payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
Expand All @@ -119,9 +124,9 @@ BYTE* peconv::pe_raw_to_virtual(
IMAGE_NT_HEADERS32* payload_nt_hdr = (IMAGE_NT_HEADERS32*)nt_hdr;
payloadImageSize = payload_nt_hdr->OptionalHeader.SizeOfImage;
}
payloadImageSize = peconv::round_up_to_unit(payloadImageSize, (DWORD)PAGE_SIZE);

DWORD protect = executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;

//first we will prepare the payload image in the local memory, so that it will be easier to edit it, apply relocations etc.
//when it will be ready, we will copy it into the space reserved in the target process
BYTE* localCopyAddress = alloc_pe_buffer(payloadImageSize, protect, desired_base);
Expand Down

0 comments on commit ae5b66d

Please sign in to comment.