GP-4347: PeLoader now pads initialized memory blocks with 0 instead of

creating an additional uninitialized block. Also improved Bytes Source
column of Memory Map.
This commit is contained in:
Ryan Kurtz 2024-02-22 07:33:45 -05:00
parent 5690528835
commit f9ce96fd6d
9 changed files with 35 additions and 21 deletions

View file

@ -134,10 +134,10 @@
this property applies to Default and Overlay blocks.</P> this property applies to Default and Overlay blocks.</P>
<P><I><B>Byte Source -</B></I> Provides information about the source of the bytes in this <P><I><B>Byte Source -</B></I> Provides information about the source of the bytes in this
block. If the bytes were originally imported from a file, then this will indicate which file block. A block is made up of one or more sub-blocks. Each sub-block is listed by its type,
and the offset into that file. If the bytes are mapped to another region of memory, it will size, and other type-specific information. For example, if the bytes were originally imported
provide the address for the mapping. Blocks may consist of regions that have different from a file, then the file name and the offset into that file is displayed. If the bytes are
sources. In that case, source information about the first several regions will be mapped to another region of memory, then the start address for the mapping will be
displayed.</P> displayed.</P>
<P><I><B>Source -</B></I> Description of block origination.</P> <P><I><B>Source -</B></I> Description of block origination.</P>

View file

@ -467,7 +467,7 @@ class MemoryMapModel extends AbstractSortedTableModel<MemoryBlock> implements Pr
String description = limited String description = limited
.stream() .stream()
.map(info -> info.getDescription()) .map(info -> info.getDescription())
.collect(Collectors.joining(", ")); .collect(Collectors.joining(" | "));
//@formatter:on //@formatter:on
if (limited != sourceInfos) { if (limited != sourceInfos) {
description += "..."; description += "...";

View file

@ -209,7 +209,7 @@ public class MemoryBlockUtils {
* @param w the write permission for the new block. * @param w the write permission for the new block.
* @param x the execute permission for the new block. * @param x the execute permission for the new block.
* @param log a {@link MessageLog} for appending error messages * @param log a {@link MessageLog} for appending error messages
* @return the new created block * @return the newly created block or null if the operation failed
* @throws AddressOverflowException if the address * @throws AddressOverflowException if the address
*/ */
public static MemoryBlock createInitializedBlock(Program program, boolean isOverlay, public static MemoryBlock createInitializedBlock(Program program, boolean isOverlay,
@ -262,7 +262,7 @@ public class MemoryBlockUtils {
* @param x the execute permission for the new block. * @param x the execute permission for the new block.
* @param log a {@link MessageLog} for appending error messages * @param log a {@link MessageLog} for appending error messages
* @param monitor the monitor for canceling this potentially long running operation. * @param monitor the monitor for canceling this potentially long running operation.
* @return the new created block * @return the newly created block or null if the operation failed
* @throws AddressOverflowException if the address * @throws AddressOverflowException if the address
*/ */
public static MemoryBlock createInitializedBlock(Program program, boolean isOverlay, public static MemoryBlock createInitializedBlock(Program program, boolean isOverlay,

View file

@ -46,6 +46,7 @@ import ghidra.program.model.address.*;
import ghidra.program.model.data.*; import ghidra.program.model.data.*;
import ghidra.program.model.listing.*; import ghidra.program.model.listing.*;
import ghidra.program.model.mem.MemoryAccessException; import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.reloc.Relocation.Status; import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationTable; import ghidra.program.model.reloc.RelocationTable;
import ghidra.program.model.symbol.*; import ghidra.program.model.symbol.*;
@ -671,6 +672,7 @@ public class PeLoader extends AbstractPeDebugLoader {
int rawDataSize = sections[i].getSizeOfRawData(); int rawDataSize = sections[i].getSizeOfRawData();
int rawDataPtr = sections[i].getPointerToRawData(); int rawDataPtr = sections[i].getPointerToRawData();
virtualSize = sections[i].getVirtualSize(); virtualSize = sections[i].getVirtualSize();
MemoryBlock block = null;
if (rawDataSize != 0 && rawDataPtr != 0) { if (rawDataSize != 0 && rawDataPtr != 0) {
int dataSize = int dataSize =
((rawDataSize > virtualSize && virtualSize > 0) || rawDataSize < 0) ((rawDataSize > virtualSize && virtualSize > 0) || rawDataSize < 0)
@ -682,8 +684,8 @@ public class PeLoader extends AbstractPeDebugLoader {
Msg.warn(this, "OptionalHeader.SizeOfImage < size of " + Msg.warn(this, "OptionalHeader.SizeOfImage < size of " +
sections[i].getName() + " section"); sections[i].getName() + " section");
} }
MemoryBlockUtils.createInitializedBlock(prog, false, sectionName, address, block = MemoryBlockUtils.createInitializedBlock(prog, false, sectionName,
fileBytes, rawDataPtr, dataSize, "", "", r, w, x, log); address, fileBytes, rawDataPtr, dataSize, "", "", r, w, x, log);
sectionToAddress.put(sections[i], address); sectionToAddress.put(sections[i], address);
} }
if (rawDataSize == virtualSize) { if (rawDataSize == virtualSize) {
@ -711,9 +713,24 @@ public class PeLoader extends AbstractPeDebugLoader {
else { else {
int dataSize = (virtualSize > 0 || rawDataSize < 0) ? virtualSize : 0; int dataSize = (virtualSize > 0 || rawDataSize < 0) ? virtualSize : 0;
if (dataSize > 0) { if (dataSize > 0) {
MemoryBlockUtils.createUninitializedBlock(prog, false, sectionName, address, if (block != null) {
dataSize, "", "", r, w, x, log); MemoryBlock paddingBlock =
sectionToAddress.putIfAbsent(sections[i], address); MemoryBlockUtils.createInitializedBlock(prog, false, sectionName,
address, dataSize, "", "", r, w, x, log);
if (paddingBlock != null) {
try {
prog.getMemory().join(block, paddingBlock);
}
catch (Exception e) {
log.appendMsg(e.getMessage());
}
}
}
else {
MemoryBlockUtils.createUninitializedBlock(prog, false, sectionName,
address, dataSize, "", "", r, w, x, log);
sectionToAddress.putIfAbsent(sections[i], address);
}
} }
} }

View file

@ -179,7 +179,7 @@ class BitMappedSubMemoryBlock extends SubMemoryBlock {
@Override @Override
protected String getDescription() { protected String getDescription() {
return "Bit Mapped: " + mappedAddress; return "bitmap[0x%x, 0x%x, %s]".formatted(subBlockOffset, subBlockLength, mappedAddress);
} }
} }

View file

@ -117,6 +117,6 @@ class BufferSubMemoryBlock extends SubMemoryBlock {
@Override @Override
protected String getDescription() { protected String getDescription() {
return ""; return "init[0x%x]".formatted(subBlockLength);
} }
} }

View file

@ -199,7 +199,7 @@ class ByteMappedSubMemoryBlock extends SubMemoryBlock {
@Override @Override
protected String getDescription() { protected String getDescription() {
return "Byte Mapped: " + mappedAddress + ", " + byteMappingScheme; return "bytemap[0x%x, 0x%x, %s]".formatted(subBlockOffset, subBlockLength, mappedAddress);
} }
} }

View file

@ -112,10 +112,8 @@ class FileBytesSubMemoryBlock extends SubMemoryBlock {
@Override @Override
protected String getDescription() { protected String getDescription() {
String fileName = fileBytes.getFilename(); return "%s[0x%x, 0x%x]".formatted(fileBytes.getFilename(),
fileBytesOffset + fileBytes.getFileOffset(), subBlockLength);
String hexString = Long.toHexString(fileBytesOffset + fileBytes.getFileOffset());
return "File: " + fileName + ": 0x" + hexString;
} }
@Override @Override

View file

@ -86,7 +86,6 @@ class UninitializedSubMemoryBlock extends SubMemoryBlock {
@Override @Override
protected String getDescription() { protected String getDescription() {
return ""; return "uninit[0x%x]".formatted(subBlockLength);
} }
} }