mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-24 13:21:22 +08:00
Merge branch 'GP-2521_ryanmkurtz_PR-4570_ryanmkurtz_NeFileBytes'
This commit is contained in:
@@ -224,25 +224,4 @@ public class Segment {
|
||||
public SegmentRelocation [] getRelocations() {
|
||||
return relocations;
|
||||
}
|
||||
/**
|
||||
* Returns the bytes the comprise this segment.
|
||||
* The size of the byte array is MAX(length,minalloc).
|
||||
* @return the bytes the comprise this segment
|
||||
*/
|
||||
public byte [] getBytes() throws IOException {
|
||||
int offset_int = getOffsetShiftAligned();
|
||||
int length_int = Conv.shortToInt(getLength());
|
||||
int minalloc_int = Conv.shortToInt(getMinAllocSize());
|
||||
|
||||
if (minalloc_int == 0) minalloc_int = 0x10000;
|
||||
|
||||
byte [] bytes = reader.readByteArray(offset_int, length_int);
|
||||
|
||||
if (length_int >= minalloc_int) {
|
||||
return bytes;
|
||||
}
|
||||
byte [] newbytes = new byte[minalloc_int];
|
||||
System.arraycopy(bytes, 0, newbytes, 0, length_int);
|
||||
return newbytes;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,9 @@ import ghidra.app.util.bin.ByteProvider;
|
||||
import ghidra.app.util.bin.format.ne.*;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.framework.options.Options;
|
||||
import ghidra.framework.store.LockException;
|
||||
import ghidra.program.database.function.OverlappingFunctionException;
|
||||
import ghidra.program.database.mem.FileBytes;
|
||||
import ghidra.program.model.address.*;
|
||||
import ghidra.program.model.data.ByteDataType;
|
||||
import ghidra.program.model.data.StringDataType;
|
||||
@@ -91,11 +93,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
|
||||
initVars();
|
||||
|
||||
// We don't use the file bytes to create block because the bytes are manipulated before
|
||||
// forming the block. Creating the FileBytes anyway in case later we want access to all
|
||||
// the original bytes.
|
||||
MemoryBlockUtils.createFileBytes(prog, provider, monitor);
|
||||
|
||||
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(prog, provider, monitor);
|
||||
SegmentedAddressSpace space =
|
||||
(SegmentedAddressSpace) prog.getAddressFactory().getDefaultAddressSpace();
|
||||
NewExecutable ne = new NewExecutable(provider, space.getAddress(SEGMENT_START, 0));
|
||||
@@ -119,7 +117,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
return;
|
||||
}
|
||||
monitor.setMessage("Processing segment table...");
|
||||
processSegmentTable(log, ib, st, space, prog, context, monitor);
|
||||
processSegmentTable(log, ib, st, space, prog, context, fileBytes, monitor);
|
||||
if (prog.getMemory().isEmpty()) {
|
||||
Msg.error(this, "Empty memory for " + prog);
|
||||
return;
|
||||
@@ -129,7 +127,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
return;
|
||||
}
|
||||
monitor.setMessage("Processing resource table...");
|
||||
processResourceTable(log, prog, rt, space, monitor);
|
||||
processResourceTable(log, prog, rt, space, fileBytes, monitor);
|
||||
|
||||
if (monitor.isCancelled()) {
|
||||
return;
|
||||
@@ -239,29 +237,48 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
|
||||
private void processSegmentTable(MessageLog log, InformationBlock ib, SegmentTable st,
|
||||
SegmentedAddressSpace space, Program program, ProgramContext context,
|
||||
TaskMonitor monitor) throws IOException {
|
||||
FileBytes fileBytes, TaskMonitor monitor) throws IOException {
|
||||
try {
|
||||
Segment[] segments = st.getSegments();
|
||||
for (int i = 0; i < segments.length; ++i) {
|
||||
String name = (segments[i].isCode() ? "Code" : "Data") + (i + 1);
|
||||
byte[] bytes = segments[i].getBytes();
|
||||
Address addr = space.getAddress(segments[i].getSegmentID(), 0);
|
||||
boolean r = true;
|
||||
boolean w = segments[i].isData() && !segments[i].isReadOnly();
|
||||
boolean x = segments[i].isCode();
|
||||
|
||||
if (bytes.length > 0) {
|
||||
MemoryBlockUtils.createInitializedBlock(program, false, name, addr,
|
||||
new ByteArrayInputStream(bytes), bytes.length, "", "", r, w, x, log,
|
||||
monitor);
|
||||
int offset = segments[i].getOffsetShiftAligned();
|
||||
int length = Short.toUnsignedInt(segments[i].getLength());
|
||||
int minalloc = Short.toUnsignedInt(segments[i].getMinAllocSize());
|
||||
if (minalloc == 0) {
|
||||
minalloc = 0x10000;
|
||||
}
|
||||
MemoryBlock block;
|
||||
if (length > 0) {
|
||||
block = MemoryBlockUtils.createInitializedBlock(program, false,
|
||||
name, addr, fileBytes, offset, length, "", "", r, w, x, log);
|
||||
if (length < minalloc) {
|
||||
// Things actually rely on the block being padded out with real 0's, so we
|
||||
// must expand it
|
||||
byte[] zeros = new byte[minalloc - length];
|
||||
MemoryBlock zeroBlock = MemoryBlockUtils.createInitializedBlock(program,
|
||||
false, name, addr.add(length), new ByteArrayInputStream(zeros),
|
||||
zeros.length, "", "", r, w, x, log, monitor);
|
||||
try {
|
||||
block = program.getMemory().join(block, zeroBlock); // expand
|
||||
}
|
||||
catch (MemoryBlockException | LockException | NotFoundException e) {
|
||||
throw new IOException(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
MemoryBlockUtils.createUninitializedBlock(program, false, name, addr,
|
||||
bytes.length, "", "", r, w, x, log);
|
||||
block = MemoryBlockUtils.createUninitializedBlock(program, false, name, addr,
|
||||
minalloc, "", "", r, w, x, log);
|
||||
}
|
||||
|
||||
if (segments[i].is32bit()) {
|
||||
Address end = addr.add(bytes.length - 1);
|
||||
Address end = block.getEnd();
|
||||
|
||||
Register opsizeRegister = context.getRegister("opsize");
|
||||
Register addrsizeRegister = context.getRegister("addrsize");
|
||||
@@ -314,7 +331,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
}
|
||||
|
||||
private void processResourceTable(MessageLog log, Program program, ResourceTable rt,
|
||||
SegmentedAddressSpace space, TaskMonitor monitor) throws IOException {
|
||||
SegmentedAddressSpace space, FileBytes fileBytes, TaskMonitor monitor) {
|
||||
Listing listing = program.getListing();
|
||||
|
||||
if (rt == null) {
|
||||
@@ -332,12 +349,12 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
Address addr = space.getAddress(segidx, 0);
|
||||
|
||||
try {
|
||||
byte[] bytes = resource.getBytes();
|
||||
|
||||
if (bytes != null && bytes.length > 0) {
|
||||
int offset = resource.getFileOffsetShifted();
|
||||
int length = resource.getFileLengthShifted();
|
||||
if (length > 0) {
|
||||
MemoryBlockUtils.createInitializedBlock(program, false, "Rsrc" + (id++),
|
||||
addr, new ByteArrayInputStream(bytes), bytes.length, "", "", true,
|
||||
false, false, log, monitor);
|
||||
addr, fileBytes, offset, length, "", "", true,
|
||||
false, false, log);
|
||||
}
|
||||
}
|
||||
catch (AddressOverflowException e) {
|
||||
@@ -383,7 +400,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
listing.createData(straddr, new ByteDataType(), 1);
|
||||
straddr = straddr.addNoWrap(1);
|
||||
listing.createData(straddr, new StringDataType(),
|
||||
Conv.byteToInt(string.getLength()));
|
||||
Byte.toUnsignedInt(string.getLength()));
|
||||
}
|
||||
catch (AddressOverflowException | CodeUnitInsertionException e) {
|
||||
log.appendMsg("Error creating data");
|
||||
@@ -514,7 +531,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
if (segmentIdx > 0) {
|
||||
int segment = st.getSegments()[segmentIdx - 1].getSegmentID();
|
||||
short offset = ib.getEntryPointOffset();
|
||||
Address entryAddr = space.getAddress(segment, Conv.shortToInt(offset));
|
||||
Address entryAddr = space.getAddress(segment, Short.toUnsignedInt(offset));
|
||||
symbolTable.addExternalEntryPoint(entryAddr);
|
||||
try {
|
||||
symbolTable.createLabel(entryAddr, "entry", SourceType.IMPORTED);
|
||||
@@ -529,7 +546,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
EntryTableBundle[] bundles = et.getBundles();
|
||||
for (EntryTableBundle bundle : bundles) {
|
||||
if (bundle.getType() == EntryTableBundle.UNUSED) {
|
||||
int count = Conv.byteToInt(bundle.getCount());
|
||||
int count = Byte.toUnsignedInt(bundle.getCount());
|
||||
for (int i = 0; i < count; ++i) {
|
||||
entryPointList.add(null);
|
||||
}
|
||||
@@ -553,7 +570,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
else {
|
||||
seg = st.getSegments()[bundle.getType() - 1].getSegmentID();
|
||||
}
|
||||
int off = Conv.shortToInt(pt.getOffset());
|
||||
int off = Short.toUnsignedInt(pt.getOffset());
|
||||
Address addr = space.getAddress(seg, off);
|
||||
symbolTable.addExternalEntryPoint(addr);
|
||||
|
||||
@@ -580,7 +597,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
Symbol symbol = symbols.get(0);
|
||||
if (symbol.getSymbolType() == SymbolType.FUNCTION && symbol.isExternal()) {
|
||||
Function func = (Function) symbol.getObject();
|
||||
Address[] thunkAddresses = func.getFunctionThunkAddresses();
|
||||
Address[] thunkAddresses = func.getFunctionThunkAddresses(false);
|
||||
if (thunkAddresses != null && thunkAddresses.length != 0) {
|
||||
return (SegmentedAddress) thunkAddresses[0];
|
||||
}
|
||||
@@ -604,7 +621,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
}
|
||||
|
||||
int segment = st.getSegments()[s].getSegmentID();
|
||||
int offset = Conv.shortToInt(reloc.getOffset());
|
||||
int offset = Short.toUnsignedInt(reloc.getOffset());
|
||||
SegmentedAddress relocAddr = null;
|
||||
|
||||
if (reloc.isInternalRef()) {
|
||||
@@ -613,7 +630,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
}
|
||||
else {
|
||||
int seg = st.getSegments()[reloc.getTargetSegment() - 1].getSegmentID();
|
||||
int off = Conv.shortToInt(reloc.getTargetOffset());
|
||||
int off = Short.toUnsignedInt(reloc.getTargetOffset());
|
||||
relocAddr = space.getAddress(seg, off);
|
||||
}
|
||||
}
|
||||
@@ -624,7 +641,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
}
|
||||
else if (reloc.isImportOrdinal()) {
|
||||
String modname = getRelocationModuleName(mrt, reloc);
|
||||
int ordinal = Conv.shortToInt(reloc.getTargetOffset());
|
||||
int ordinal = Short.toUnsignedInt(reloc.getTargetOffset());
|
||||
String procname = SymbolUtilities.ORDINAL_PREFIX + ordinal;
|
||||
relocAddr = getImportSymbolByName(symbolTable, modname, procname);
|
||||
}
|
||||
@@ -732,7 +749,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
return imp.getNameAt(reloc.getTargetOffset()).getString();
|
||||
}
|
||||
else if (reloc.isImportOrdinal()) {
|
||||
int ordinal = Conv.shortToInt(reloc.getTargetOffset());
|
||||
int ordinal = Short.toUnsignedInt(reloc.getTargetOffset());
|
||||
return SymbolUtilities.ORDINAL_PREFIX + ordinal;
|
||||
}
|
||||
return null;
|
||||
@@ -774,7 +791,7 @@ public class NeLoader extends AbstractLibrarySupportLoader {
|
||||
private void createSymbols(LengthStringOrdinalSet[] lengthStringOrdinalSets,
|
||||
SymbolTable symbolTable) {
|
||||
for (LengthStringOrdinalSet lengthStringOrdinalSet : lengthStringOrdinalSets) {
|
||||
int ordinal = Conv.shortToInt(lengthStringOrdinalSet.getOrdinal());
|
||||
int ordinal = Short.toUnsignedInt(lengthStringOrdinalSet.getOrdinal());
|
||||
if (ordinal >= entryPointList.size()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user