mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-25 13:42:06 +00:00
Let AddressSpace do segment selector assignment in NeLoader
This commit is contained in:
parent
017537be35
commit
b0d90cf36f
@ -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) {
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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...
|
||||
|
@ -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<Address> entryPointList = new ArrayList<>();
|
||||
private Comparator<String> comparator = new CallNameComparator();
|
||||
@ -65,7 +66,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
if (provider.length() < MIN_BYTE_LENGTH) {
|
||||
return loadSpecs;
|
||||
}
|
||||
NewExecutable ne = new NewExecutable(RethrowContinuesFactory.INSTANCE, provider);
|
||||
NewExecutable ne = new NewExecutable(RethrowContinuesFactory.INSTANCE, provider, null);
|
||||
WindowsHeader wh = ne.getWindowsHeader();
|
||||
if (wh != null) {
|
||||
List<QueryResult> results = QueryOpinionService.query(getName(),
|
||||
@ -99,7 +100,9 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
// the original bytes.
|
||||
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();
|
||||
InformationBlock ib = wh.getInformationBlock();
|
||||
SegmentTable st = wh.getSegmentTable();
|
||||
@ -113,8 +116,6 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
Listing listing = prog.getListing();
|
||||
SymbolTable symbolTable = prog.getSymbolTable();
|
||||
Memory memory = prog.getMemory();
|
||||
SegmentedAddressSpace space =
|
||||
(SegmentedAddressSpace) prog.getAddressFactory().getDefaultAddressSpace();
|
||||
ProgramContext context = prog.getProgramContext();
|
||||
RelocationTable relocTable = prog.getRelocationTable();
|
||||
|
||||
|
@ -69,7 +69,8 @@ public class ProtectedAddressSpace extends SegmentedAddressSpace {
|
||||
@Override
|
||||
public int getNextOpenSegment(Address addr) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user