diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/FileHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/FileHeader.java index 045d56eb35..b78dfb2d81 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/FileHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/FileHeader.java @@ -307,16 +307,32 @@ public class FileHeader implements StructConverter { Msg.error(this, "File alignment == 0: section processing skipped"); } else { sectionHeaders = new SectionHeader[numberOfSections]; - for (int i = 0; i < numberOfSections; ++i) { - sectionHeaders[i] = SectionHeader.createSectionHeader(reader, tmpIndex); - - int sizeOfRawData = sectionHeaders[i].getSizeOfRawData(); - sizeOfRawData = PortableExecutable.computeAlignment(sizeOfRawData, optHeader.getFileAlignment()); - sectionHeaders[i].setSizeOfRawData(sizeOfRawData); - - tmpIndex += SectionHeader.IMAGE_SIZEOF_SECTION_HEADER; - } - } + for (int i = 0; i < numberOfSections; ++i) { + sectionHeaders[i] = SectionHeader.createSectionHeader(reader, tmpIndex); + + // Ensure VirtualSize is large enough to accommodate SizeOfRawData, but do not + // exceed the next alignment boundary. We can only do this if the VirtualAddress is + // already properly aligned, since we currently don't support moving sections to + // different addresses to enforce alignment. + int virtualAddress = sectionHeaders[i].getVirtualAddress(); + int virtualSize = sectionHeaders[i].getVirtualSize(); + int sizeOfRawData = sectionHeaders[i].getSizeOfRawData(); + int alignedVirtualAddress = PortableExecutable.computeAlignment(virtualAddress, + optHeader.getSectionAlignment()); + int alignedVirtualSize = PortableExecutable.computeAlignment(virtualSize, + optHeader.getSectionAlignment()); + if (virtualAddress == alignedVirtualAddress) { + if (sizeOfRawData > virtualSize) { + sectionHeaders[i].setVirtualSize( + Math.min(sizeOfRawData, alignedVirtualSize)); + } + } + else { + Msg.warn(this, "Section " + sectionHeaders[i].getName() + " is not aligned!"); + } + tmpIndex += SectionHeader.IMAGE_SIZEOF_SECTION_HEADER; + } + } reader.setPointerIndex(oldIndex); } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PortableExecutable.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PortableExecutable.java index a183d5b7fa..cb34160594 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PortableExecutable.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/pe/PortableExecutable.java @@ -184,7 +184,7 @@ public class PortableExecutable { } public static int computeAlignment(int value, int alignment) { - if ((value % alignment) == 0) { + if (alignment == 0 || (value % alignment) == 0) { return value; } int a = ((value + alignment) / alignment) * alignment;