Skip to content

Commit

Permalink
Minor improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
yetmorecode committed Dec 14, 2021
1 parent f785360 commit 2dd83ff
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 29 deletions.
42 changes: 19 additions & 23 deletions src/main/java/yetmorecode/ghidra/LxLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,9 @@ private void createImageMappings(LxExecutable executable, Program program, ByteP
program.getSymbolTable().createLabel(b.getStart(), "IMAGE_LE_HEADER", SourceType.ANALYSIS);
log(CHECK + "Mapped LX Header Section");

// LE loader section

if (loaderOptions.mapExtra) {
// LE loader section
addr = b.getStart().add(header.objectTableOffset);
monitor.setMessage(String.format(ARROW + "Mapping LX Loader section"));
createData(
Expand All @@ -202,9 +203,7 @@ private void createImageMappings(LxExecutable executable, Program program, ByteP
);
program.getSymbolTable().createLabel(addr, "IMAGE_LE_LOADER", SourceType.ANALYSIS);
log(CHECK + "Mapped LX Loader Section");
}

if (loaderOptions.mapExtra) {

// LE fixup section
var dm = program.getDataTypeManager();
var cat = dm.createCategory(new CategoryPath("/_le/_fixup"));
Expand All @@ -215,7 +214,8 @@ private void createImageMappings(LxExecutable executable, Program program, ByteP
header.dataPagesOffset - dosHeader.e_lfanew() - header.fixupPageTableOffset,
loaderOptions,
cat,
program
program,
b
);
createData(program, addr, ft);
program.getSymbolTable().createLabel(addr, "IMAGE_LE_FIXUP", SourceType.ANALYSIS);
Expand Down Expand Up @@ -277,11 +277,10 @@ private Data createData(Program program, Address address, DataType dt) {
return null;
}

private byte[] createObjectBlock(Program program, LxExecutable le, ObjectTableEntry object, boolean isLastObject) throws IOException, UsrException {
private byte[] createObjectBlock(Program program, LxExecutable le, ObjectTableEntry object, boolean isLastObject) throws IOException {
var header = le.getLeHeader();
var pageMapOffset = le.getDosHeader().e_lfanew() + header.pageTableOffset;
var pageSize = header.pageSize;
var space = program.getAddressFactory().getDefaultAddressSpace();

// Temporary memory to assemble all pages to one block
byte block[] = new byte[object.size+4096];
Expand All @@ -299,15 +298,6 @@ private byte[] createObjectBlock(Program program, LxExecutable le, ObjectTableEn

PageMapEntry entry = new PageMapEntry(le.getReader(), pageMapOffset + (index-1) * 4);
var pageOffset = header.dataPagesOffset + (entry.getIndex()-1)*pageSize;

// Create a label for each page
if (loaderOptions.createPageLabels) {
program.getSymbolTable().createLabel(
space.getAddress(loaderOptions.getBaseAddress(object) + blockIndex),
"LE_PAGE_" + index,
SourceType.ANALYSIS
);
}

// Read page from file
FactoryBundledWithBinaryReader r = le.getReader();
Expand Down Expand Up @@ -486,11 +476,16 @@ private void createEntrypoint(LxExecutable exe, Program program, TaskMonitor mon
addr = unit.getAddress();
}

var to = s.getAddress(loaderOptions.getBaseAddress(f.objectNumber) + f.targetOffset);
program.getReferenceManager().removeAllReferencesFrom(addr);
var ref = new MemReferenceImpl(addr, to, RefType.JUMP_OVERRIDE_UNCONDITIONAL, SourceType.ANALYSIS, 0, true);
program.getReferenceManager().addReference(ref);

if (loaderOptions.fixupEnabled(f) && f.is1616PointerFixup()) {
// 16:16 pointer fixups are weird since they involve segment selectors
// and Ghidra only knows DOS segmented memory (no protected mode segmentation),
// so we remove the old ref and place on calculated by ourself
var to = s.getAddress(loaderOptions.getBaseAddress(f.objectNumber) + f.targetOffset);
program.getReferenceManager().removeAllReferencesFrom(addr);
var ref = new MemReferenceImpl(addr, to, RefType.JUMP_OVERRIDE_UNCONDITIONAL, SourceType.ANALYSIS, 0, true);
program.getReferenceManager().addReference(ref);
}

if (loaderOptions.createFixupLabels) {
program.getListing().setComment(
addr,
Expand All @@ -503,11 +498,12 @@ private void createEntrypoint(LxExecutable exe, Program program, TaskMonitor mon
}
}
}


// Create a label for each page
if (loaderOptions.createPageLabels) {
for (var i = 1; i <= exe.header.pageCount; i++) {
var addr = s.getAddress(header.dataPagesOffset - dosHeader.e_lfanew()).add((i-1)*header.pageSize);
program.getSymbolTable().createLabel(addr, "IMAGE_LE_DATA", SourceType.ANALYSIS);
program.getSymbolTable().createLabel(addr, "LE_PAGE_" + i, SourceType.ANALYSIS);
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ public class LoaderOptions {
// Default options
public boolean disassembleEntry = true;
public boolean addEntry = true;
public boolean mapExtra = true;
public boolean mapExtra = false;
public boolean[] enableType = new boolean[9];

// More options available through "loader options"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,14 @@
import ghidra.program.model.data.Category;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.util.exception.UsrException;
import yetmorecode.ghidra.format.lx.LoaderOptions;
import yetmorecode.ghidra.format.lx.model.LxExecutable;

public class FixupSectionType extends StructureDataType {

public FixupSectionType(LxExecutable executable, int end, LoaderOptions options, Category cat, Program program) throws UsrException, IOException {
public FixupSectionType(LxExecutable executable, int end, LoaderOptions options, Category cat, Program program, MemoryBlock b) throws UsrException, IOException {
super("IMAGE_LE_FIXUP", 0);

var h = executable.header;
Expand All @@ -29,7 +30,7 @@ public FixupSectionType(LxExecutable executable, int end, LoaderOptions options,
for (var object : executable.getObjects()) {
if (executable.objectHasFixups(object)) {
add(
new ObjectFixupsType(executable, object, options, cat, program),
new ObjectFixupsType(executable, object, options, cat, program, b),
"fixups_object" + object.number,
"Fixup records for object #" + object.number
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,32 @@

import java.io.IOException;

import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.data.Category;
import ghidra.program.model.data.CategoryPath;
import ghidra.program.model.data.StructureDataType;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.symbol.MemReferenceImpl;
import ghidra.program.model.symbol.RefType;
import ghidra.program.model.symbol.SourceType;
import ghidra.util.exception.UsrException;
import yetmorecode.ghidra.format.lx.LoaderOptions;
import yetmorecode.ghidra.format.lx.model.LxExecutable;
import yetmorecode.ghidra.format.lx.model.ObjectTableEntry;

public class ObjectFixupsType extends StructureDataType {

public ObjectFixupsType(LxExecutable executable, ObjectTableEntry object, LoaderOptions options, Category cat, Program program) throws UsrException, IOException {
public ObjectFixupsType(LxExecutable executable, ObjectTableEntry object, LoaderOptions options, Category cat, Program program, MemoryBlock b) throws UsrException, IOException {
super(String.format("%08x_%d", options.getBaseAddress(object), object.number), 0);
setCategoryPath(cat.getCategoryPath());

// Iterate over all object pages
for (int i = 0; i < object.pageCount; i++) {
var page = object.pageTableIndex + i;
var pageSize = executable.header.pageSize;

// If page has fixups
if (executable.fixups.get(page).size() > 0) {
var sub = new StructureDataType(String.format("%08x", options.getBaseAddress(object) + i*pageSize), 0);
sub.setCategoryPath(new CategoryPath(
Expand All @@ -29,17 +38,36 @@ public ObjectFixupsType(LxExecutable executable, ObjectTableEntry object, Loader
)
));
add(sub, "page_" + page, "Page #" + page + " fixups");

// Each single fixup
var current = 0;
for (var f : executable.fixups.get(page)) {
// Add datatype
var fixupData = f.toDataType();

fixupData.setCategoryPath(new CategoryPath(
String.format(
"%s/%08x/%08x",
String.format("%s/%08x/%08x",
cat.getCategoryPathName(),
options.getBaseAddress(object) + i*pageSize,
f.getSourceAddress()
)
));
sub.add(fixupData, "fix_" + f.index, "Fixup record #" + f.index);

// Add xref
var to = b.getStart().add(executable.header.dataPagesOffset - executable.getDosHeader().e_lfanew() + (page-1)*pageSize + current);
var space = program.getAddressFactory().getDefaultAddressSpace();
var ref = new MemReferenceImpl(
space.getAddress(f.getSourceAddress()),
to,
RefType.DATA_IND,
SourceType.ANALYSIS,
0,
false
);
program.getReferenceManager().addReference(ref);

current += fixupData.getLength();
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ public int getSourceType() {
public boolean isTargetOffset32Bit() {
return (targetFlags & 0x10) > 0;
}

public boolean is1616PointerFixup() {
return getSourceType() == SOURCE_1616PTR_FIXUP;
}

@Override
public DataType toDataType() throws DuplicateNameException, IOException {
Expand Down

0 comments on commit 2dd83ff

Please sign in to comment.