Let AddressSpace do segment selector assignment in NeLoader

This commit is contained in:
caheckman 2019-08-26 10:55:12 -04:00
parent 017537be35
commit b0d90cf36f
5 changed files with 60 additions and 35 deletions

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; package ghidra.app.util.bin.format.ne;
import generic.continues.*; import java.io.IOException;
import ghidra.app.util.bin.*;
import ghidra.app.util.bin.format.*;
import ghidra.app.util.bin.format.mz.*;
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). * A class to manage loading New Executables (NE).
@ -34,17 +34,20 @@ public class NewExecutable {
private WindowsHeader winHeader; private WindowsHeader winHeader;
/** /**
* Constructs a new instance of an new executable. * Constructs a new instance of an new executable.
* @param bp the byte provider * @param factory is the object factory to bundle with the reader
* @throws IOException if an I/O error occurs. * @param bp the byte provider
*/ * @param baseAddr the image base of the executable
public NewExecutable(GenericFactory factory, ByteProvider bp) throws IOException { * @throws IOException if an I/O error occurs.
*/
public NewExecutable(GenericFactory factory, ByteProvider bp, SegmentedAddress baseAddr)
throws IOException {
reader = new FactoryBundledWithBinaryReader(factory, bp, true); reader = new FactoryBundledWithBinaryReader(factory, bp, true);
dosHeader = DOSHeader.createDOSHeader(reader); dosHeader = DOSHeader.createDOSHeader(reader);
if (dosHeader.isDosSignature()) { if (dosHeader.isDosSignature()) {
try { try {
winHeader = new WindowsHeader(reader, (short)dosHeader.e_lfanew()); winHeader = new WindowsHeader(reader, baseAddr, (short) dosHeader.e_lfanew());
} }
catch (InvalidWindowsHeaderException e) { catch (InvalidWindowsHeaderException e) {
} }

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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 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; import ghidra.util.Conv;
/** /**
@ -28,7 +29,8 @@ import ghidra.util.Conv;
public class SegmentTable { public class SegmentTable {
private Segment [] segments; 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(); long oldIndex = reader.getPointerIndex();
reader.setPointerIndex(Conv.shortToInt(index)); reader.setPointerIndex(Conv.shortToInt(index));
@ -39,14 +41,29 @@ public class SegmentTable {
segments = new Segment[segmentCountInt]; 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) { 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; int size = segments[i].getMinAllocSize() & 0xffff;
if (size == 0) { if (size == 0) {
size = 0x10000; 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); reader.setPointerIndex(oldIndex);

View file

@ -1,6 +1,5 @@
/* ### /* ###
* IP: GHIDRA * IP: GHIDRA
* REVIEWED: YES
* *
* Licensed under the Apache License, Version 2.0 (the "License"); * Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with 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; package ghidra.app.util.bin.format.ne;
import ghidra.app.util.bin.format.*;
import java.io.IOException; import java.io.IOException;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
import ghidra.program.model.address.SegmentedAddress;
/** /**
* A class to represent and parse the * A class to represent and parse the
* Windows new-style executable (NE) header. * Windows new-style executable (NE) header.
@ -39,20 +40,22 @@ public class WindowsHeader {
private NonResidentNameTable nonResNameTable; private NonResidentNameTable nonResNameTable;
/** /**
* Constructor * Constructor
* @param reader the binary reader * @param reader the binary reader
* @param index the index where the windows headers begins * @param baseAddr the image base address
* @throws InvalidWindowsHeaderException if the bytes defined in the binary reader at * @param index the index where the windows headers begins
* the specified index do not constitute a valid windows header. * @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 { * @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); this.infoBlock = new InformationBlock(reader, index);
short segTableIndex = (short)(infoBlock.getSegmentTableOffset() + index); short segTableIndex = (short)(infoBlock.getSegmentTableOffset() + index);
this.segTable = new SegmentTable(reader, this.segTable = new SegmentTable(reader,
segTableIndex, baseAddr, segTableIndex, infoBlock.getSegmentCount(),
infoBlock.getSegmentCount(), infoBlock.getSegmentAlignmentShiftCount());
infoBlock.getSegmentAlignmentShiftCount());
//if resource table offset == resident name table offset, then //if resource table offset == resident name table offset, then
//we do not have any resources... //we do not have any resources...

View file

@ -51,6 +51,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
private static final String TAB = " "; private static final String TAB = " ";
private static final long MIN_BYTE_LENGTH = 4; private static final long MIN_BYTE_LENGTH = 4;
private static final int SEGMENT_START = 0x1000;
private ArrayList<Address> entryPointList = new ArrayList<>(); private ArrayList<Address> entryPointList = new ArrayList<>();
private Comparator<String> comparator = new CallNameComparator(); private Comparator<String> comparator = new CallNameComparator();
@ -65,7 +66,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
if (provider.length() < MIN_BYTE_LENGTH) { if (provider.length() < MIN_BYTE_LENGTH) {
return loadSpecs; return loadSpecs;
} }
NewExecutable ne = new NewExecutable(RethrowContinuesFactory.INSTANCE, provider); NewExecutable ne = new NewExecutable(RethrowContinuesFactory.INSTANCE, provider, null);
WindowsHeader wh = ne.getWindowsHeader(); WindowsHeader wh = ne.getWindowsHeader();
if (wh != null) { if (wh != null) {
List<QueryResult> results = QueryOpinionService.query(getName(), List<QueryResult> results = QueryOpinionService.query(getName(),
@ -99,7 +100,9 @@ public class NeLoader extends AbstractLibrarySupportLoader {
// the original bytes. // the original bytes.
MemoryBlockUtils.createFileBytes(prog, provider, monitor); MemoryBlockUtils.createFileBytes(prog, provider, monitor);
NewExecutable ne = new NewExecutable(factory, provider); SegmentedAddressSpace space =
(SegmentedAddressSpace) prog.getAddressFactory().getDefaultAddressSpace();
NewExecutable ne = new NewExecutable(factory, provider, space.getAddress(SEGMENT_START, 0));
WindowsHeader wh = ne.getWindowsHeader(); WindowsHeader wh = ne.getWindowsHeader();
InformationBlock ib = wh.getInformationBlock(); InformationBlock ib = wh.getInformationBlock();
SegmentTable st = wh.getSegmentTable(); SegmentTable st = wh.getSegmentTable();
@ -113,8 +116,6 @@ public class NeLoader extends AbstractLibrarySupportLoader {
Listing listing = prog.getListing(); Listing listing = prog.getListing();
SymbolTable symbolTable = prog.getSymbolTable(); SymbolTable symbolTable = prog.getSymbolTable();
Memory memory = prog.getMemory(); Memory memory = prog.getMemory();
SegmentedAddressSpace space =
(SegmentedAddressSpace) prog.getAddressFactory().getDefaultAddressSpace();
ProgramContext context = prog.getProgramContext(); ProgramContext context = prog.getProgramContext();
RelocationTable relocTable = prog.getRelocationTable(); RelocationTable relocTable = prog.getRelocationTable();

View file

@ -69,7 +69,8 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace {
@Override @Override
public int getNextOpenSegment(Address addr) { public int getNextOpenSegment(Address addr) {
int res = getDefaultSegmentFromFlat(addr.getOffset()); int res = getDefaultSegmentFromFlat(addr.getOffset());
res += 1; // Advance the selector by 8, accounting for the descriptor table bit and the privilege level bits
res = (res + 8) & 0xfff8;
return res; return res;
} }
} }