diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/NewExecutable.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/NewExecutable.java index 5cea4c6384..e95d196494 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/NewExecutable.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/NewExecutable.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,12 +15,13 @@ */ package ghidra.app.util.bin.format.ne; -import generic.continues.*; -import ghidra.app.util.bin.*; -import ghidra.app.util.bin.format.*; -import ghidra.app.util.bin.format.mz.*; +import java.io.IOException; -import java.io.*; +import generic.continues.GenericFactory; +import ghidra.app.util.bin.ByteProvider; +import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; +import ghidra.app.util.bin.format.mz.DOSHeader; +import ghidra.program.model.address.SegmentedAddress; /** * A class to manage loading New Executables (NE). @@ -34,17 +34,20 @@ public class NewExecutable { private WindowsHeader winHeader; /** - * Constructs a new instance of an new executable. - * @param bp the byte provider - * @throws IOException if an I/O error occurs. - */ - public NewExecutable(GenericFactory factory, ByteProvider bp) throws IOException { + * Constructs a new instance of an new executable. + * @param factory is the object factory to bundle with the reader + * @param bp the byte provider + * @param baseAddr the image base of the executable + * @throws IOException if an I/O error occurs. + */ + public NewExecutable(GenericFactory factory, ByteProvider bp, SegmentedAddress baseAddr) + throws IOException { reader = new FactoryBundledWithBinaryReader(factory, bp, true); dosHeader = DOSHeader.createDOSHeader(reader); if (dosHeader.isDosSignature()) { try { - winHeader = new WindowsHeader(reader, (short)dosHeader.e_lfanew()); + winHeader = new WindowsHeader(reader, baseAddr, (short) dosHeader.e_lfanew()); } catch (InvalidWindowsHeaderException e) { } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/SegmentTable.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/SegmentTable.java index 15f0a278bc..41ad4b8822 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/SegmentTable.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/SegmentTable.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +17,9 @@ package ghidra.app.util.bin.format.ne; import java.io.IOException; -import ghidra.app.util.bin.format.*; +import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; +import ghidra.program.model.address.SegmentedAddress; +import ghidra.program.model.address.SegmentedAddressSpace; import ghidra.util.Conv; /** @@ -28,7 +29,8 @@ import ghidra.util.Conv; public class SegmentTable { private Segment [] segments; - SegmentTable(FactoryBundledWithBinaryReader reader, short index, short segmentCount, short shiftAlignCount) throws IOException { + SegmentTable(FactoryBundledWithBinaryReader reader, SegmentedAddress baseAddr, short index, + short segmentCount, short shiftAlignCount) throws IOException { long oldIndex = reader.getPointerIndex(); reader.setPointerIndex(Conv.shortToInt(index)); @@ -39,14 +41,29 @@ public class SegmentTable { segments = new Segment[segmentCountInt]; - int startOffset = 0; + SegmentedAddressSpace space; + int curSegment; + if (baseAddr != null) { + space = (SegmentedAddressSpace) baseAddr.getAddressSpace(); + curSegment = baseAddr.getSegment(); + } + else { + space = null; + curSegment = 0; + } for (int i = 0 ; i < segmentCountInt ; ++i) { - segments[i] = new Segment(reader, shiftAlignCount, startOffset >> 4); + segments[i] = new Segment(reader, shiftAlignCount, curSegment); int size = segments[i].getMinAllocSize() & 0xffff; if (size == 0) { size = 0x10000; } - startOffset = (startOffset + size + 0xf) & ~0xf; + if (space != null) { + SegmentedAddress endAddr = space.getAddress(curSegment, size - 1); + curSegment = space.getNextOpenSegment(endAddr); + } + else { + curSegment += 1; + } } reader.setPointerIndex(oldIndex); diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/WindowsHeader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/WindowsHeader.java index a66f040597..825de14d0f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/WindowsHeader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/ne/WindowsHeader.java @@ -1,6 +1,5 @@ /* ### * IP: GHIDRA - * REVIEWED: YES * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -16,9 +15,11 @@ */ package ghidra.app.util.bin.format.ne; -import ghidra.app.util.bin.format.*; import java.io.IOException; +import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; +import ghidra.program.model.address.SegmentedAddress; + /** * A class to represent and parse the * Windows new-style executable (NE) header. @@ -39,20 +40,22 @@ public class WindowsHeader { private NonResidentNameTable nonResNameTable; /** - * Constructor - * @param reader the binary reader - * @param index the index where the windows headers begins - * @throws InvalidWindowsHeaderException if the bytes defined in the binary reader at - * the specified index do not constitute a valid windows header. - */ - public WindowsHeader(FactoryBundledWithBinaryReader reader, short index) throws InvalidWindowsHeaderException, IOException { + * Constructor + * @param reader the binary reader + * @param baseAddr the image base address + * @param index the index where the windows headers begins + * @throws InvalidWindowsHeaderException if the bytes defined in the binary reader at + * the specified index do not constitute a valid windows header. + * @throws IOException for problems reading the header bytes + */ + public WindowsHeader(FactoryBundledWithBinaryReader reader, SegmentedAddress baseAddr, + short index) throws InvalidWindowsHeaderException, IOException { this.infoBlock = new InformationBlock(reader, index); short segTableIndex = (short)(infoBlock.getSegmentTableOffset() + index); this.segTable = new SegmentTable(reader, - segTableIndex, - infoBlock.getSegmentCount(), - infoBlock.getSegmentAlignmentShiftCount()); + baseAddr, segTableIndex, infoBlock.getSegmentCount(), + infoBlock.getSegmentAlignmentShiftCount()); //if resource table offset == resident name table offset, then //we do not have any resources... diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java index fc5c915258..59e648fabb 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/NeLoader.java @@ -51,6 +51,7 @@ public class NeLoader extends AbstractLibrarySupportLoader { private static final String TAB = " "; private static final long MIN_BYTE_LENGTH = 4; + private static final int SEGMENT_START = 0x1000; private ArrayList
entryPointList = new ArrayList<>(); private Comparator