ghidra.app.util.MemoryBlockUtils Java Examples

The following examples show how to use ghidra.app.util.MemoryBlockUtils. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: ApploaderProgramBuilder.java    From Ghidra-GameCube-Loader with Apache License 2.0 6 votes vote down vote up
protected void load(ByteProvider provider)
		throws AddressOutOfBoundsException {
	this.baseAddress = 0x80000000L;
	this.addressSpace = program.getAddressFactory().getDefaultAddressSpace();
	
	try {
		this.program.setImageBase(addressSpace.getAddress(this.baseAddress), true);
		
		// Create Apploader section.
		MemoryBlockUtils.createInitializedBlock(this.program, false, "Apploader", addressSpace.getAddress(0x81200000), provider.getInputStream(ApploaderHeader.HEADER_SIZE),
				header.GetSize(), "", null, true, true, true, null, monitor);
		
		// Create trailer section.
		MemoryBlockUtils.createInitializedBlock(this.program, false, "Trailer", addressSpace.getAddress(0x81200000 + header.GetSize()),
				provider.getInputStream(ApploaderHeader.HEADER_SIZE + header.GetSize()), header.GetTrailerSize(), "", null, true, true, true, null, monitor);
	}
	catch (Exception e) {
		e.printStackTrace();
	}
}
 
Example #2
Source File: MachoLoader.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Override
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
		Program program, TaskMonitor monitor, MessageLog log) throws IOException {

	try {
		FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);

		// A Mach-O file may contain PRELINK information.  If so, we use a special
		// program builder that knows how to deal with it.
		List<PrelinkMap> prelinkList = MachoPrelinkUtils.parsePrelinkXml(provider, monitor);
		if (!prelinkList.isEmpty()) {
			MachoPrelinkProgramBuilder.buildProgram(program, provider, fileBytes, prelinkList,
				log, monitor);
		}
		else {
			MachoProgramBuilder.buildProgram(program, provider, fileBytes, log, monitor);
		}
	}
	catch (Exception e) {
		throw new IOException(e.getMessage());
	}
}
 
Example #3
Source File: ElfProgramBuilder.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Override
protected MemoryBlock createUninitializedBlock(MemoryLoadable loadable, boolean isOverlay,
		String name, Address start, long dataLength, String comment, boolean r, boolean w,
		boolean x) throws IOException, AddressOverflowException, CancelledException {

	// TODO: MemoryBlockUtil poorly and inconsistently handles duplicate name errors (can throw RuntimeException).
	// Are we immune from such errors? If not, how should they be handled?

	long revisedLength = checkBlockLimit(name, dataLength, false);

	if (start.isNonLoadedMemoryAddress()) {
		r = false;
		w = false;
		x = false;
	}

	if (dataLength != revisedLength) {
		comment += " (section truncated)";
	}

	return MemoryBlockUtils.createUninitializedBlock(program, isOverlay, name, start,
		revisedLength, comment, BLOCK_SOURCE_NAME, r, w, x, log);
}
 
Example #4
Source File: MemoryBlockHelper.java    From Ghidra-Switch-Loader with ISC License 5 votes vote down vote up
public void addSection(String name, long addressOffset, long offset, long length, boolean read, boolean write, boolean execute)
{
    try
    {
        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)
    {
        Msg.error(this, "Failed to add section " + name, e);
    }
    
    this.flushLog();
}
 
Example #5
Source File: SystemMemorySections.java    From Ghidra-GameCube-Loader with Apache License 2.0 5 votes vote down vote up
public static void Create(Program program) {
	var addressSpace = program.getAddressFactory().getDefaultAddressSpace();
	
	// Create globals section first
	MemoryBlockUtils.createUninitializedBlock(program, false, "OS Globals", addressSpace.getAddress(0x80000000), 0x3100, "Operating System Globals", null, true, true, false, null);
	
	// Now create hardware registers
	var cp = MemoryBlockUtils.createUninitializedBlock(program, false, "CP", addressSpace.getAddress(0xCC000000), 0x80, "Command Processor Register", null, true, true, false, null);
	cp.setVolatile(true);

	var pe = MemoryBlockUtils.createUninitializedBlock(program, false, "PE", addressSpace.getAddress(0xCC001000), 0x100, "Pixel Engine Register", null, true, true, false, null);
	pe.setVolatile(true);
	
	var vi = MemoryBlockUtils.createUninitializedBlock(program, false, "VI", addressSpace.getAddress(0xCC002000), 0x100, "Video Interface Register", null, true, true, false, null);
	vi.setVolatile(true);
	
	var pi = MemoryBlockUtils.createUninitializedBlock(program, false, "PI", addressSpace.getAddress(0xCC003000), 0x100, "Processor Interface Register", null, true, true, false, null);
	pi.setVolatile(true);
	
	var mi = MemoryBlockUtils.createUninitializedBlock(program, false, "MI", addressSpace.getAddress(0xCC004000), 0x80, "Memory Interface Register", null, true, true, false, null);
	mi.setVolatile(true);
	
	var dsp = MemoryBlockUtils.createUninitializedBlock(program, false, "DSP", addressSpace.getAddress(0xCC005000), 0x200, "Digital Signal Processor Register", null, true, true, false, null);
	dsp.setVolatile(true);
	
	var di = MemoryBlockUtils.createUninitializedBlock(program, false, "DI", addressSpace.getAddress(0xCC006000), 0x40, "DVD Interface Reigster", null, true, true, false, null);
	di.setVolatile(true);
	
	var si = MemoryBlockUtils.createUninitializedBlock(program, false, "SI", addressSpace.getAddress(0xCC006400), 0x100, "Serial Interface Reigster", null, true, true, false, null);
	si.setVolatile(true);
	
	var exi = MemoryBlockUtils.createUninitializedBlock(program, false, "EXI", addressSpace.getAddress(0xCC006800), 0x40, "External Interface Reigster", null, true, true, false, null);
	exi.setVolatile(true);
	
	var ai = MemoryBlockUtils.createUninitializedBlock(program, false, "AI", addressSpace.getAddress(0xCC006C00), 0x40, "Audio Interface Reigster", null, true, true, false, null);
	ai.setVolatile(true);
	
	var gxfifo = MemoryBlockUtils.createUninitializedBlock(program, false, "GXFIFO", addressSpace.getAddress(0xCC008000), 0x8, "Graphics FIFO Reigster", null, true, true, false, null);
	gxfifo.setVolatile(true);
}
 
Example #6
Source File: CoffLoader.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private MemoryBlock createInitializedBlock(ByteProvider provider, Program program,
		FileBytes fileBytes, TaskMonitor monitor, MessageLog log, final Language language,
		int sectionNumber, CoffSectionHeader section, final int sectionSize,
		Address sectionAddr, boolean isOverlay) throws AddressOverflowException, IOException {

	String name = section.getName();
	if (isOverlay) {
		name += "-" + sectionNumber;
	}
	MemoryBlock block = null;
	try {
		if (section.isProcessedBytes(language)) {
			try (InputStream dataStream = section.getRawDataStream(provider, language)) {
				block = MemoryBlockUtils.createInitializedBlock(program, isOverlay, name,
					sectionAddr, dataStream, sectionSize,
					"PhysAddr:0x" + Integer.toHexString(section.getPhysicalAddress()) + " " +
						"Size:0x" + Integer.toHexString(sectionSize) + " " + "Flags:0x" +
						Integer.toHexString(section.getFlags()),
					null/*source*/, section.isReadable(), section.isWritable(),
					section.isExecutable(), log, monitor);
			}
		}
		else {
			block = MemoryBlockUtils.createInitializedBlock(program, isOverlay, name,
				sectionAddr, fileBytes, section.getPointerToRawData(), sectionSize,
				"PhysAddr:0x" + Integer.toHexString(section.getPhysicalAddress()) + " " +
					"Size:0x" + Integer.toHexString(sectionSize) + " " + "Flags:0x" +
					Integer.toHexString(section.getFlags()),
				null/*source*/, section.isReadable(), section.isWritable(),
				section.isExecutable(), log);
		}
	}
	catch (RuntimeException e) {
		log.appendMsg(
			"Unable to create non-loaded block " + section + ". No memory block was created.");
		log.appendException(e);
	}
	return block;
}
 
Example #7
Source File: CoffLoader.java    From ghidra with Apache License 2.0 5 votes vote down vote up
@Override
protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
		Program program, TaskMonitor monitor, MessageLog log)
		throws IOException, CancelledException {

	boolean performFakeLinking = performFakeLinking(options);

	CoffFileHeader header = new CoffFileHeader(provider);
	header.parse(provider, monitor);

	Map<CoffSectionHeader, Address> sectionsMap = new HashMap<>();
	Map<CoffSymbol, Symbol> symbolsMap = new HashMap<>();

	FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, monitor);

	int id = program.startTransaction("loading program from COFF");
	boolean success = false;
	try {
		processSectionHeaders(provider, header, program, fileBytes, monitor, log, sectionsMap,
			performFakeLinking);
		processSymbols(header, program, monitor, log, sectionsMap, symbolsMap);
		processEntryPoint(header, program, monitor, log);
		processRelocations(header, program, sectionsMap, symbolsMap, log, monitor);
		success = true;
	}
	catch (AddressOverflowException e) {
		throw new IOException(e);
	}
	finally {
		program.endTransaction(id, success);
	}
}
 
Example #8
Source File: MergeTwoProgramsScript.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void mergeMemory( Program currProgram, Program otherProgram ) throws Exception {
	monitor.setMessage( "Merging memory..." );
	Memory otherMemory = otherProgram.getMemory();
	MemoryBlock[] otherBlocks = otherMemory.getBlocks();
	MessageLog log = new MessageLog();
	for (MemoryBlock otherBlock : otherBlocks) {
		if (monitor.isCancelled()) {
			break;
		}
		if (otherBlock.getType() != MemoryBlockType.DEFAULT) {
			printerr("Unhandled memory block type: " + otherBlock.getName());
			continue;
		}
		if (otherBlock.isInitialized()) {
			MemoryBlockUtils.createInitializedBlock(currProgram, false, otherBlock.getName(),
				otherBlock.getStart(), otherBlock.getData(), otherBlock.getSize(),
				otherBlock.getComment(), otherBlock.getSourceName(), otherBlock.isRead(),
				otherBlock.isWrite(), otherBlock.isExecute(), log, monitor);
		}
		else {
			MemoryBlockUtils.createUninitializedBlock(currProgram, false, otherBlock.getName(),
				otherBlock.getStart(), otherBlock.getSize(), otherBlock.getComment(),
				otherBlock.getSourceName(), otherBlock.isRead(), otherBlock.isWrite(),
				otherBlock.isExecute(), log);
		}
	}
}
 
Example #9
Source File: MIPS_ElfRelocationHandler.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Flush the section GOT table to a new %got memory block
 */
private void createGot() {
	if (lastSectionGotEntryAddress == null) {
		return;
	}
	int size = (int) lastSectionGotEntryAddress.subtract(sectionGotAddress) + 1;
	String sectionName = relocationTable.getSectionToBeRelocated().getNameAsString();
	String blockName = getSectionGotName();
	try {
		MemoryBlock block = MemoryBlockUtils.createInitializedBlock(program, false,
			blockName, sectionGotAddress, size, "GOT for " + sectionName + " section",
			"MIPS-Elf Loader", true, false, false, loadHelper.getLog());
		DataConverter converter =
			program.getMemory().isBigEndian() ? BigEndianDataConverter.INSTANCE
					: LittleEndianDataConverter.INSTANCE;
		for (long symbolValue : gotMap.keySet()) {
			Address addr = gotMap.get(symbolValue);
			byte[] bytes;
			if (program.getDefaultPointerSize() == 4) {
				bytes = converter.getBytes((int) symbolValue);
			}
			else {
				bytes = converter.getBytes(symbolValue);
			}
			block.putBytes(addr, bytes);
			loadHelper.createData(addr, PointerDataType.dataType);
		}
	}
	catch (MemoryAccessException e) {
		throw new AssertException(e); // unexpected
	}
}
 
Example #10
Source File: PefLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private void processSections(ContainerHeader header, Program program, FileBytes fileBytes,
		ImportStateCache importState, MessageLog log, TaskMonitor monitor)
		throws AddressOverflowException, IOException {

	List<SectionHeader> sections = header.getSections();
	for (SectionHeader section : sections) {
		if (monitor.isCancelled()) {
			return;
		}

		Address start = getSectionAddressAligned(section, program);

		monitor.setMessage("Creating section at 0x" + start + "...");

		if (!section.getSectionKind().isInstantiated()) {
			continue;
		}

		if (section.getSectionKind() == SectionKind.PackedData) {
			byte[] unpackedData = section.getUnpackedData(monitor);
			ByteArrayInputStream is = new ByteArrayInputStream(unpackedData);
			MemoryBlockUtils.createInitializedBlock(program, false, section.getName(), start,
				is, unpackedData.length, section.getSectionKind().toString(), null,
				section.isRead(), section.isWrite(), section.isExecute(), log, monitor);
		}
		else {
			MemoryBlockUtils.createInitializedBlock(program, false, section.getName(), start,
				fileBytes, section.getContainerOffset(), section.getUnpackedLength(),
				section.getSectionKind().toString(), null, section.isRead(), section.isWrite(),
				section.isExecute(), log);
		}

		importState.setMemoryBlockForSection(section, program.getMemory().getBlock(start));

		if (section.getUnpackedLength() < section.getTotalLength()) {
			start = start.add(section.getUnpackedLength());

			MemoryBlockUtils.createUninitializedBlock(program, false, section.getName(), start,
				section.getTotalLength() - section.getUnpackedLength(),
				section.getSectionKind().toString(), null, section.isRead(), section.isWrite(),
				section.isExecute(), log);
		}
	}
}
 
Example #11
Source File: ElfProgramBuilder.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
protected MemoryBlock createInitializedBlock(MemoryLoadable loadable, boolean isOverlay,
		String name, Address start, long fileOffset, long dataLength, String comment, boolean r,
		boolean w, boolean x, TaskMonitor monitor)
		throws IOException, AddressOverflowException, CancelledException {

	// TODO: MemoryBlockUtil poorly and inconsistently handles duplicate name errors (can throw RuntimeException).
	// Are we immune from such errors? If not, how should they be handled?

	long revisedLength = checkBlockLimit(name, dataLength, true);

	if (start.isNonLoadedMemoryAddress()) {
		r = false;
		w = false;
		x = false;
	}

	Msg.debug(this,
		"Loading block " + name + " at " + start + " from file offset " + fileOffset);

	long endOffset = fileOffset + revisedLength - 1;
	if (endOffset >= fileBytes.getSize()) {
		revisedLength = fileBytes.getSize() - fileOffset;
		log("Truncating block load for " + name + " which exceeds file length");
	}

	String blockComment = comment;
	if (dataLength != revisedLength) {
		blockComment += " (section truncated)";
	}

	if (elf.getLoadAdapter().hasFilteredLoadInputStream(this, loadable, start)) {
		// block is unable to map directly to file bytes - load from input stream
		try (InputStream dataInput =
			getInitializedBlockInputStream(loadable, start, fileOffset, revisedLength)) {
			return MemoryBlockUtils.createInitializedBlock(program, isOverlay, name, start,
				dataInput, revisedLength, blockComment, BLOCK_SOURCE_NAME, r, w, x, log,
				monitor);
		}
	}

	// create block using direct mapping to file bytes
	return MemoryBlockUtils.createInitializedBlock(program, isOverlay, name, start, fileBytes,
		fileOffset, revisedLength, blockComment, BLOCK_SOURCE_NAME, r, w, x, log);
}
 
Example #12
Source File: CoffLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private void processSectionHeaders(ByteProvider provider, CoffFileHeader header,
		Program program, FileBytes fileBytes, TaskMonitor monitor, MessageLog log,
		Map<CoffSectionHeader, Address> map, boolean performFakeLinking)
		throws AddressOverflowException, IOException {

	monitor.setMessage("Process sections...");

	final Language language = program.getLanguage();

	List<CoffSectionHeader> sections = header.getSections();

	if (performFakeLinking) {
		possiblyRelocateSections(program, header, map);
	}

	int sectionNumber = 0;
	for (CoffSectionHeader section : sections) {
		++sectionNumber;
		if (monitor.isCancelled()) {
			break;
		}

		MemoryBlock block = null;

		final int sectionSize = section.getSize(language);

		Address sectionAddr = section.getPhysicalAddress(language);

		if (sectionSize == 0 || section.getFlags() == 0) {
			log.appendMsg("Empty Section, Created Symbol: " + section.getName());
			// don't create a block, but record the section to get at the address!
			block = program.getMemory().getBlock(sectionAddr);
			try {
				program.getSymbolTable().createLabel(sectionAddr, section.getName(),
					SourceType.IMPORTED);
				// TODO: sectionSize somewhere for case where flags==0 ?
			}
			catch (InvalidInputException e) {
				// unexpected
			}
		}
		else if (!section.isAllocated()) {
			block = createInitializedBlock(provider, program, fileBytes, monitor, log, language,
				sectionNumber, section, sectionSize, sectionAddr, true);
			if (block != null) {
				log.appendMsg("Created Overlay Block: " + section + " @ " + sectionAddr);
			}
		}
		else if (section.isUninitializedData()) {
			block = MemoryBlockUtils.createUninitializedBlock(program, false, section.getName(),
				sectionAddr, sectionSize,
				"PhysAddr:0x" + Integer.toHexString(section.getPhysicalAddress()) + " " +
					"Size:0x" + Integer.toHexString(sectionSize) + " " + "Flags:0x" +
					Integer.toHexString(section.getFlags()),
				null/*source*/, section.isReadable(), section.isWritable(),
				section.isExecutable(), log);
			if (block != null) {
				log.appendMsg("Created Uninitialized Block: " + section + " @ " + sectionAddr);
			}
		}
		else {
			block = createInitializedBlock(provider, program, fileBytes, monitor, log, language,
				sectionNumber, section, sectionSize, sectionAddr, false);
			if (block != null) {
				log.appendMsg("Created Initialized Block: " + section + " @ " + sectionAddr);
			}
		}

		if (block != null) {
			sectionAddr = block.getStart();
		}
		map.put(section, sectionAddr);
	}
}
 
Example #13
Source File: NeLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program prog,
		TaskMonitor monitor, MessageLog log) throws IOException, CancelledException {

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing new executable...");

	initVars();

	ContinuesFactory factory = MessageLogContinuesFactory.create(log);

	// 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);

	SegmentedAddressSpace space =
		(SegmentedAddressSpace) prog.getAddressFactory().getDefaultAddressSpace();
	NewExecutable ne = new NewExecutable(factory, provider, space.getAddress(SEGMENT_START, 0));
	WindowsHeader wh = ne.getWindowsHeader();
	InformationBlock ib = wh.getInformationBlock();
	SegmentTable st = wh.getSegmentTable();
	ResourceTable rt = wh.getResourceTable();
	EntryTable et = wh.getEntryTable();
	ResidentNameTable rnt = wh.getResidentNameTable();
	NonResidentNameTable nrnt = wh.getNonResidentNameTable();
	ImportedNameTable imp = wh.getImportedNameTable();
	ModuleReferenceTable mrt = wh.getModuleReferenceTable();

	Listing listing = prog.getListing();
	SymbolTable symbolTable = prog.getSymbolTable();
	Memory memory = prog.getMemory();
	ProgramContext context = prog.getProgramContext();
	RelocationTable relocTable = prog.getRelocationTable();

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing segment table...");
	processSegmentTable(log, ib, st, space, prog, context, monitor);
	if (prog.getMemory().isEmpty()) {
		Msg.error(this, "Empty memory for " + prog);
		return;
	}

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing resource table...");
	processResourceTable(log, prog, rt, space, monitor);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing module reference table...");
	processModuleReferenceTable(mrt, st, imp, prog, space, log, monitor);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing entry table...");
	processEntryTable(st, ib, et, symbolTable, space);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing non-resident name table...");
	processNonResidentNameTable(nrnt, symbolTable);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing resident name table...");
	processResidentNameTable(rnt, symbolTable);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing segment relocations...");
	processRelocations(st, imp, mrt, relocTable, prog, memory, space, log, monitor);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing information block...");
	processInformationBlock(ib, nrnt, memory, listing);

	processProperties(ib, prog, monitor);

}
 
Example #14
Source File: PrelinkFileSystem.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public Program getProgram(GFile file, LanguageService languageService, TaskMonitor monitor,
		Object consumer) throws Exception {
	Long offset = fileToMachoOffsetMap.get(file);
	if (offset == null) {
		return null;
	}
	MachHeader machHeader =
		MachHeader.createMachHeader(RethrowContinuesFactory.INSTANCE, provider, offset, true);
	LanguageCompilerSpecPair lcs = MacosxLanguageHelper.getLanguageCompilerSpecPair(
		languageService, machHeader.getCpuType(), machHeader.getCpuSubType());
	Program program =
		new ProgramDB(file.getName(), lcs.getLanguage(), lcs.getCompilerSpec(), consumer);
	int id = program.startTransaction(getName());
	boolean success = false;
	try {
		FileBytes fileBytes = MemoryBlockUtils.createFileBytes(program, provider, offset,
			provider.length() - offset, monitor);
		ByteProvider providerWrapper =
			new ByteProviderWrapper(provider, offset, provider.length() - offset);
		MachoProgramBuilder.buildProgram(program, providerWrapper, fileBytes, new MessageLog(),
			monitor);
		program.setExecutableFormat(MachoLoader.MACH_O_NAME);
		program.setExecutablePath(file.getPath());

		if (file.equals(systemKextFile)) {
			processSystemKext(languageService, program, monitor);
		}

		success = true;
	}
	catch (Exception e) {
		throw e;
	}
	finally {
		program.endTransaction(id, success);
		if (!success) {
			program.release(consumer);
		}
	}
	return program;
}
 
Example #15
Source File: MzLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program prog,
		TaskMonitor monitor, MessageLog log) throws IOException, CancelledException {

	FileBytes fileBytes = MemoryBlockUtils.createFileBytes(prog, provider, monitor);
	AddressFactory af = prog.getAddressFactory();
	if (!(af.getDefaultAddressSpace() instanceof SegmentedAddressSpace)) {
		throw new IOException("Selected Language must have a segmented address space.");
	}

	SegmentedAddressSpace space = (SegmentedAddressSpace) af.getDefaultAddressSpace();
	SymbolTable symbolTable = prog.getSymbolTable();
	ProgramContext context = prog.getProgramContext();
	Memory memory = prog.getMemory();

	ContinuesFactory factory = MessageLogContinuesFactory.create(log);
	OldStyleExecutable ose = new OldStyleExecutable(factory, provider);
	DOSHeader dos = ose.getDOSHeader();
	FactoryBundledWithBinaryReader reader = ose.getBinaryReader();

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing segments...");
	processSegments(prog, fileBytes, space, reader, dos, log, monitor);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Adjusting segments...");
	adjustSegmentStarts(prog);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing relocations...");
	doRelocations(prog, reader, dos);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Processing symbols...");
	createSymbols(space, symbolTable, dos);

	if (monitor.isCancelled()) {
		return;
	}
	monitor.setMessage("Setting registers...");

	Symbol entrySymbol =
		SymbolUtilities.getLabelOrFunctionSymbol(prog, ENTRY_NAME, err -> log.error("MZ", err));
	setRegisters(context, entrySymbol, memory.getBlocks(), dos);

}
 
Example #16
Source File: OmfLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
protected void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,
		Program program, TaskMonitor monitor, MessageLog log)
		throws IOException, CancelledException {

	OmfFileHeader header = null;
	BinaryReader reader = OmfFileHeader.createReader(provider);
	try {
		header = OmfFileHeader.parse(reader, monitor);
		header.resolveNames();
		header.sortSegmentDataBlocks();
		OmfFileHeader.doLinking(IMAGE_BASE, header.getSegments(), header.getGroups());
	}
	catch (OmfException ex) {
		if (header == null) {
			throw new IOException("OMF File header was corrupted");
		}
		log.appendMsg("File was corrupted - leaving partial program " + provider.getName());
	}

	// 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(program, provider, monitor);

	int id = program.startTransaction("loading program from OMF");
	boolean success = false;
	try {
		processSegmentHeaders(reader, header, program, monitor, log);
		processExternalSymbols(header, program, monitor, log);
		processPublicSymbols(header, program, monitor, log);
		processRelocations(header, program, monitor, log);
		success = true;
	}
	catch (AddressOverflowException e) {
		throw new IOException(e);
	}
	finally {
		program.endTransaction(id, success);
	}
}
 
Example #17
Source File: OmfLoader.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
	 * Run through the OMF segments an produce Ghidra memory blocks.
	 * Most segments cause an initialized block to be created, but if a segment
	 * consists only of a string of zero bytes, as described by a compact LIDATA record,
	 * an uninitialized block is created.
	 * @param reader is a reader for the underlying file
	 * @param header is the OMF file header
	 * @param program is the Program
	 * @param mbu is the block creation utility
	 * @param monitor is checked for cancellation
	 * @param log receives error messages
	 * @throws AddressOverflowException if the underlying data stream causes an address to wrap
	 * @throws IOException for problems accessing the OMF file through the reader
	 */
	private void processSegmentHeaders(BinaryReader reader, OmfFileHeader header, Program program,
			TaskMonitor monitor, MessageLog log) throws AddressOverflowException, IOException {
		monitor.setMessage("Process segments...");

		final Language language = program.getLanguage();

		ArrayList<OmfSegmentHeader> segments = header.getSegments();
//		int sectionNumber = 0;
		for (OmfSegmentHeader segment : segments) {
//			++sectionNumber;
			if (monitor.isCancelled()) {
				break;
			}

			//		if (segment.hasIteratedData() && segment.hasEnumeratedData())
			//			throw new IOException("OMF segment has both iterated and enumerated data blocks");
			MemoryBlock block = null;

			final long segmentSize = segment.getSegmentLength();

			Address segmentAddr = segment.getAddress(language);

			if (segmentSize == 0) {
				// don't create a block...just log that we've seen the segment
				block = program.getMemory().getBlock(segmentAddr);
				log.appendMsg("Empty Segment: " + segment.getName());
			}
			else if (segment.hasNonZeroData()) {
				block = MemoryBlockUtils.createInitializedBlock(program, false, segment.getName(),
					segmentAddr, segment.getRawDataStream(reader, log), segmentSize,
					"Address:0x" + Long.toHexString(segmentAddr.getOffset()) + " " + "Size:0x" +
						Long.toHexString(segmentSize),
					null/*source*/, segment.isReadable(), segment.isWritable(),
					segment.isExecutable(), log, monitor);
				if (block != null) {
					log.appendMsg(
						"Created Initialized Block: " + segment.getName() + " @ " + segmentAddr);
				}
			}
			else {
				block = MemoryBlockUtils.createUninitializedBlock(program, false, segment.getName(),
					segmentAddr, segmentSize,
					"Address:0x" + Long.toHexString(segmentAddr.getOffset()) + " " + "Size:0x" +
						Long.toHexString(segmentSize),
					null/*source*/, segment.isReadable(), segment.isWritable(),
					segment.isExecutable(), log);
				if (block != null) {
					log.appendMsg(
						"Created Uninitialized Block: " + segment.getName() + " @ " + segmentAddr);
				}
			}
		}
	}
 
Example #18
Source File: NXProgramBuilder.java    From Ghidra-Switch-Loader with ISC License 4 votes vote down vote up
public void load(TaskMonitor monitor)
{
    NXOAdapter adapter = this.nxo.getAdapter();
    ByteProvider memoryProvider = adapter.getMemoryProvider();
    this.aSpace = program.getAddressFactory().getDefaultAddressSpace();
    
    try 
    {
        this.memBlockHelper = new MemoryBlockHelper(monitor, this.program, memoryProvider);
        
        NXOSection text = adapter.getSection(NXOSectionType.TEXT);
        NXOSection rodata = adapter.getSection(NXOSectionType.RODATA);
        NXOSection data = adapter.getSection(NXOSectionType.DATA);
        
        if (adapter.getDynamicSize() == 0)
        {
            // We can't create .dynamic, so work with what we've got.
            return;
        }
        
        this.memBlockHelper.addSection(".dynamic", adapter.getDynamicOffset(), adapter.getDynamicOffset(), adapter.getDynamicSize(), true, true, false);

        // Create dynamic sections
        this.tryCreateDynBlock(".dynstr", ElfDynamicType.DT_STRTAB, ElfDynamicType.DT_STRSZ);
        this.tryCreateDynBlock(".init_array", ElfDynamicType.DT_INIT_ARRAY, ElfDynamicType.DT_INIT_ARRAYSZ);
        this.tryCreateDynBlock(".fini_array", ElfDynamicType.DT_FINI_ARRAY, ElfDynamicType.DT_FINI_ARRAYSZ);
        this.tryCreateDynBlock(".rela.dyn", ElfDynamicType.DT_RELA, ElfDynamicType.DT_RELASZ);
        this.tryCreateDynBlock(".rel.dyn", ElfDynamicType.DT_REL, ElfDynamicType.DT_RELSZ);
        
        if (adapter.isAarch32())
        {
            this.tryCreateDynBlock(".rel.plt", ElfDynamicType.DT_JMPREL, ElfDynamicType.DT_PLTRELSZ);
        }
        else
        {
            this.tryCreateDynBlock(".rela.plt", ElfDynamicType.DT_JMPREL, ElfDynamicType.DT_PLTRELSZ);
        }

        this.tryCreateDynBlockWithRange(".hash", ElfDynamicType.DT_HASH, ElfDynamicType.DT_GNU_HASH);
        this.tryCreateDynBlockWithRange(".gnu.hash", ElfDynamicType.DT_GNU_HASH, ElfDynamicType.DT_SYMTAB);
        
        if (adapter.getSymbolTable(this.program) != null)
        {
            Msg.info(this, String.format("String table offset %X, base addr %X", adapter.getSymbolTable(this.program).getFileOffset(), this.nxo.getBaseAddress()));
            this.memBlockHelper.addSection(".dynsym", adapter.getSymbolTable(this.program).getFileOffset() - this.nxo.getBaseAddress(), adapter.getSymbolTable(this.program).getFileOffset() - this.nxo.getBaseAddress(), adapter.getSymbolTable(this.program).getLength(), true, false, false);
        }
        
        this.setupRelocations();
        this.createGlobalOffsetTable();
        
        this.memBlockHelper.addFillerSection(".text", text.getOffset(), text.getSize(), true, false, true);
        this.memBlockHelper.addFillerSection(".rodata", rodata.getOffset(), rodata.getSize(), true, false, false);
        this.memBlockHelper.addFillerSection(".data", data.getOffset(), data.getSize(), true, true, false);
        
        this.setupStringTable();
        this.setupSymbolTable();
        
        // Create BSS. This needs to be done before the EXTERNAL block is created in setupImports
        Address bssStartAddr = aSpace.getAddress(this.nxo.getBaseAddress() + adapter.getBssOffset());
        Msg.info(this, String.format("Created bss from 0x%X to 0x%X", bssStartAddr.getOffset(), bssStartAddr.getOffset() + adapter.getBssSize()));
        MemoryBlockUtils.createUninitializedBlock(this.program, false, ".bss", bssStartAddr, adapter.getBssSize(), "", null, true, true, false, new MessageLog());
        
        this.setupImports(monitor);
        this.performRelocations();
        
        // Set all data in the GOT to the pointer data type
        // NOTE: Currently the got range may be null in e.g. old libnx nros
        // We may want to manually figure this out ourselves in future.
        if (adapter.getGotSize() > 0)
        {
            for (Address addr = this.aSpace.getAddress(adapter.getGotOffset()); addr.compareTo(this.aSpace.getAddress(adapter.getGotOffset() + adapter.getGotSize())) < 0; addr = addr.add(adapter.getOffsetSize()))
            {
                this.createPointer(addr);
            }
        }
    }
    catch (IOException | NotFoundException | AddressOverflowException | AddressOutOfBoundsException | CodeUnitInsertionException | DataTypeConflictException | MemoryAccessException | InvalidInputException e)
    {
        e.printStackTrace();
    }
    
    // Ensure memory blocks are ordered from first to last.
    // Normally they are ordered by the order they are added.
    UIUtil.sortProgramTree(this.program);
}