Skip to content

Commit

Permalink
Fixed BinaryExporter's export method
Browse files Browse the repository at this point in the history
  • Loading branch information
astrelsky committed Feb 3, 2020
1 parent dc16f29 commit e2b28b6
Showing 1 changed file with 34 additions and 32 deletions.
Expand Up @@ -21,9 +21,12 @@
import ghidra.app.util.DomainObjectService;
import ghidra.app.util.Option;
import ghidra.framework.model.DomainObject;
import ghidra.program.database.mem.AddressSourceInfo;
import ghidra.program.database.mem.FileBytes;
import ghidra.program.model.address.*;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.*;
import ghidra.program.model.reloc.Relocation;
import ghidra.util.HelpLocation;
import ghidra.util.task.TaskMonitor;

Expand All @@ -39,48 +42,47 @@ public BinaryExporter() {

@Override
public boolean export(File file, DomainObject domainObj, AddressSetView addrSet,
TaskMonitor monitor) throws IOException, ExporterException {
TaskMonitor monitor) throws IOException {

if (!(domainObj instanceof Program)) {
log.appendMsg("Unsupported type: " + domainObj.getClass().getName());
return false;
}
Program program = (Program) domainObj;
final Program program = (Program) domainObj;
final Memory memory = program.getMemory();

Memory memory = program.getMemory();
try (final RandomAccessFile fout = new RandomAccessFile(file, "rw")) {
final List<FileBytes> fileBytes = memory.getAllFileBytes();
if (!fileBytes.isEmpty()) {
final FileBytes fByte = fileBytes.get(0);
long offset = 0;
long size = fByte.getSize();
while (size > Integer.MAX_VALUE) {
final byte[] bytes = new byte[Integer.MAX_VALUE];
fByte.getModifiedBytes(offset, bytes);
fout.write(bytes);
size -= Integer.MAX_VALUE;
offset += Integer.MAX_VALUE;
}
final byte[] bytes = new byte[(int) size];
fByte.getModifiedBytes(offset, bytes);
fout.write(bytes);

if (addrSet == null) {
addrSet = memory;
}

FileOutputStream fos = new FileOutputStream(file);

AddressSet set = new AddressSet(addrSet);

//skip blocks that are not initialized...
MemoryBlock[] blocks = memory.getBlocks();
for (int i = 0; i < blocks.length; ++i) {
if (!blocks[i].isInitialized()) {
set.delete(new AddressRangeImpl(blocks[i].getStart(), blocks[i].getEnd()));
// Now put back the original relocation bytes
final Iterable<Relocation> relocs =
() -> program.getRelocationTable().getRelocations();
for (Relocation reloc : relocs) {
final AddressSourceInfo info = memory.getAddressSourceInfo(reloc.getAddress());
// some relocations report negative offsets
if (info.getFileOffset() >= 0) {
// seek incase the offset is larger than an int
fout.seek(info.getFileOffset());
fout.write(reloc.getBytes());
}
}
}
}

try {
AddressRangeIterator iter = set.getAddressRanges();
while (iter.hasNext()) {
AddressRange range = iter.next();
byte[] mem = new byte[(int) range.getLength()];
int numBytes = memory.getBytes(range.getMinAddress(), mem);
fos.write(mem, 0, numBytes);
}
}
catch (MemoryAccessException e) {
throw new ExporterException(e);
}
finally {
fos.close();
}

return true;
}

Expand Down

0 comments on commit e2b28b6

Please sign in to comment.