Skip to content

Commit

Permalink
Initial 9.1 update. Symbols are currently broken for some reason
Browse files Browse the repository at this point in the history
  • Loading branch information
Adubbz committed Sep 28, 2019
1 parent 1ab12ce commit 4eff593
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 148 deletions.
12 changes: 11 additions & 1 deletion src/main/java/adubbz/nx/analyzer/ipc/IPCEmulator.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
import ghidra.pcode.emulate.BreakCallBack;
import ghidra.pcode.emulate.BreakTableCallBack;
import ghidra.pcode.emulate.Emulate;
import ghidra.pcode.error.LowlevelError;
import ghidra.pcode.memstate.MemoryBank;
import ghidra.pcode.memstate.MemoryFaultHandler;
import ghidra.pcode.memstate.MemoryPageBank;
Expand All @@ -38,6 +39,8 @@
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.util.Msg;
import ghidra.util.exception.CancelledException;
import ghidra.util.task.TaskMonitor;
import ghidra.util.task.TaskMonitorAdapter;

public class IPCEmulator
Expand Down Expand Up @@ -327,7 +330,14 @@ public IPCTrace emulateCommand(Address procFuncAddr, int cmd, byte[] data, int b
break;
}

emu.executeInstruction(true);
try
{
emu.executeInstruction(true, TaskMonitor.DUMMY);
}
catch (CancelledException | LowlevelError e)
{
e.printStackTrace();
}
}

return this.currentTrace;
Expand Down
19 changes: 7 additions & 12 deletions src/main/java/adubbz/nx/loader/SwitchLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,18 +12,14 @@
import java.util.Collection;
import java.util.List;

import adubbz.nx.loader.kip1.KIP1Header;
import adubbz.nx.loader.kip1.KIP1ProgramBuilder;
import adubbz.nx.loader.knx.KNXProgramBuilder;
import adubbz.nx.loader.nro0.NRO0Header;
import adubbz.nx.loader.nro0.NRO0ProgramBuilder;
import adubbz.nx.loader.nso0.NSO0Header;
import adubbz.nx.loader.nso0.NSO0ProgramBuilder;
import ghidra.app.util.Option;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.ByteProviderWrapper;
import ghidra.app.util.importer.MemoryConflictHandler;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.opinion.BinaryLoader;
import ghidra.app.util.opinion.LoadSpec;
Expand All @@ -33,7 +29,6 @@
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.lang.CompilerSpec;
import ghidra.program.model.lang.CompilerSpecID;
import ghidra.program.model.lang.Language;
Expand Down Expand Up @@ -106,7 +101,7 @@ protected List<Program> loadProgram(ByteProvider provider, String programName,

try
{
success = this.loadInto(provider, loadSpec, options, log, prog, monitor, MemoryConflictHandler.ALWAYS_OVERWRITE);
success = this.loadInto(provider, loadSpec, options, log, prog, monitor);
}
finally
{
Expand All @@ -124,15 +119,15 @@ protected List<Program> loadProgram(ByteProvider provider, String programName,

@Override
protected boolean loadProgramInto(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
MessageLog messageLog, Program program, TaskMonitor monitor, MemoryConflictHandler memoryConflictHandler)
MessageLog messageLog, Program program, TaskMonitor monitor)
throws IOException
{
var space = program.getAddressFactory().getDefaultAddressSpace();

if (this.binaryType == BinaryType.SX_KIP1)
{
ByteProvider offsetProvider = new ByteProviderWrapper(provider, 0x10, provider.length() - 0x10);
KIP1ProgramBuilder.loadKIP1(offsetProvider, program, memoryConflictHandler, monitor);
KIP1ProgramBuilder.loadKIP1(offsetProvider, program, monitor);
}
else
{
Expand All @@ -149,16 +144,16 @@ protected boolean loadProgramInto(ByteProvider provider, LoadSpec loadSpec, List

if (this.binaryType == BinaryType.KIP1)
{
KIP1ProgramBuilder.loadKIP1(provider, program, memoryConflictHandler, monitor);
KIP1ProgramBuilder.loadKIP1(provider, program, monitor);
}

else if (this.binaryType == BinaryType.NSO0)
{
NSO0ProgramBuilder.loadNSO0(provider, program, memoryConflictHandler, monitor);
NSO0ProgramBuilder.loadNSO0(provider, program, monitor);
}
else if (this.binaryType == BinaryType.NRO0)
{
NRO0ProgramBuilder.loadNRO0(provider, program, memoryConflictHandler, monitor);
NRO0ProgramBuilder.loadNRO0(provider, program, monitor);
}
else if (this.binaryType == BinaryType.KERNEL_800)
{
Expand All @@ -171,7 +166,7 @@ else if (this.binaryType == BinaryType.KERNEL_800)
Msg.error(this, "Failed to set image base");
}

KNXProgramBuilder.loadKNX(provider, program, memoryConflictHandler, monitor);
KNXProgramBuilder.loadKNX(provider, program, monitor);
}
}

Expand Down
149 changes: 69 additions & 80 deletions src/main/java/adubbz/nx/loader/common/MemoryBlockHelper.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,139 +6,128 @@
*/
package adubbz.nx.loader.common;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import adubbz.nx.util.ByteUtil;
import ghidra.app.util.MemoryBlockUtil;
import org.apache.commons.compress.utils.Lists;

import ghidra.app.util.MemoryBlockUtils;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
import ghidra.app.util.bin.format.elf.ElfHeader;
import ghidra.app.util.bin.format.elf.ElfSectionHeader;
import ghidra.app.util.bin.format.elf.ElfStringTable;
import ghidra.app.util.bin.format.elf.ElfSymbolTable;
import ghidra.framework.store.LockException;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOutOfBoundsException;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.model.address.AddressRange;
import ghidra.program.model.address.AddressRangeImpl;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.mem.MemoryBlock;
import ghidra.program.model.mem.MemoryBlockException;
import ghidra.program.model.mem.MemoryConflictException;
import ghidra.util.Msg;
import ghidra.util.exception.DuplicateNameException;
import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;

public class MemoryBlockHelper
{
private TaskMonitor monitor;
private Program program;
private ByteProvider byteProvider;
private MemoryBlockUtil mbu;
private long baseAddress;

private List<String> sectionsToInit = new ArrayList<>();
private MessageLog log;

public MemoryBlockHelper(TaskMonitor monitor, Program program, ByteProvider byteProvider, MemoryBlockUtil mbu, long baseAddress)
public MemoryBlockHelper(TaskMonitor monitor, Program program, ByteProvider byteProvider)
{
this.monitor = monitor;
this.program = program;
this.byteProvider = byteProvider;
this.mbu = mbu;
this.baseAddress = baseAddress;
this.log = new MessageLog();
}

public MemoryBlock addManualDeferredSection(String name, long addressOffset, InputStream dataInput, long dataSize, boolean read, boolean write, boolean execute)
public void addSection(String name, long addressOffset, long offset, long length, boolean read, boolean write, boolean execute)
{
AddressSpace addressSpace = this.program.getAddressFactory().getDefaultAddressSpace();
MemoryBlock mb = null;

try
try
{
mb = this.mbu.createUninitializedBlock(false, name, addressSpace.getAddress(this.baseAddress + addressOffset), dataSize, "", null, read, write, execute);

if (mb == null)
{
Msg.error(this, this.mbu.getMessages());
}
}
catch (AddressOutOfBoundsException e)
FileBytes fileBytes = MemoryBlockUtils.createFileBytes(this.program, this.byteProvider, offset, length, this.monitor);
MemoryBlockUtils.createInitializedBlock(this.program, false, name, this.program.getImageBase().add(addressOffset), fileBytes, 0, length, "", null, read, write, execute, this.log);
}
catch (Exception e)
{
e.printStackTrace();
Msg.error(this, "Failed to add section " + name, e);
}

return mb;
this.flushLog();
}

public void addDeferredSection(String name, long addressOffset, InputStream dataInput, long dataSize, boolean read, boolean write, boolean execute)
private void addUniqueSection(String name, long addressOffset, long offset, long length, boolean read, boolean write, boolean execute)
{
MemoryBlock mb = this.addManualDeferredSection(name, addressOffset, dataInput, dataSize, read, write, execute);
Memory memory = this.program.getMemory();
Address startAddr = this.program.getImageBase().add(addressOffset);
Address endAddr = startAddr.add(length);
String newBlockName = name;
int nameCounter = 0;

if (mb != null)
while (memory.getBlock(newBlockName) != null)
{
this.sectionsToInit.add(mb.getName());
nameCounter++;
newBlockName = name + "." + nameCounter;
}

Msg.info(this, "Adding unique section " + newBlockName + " from " + startAddr.toString() + " to " + endAddr.toString());
this.addSection(newBlockName, offset, offset, length, read, write, execute);
}

public void addSection(String name, long addressOffset, InputStream dataInput, long dataSize, boolean read, boolean write, boolean execute) throws AddressOverflowException, AddressOutOfBoundsException
{
AddressSpace addressSpace = this.program.getAddressFactory().getDefaultAddressSpace();
this.mbu.createInitializedBlock(name, addressSpace.getAddress(this.baseAddress + addressOffset), dataInput, dataSize, "", null, read, write, execute, this.monitor);
}

public void finalizeSection(String name) throws LockException, NotFoundException, MemoryAccessException, IOException
public void addFillerSection(String name, long addressOffset, long length, boolean read, boolean write, boolean execute)
{
Memory memory = this.program.getMemory();
Msg.info(this, "Attempting to manually finalize " + name);
Address startAddr = this.program.getImageBase().add(addressOffset);
Address endAddr = startAddr.add(length);
AddressRange range = new AddressRangeImpl(startAddr, endAddr);

List<MemoryBlock> blocksInRange = Lists.newArrayList();

for (MemoryBlock block : memory.getBlocks())
{
if (block.getName().equals(name))
AddressRange blockRange = new AddressRangeImpl(block.getStart(), block.getEnd());

if (range.intersects(blockRange))
{
Msg.info(this, "Manually finalizing " + name);
memory.convertToInitialized(block, (byte)0);
byte[] data = this.byteProvider.readBytes(block.getStart().getOffset() - this.baseAddress, block.getSize());
block.putBytes(block.getStart(), data);
blocksInRange.add(block);
}
}
}

public void finalizeSections() throws LockException, NotFoundException, MemoryAccessException, IOException
{
Memory memory = this.program.getMemory();

for (MemoryBlock block : memory.getBlocks())
if (blocksInRange.isEmpty())
{
Msg.info(this, "Adding filler section " + name + " from " + startAddr.toString() + " to " + endAddr.toString());
this.addSection(name, addressOffset, addressOffset, range.getLength(), read, write, execute);
return;
}

Address fillerBlockStart = startAddr;
AddressRange fillerBlockRange;

for (MemoryBlock block : blocksInRange)
{
if (this.sectionsToInit.contains(block.getName()))
fillerBlockRange = new AddressRangeImpl(fillerBlockStart, block.getStart());

if (fillerBlockRange.getLength() > 2)
{
memory.convertToInitialized(block, (byte)0);
byte[] data = this.byteProvider.readBytes(block.getStart().getOffset() - this.baseAddress, block.getSize());
block.putBytes(block.getStart(), data);
long offset = fillerBlockRange.getMinAddress().subtract(this.program.getImageBase());
this.addUniqueSection(name, offset, offset, fillerBlockRange.getLength() - 1, read, write, execute);
}

fillerBlockStart = block.getEnd().add(1);
}

fillerBlockRange = new AddressRangeImpl(fillerBlockStart, endAddr);

if (fillerBlockRange.getLength() > 2)
{
long offset = fillerBlockRange.getMinAddress().subtract(this.program.getImageBase());
this.addUniqueSection(name, offset, offset, fillerBlockRange.getLength() - 1, read, write, execute);
}
}

private class DeferredInitSection
public void flushLog()
{
private MemoryBlock block;
private InputStream dataInput;

public DeferredInitSection(MemoryBlock block, InputStream dataInput)
if (this.log.getMsgCount() > 0)
{
this.block = block;
this.dataInput = dataInput;
Msg.info(this, this.log.toString());
this.log.clear();
}
}
}
Loading

0 comments on commit 4eff593

Please sign in to comment.