mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Let AddressSpace do segment selector assignment in NeLoader
This commit is contained in:
parent
017537be35
commit
b0d90cf36f
5 changed files with 60 additions and 35 deletions
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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...
|
||||||
|
|
|
@ -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();
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue