Add Ghidra 10.2.1 support

This commit is contained in:
Maschell 2022-11-12 14:04:14 +01:00
parent 39fd646f53
commit fc59d1cfb9
7 changed files with 38 additions and 35 deletions

View File

@ -12,7 +12,7 @@ The loader will fallback to the default PowerPC processor if the Gekko/Broadway
# Usage
Install the extension using the `Install Extensions` option inside Ghidra or extract the .zip manually into `[GHIDRA_ROOT]\Ghidra\Extensions`. Make sure to restart the program after installing.
Install the extension using the `Install Extensions` option inside Ghidra.
Once the extension is installed, you can import a .rpx/.rpl file via `File->Import File...`.

View File

@ -49,3 +49,17 @@ else {
jar {
duplicatesStrategy 'exclude'
}
repositories {
// Declare dependency repositories here. This is not needed if dependencies are manually
// dropped into the lib/ directory.
// See https://docs.gradle.org/current/userguide/declaring_repositories.html for more info.
// Ex: mavenCentral()
}
dependencies {
// Any external dependencies added here will automatically be copied to the lib/ directory when
// this extension is built.
}
// Exclude additional files from the built extension
// Ex: buildExtension.exclude '.idea/**'

View File

@ -1,5 +1,5 @@
name=@extname@
description=Simple extension to open Wii U binaries (.rpx/.rpl)
author= Maschell
createdOn= 11/10/2019
createdOn= 12/11/2022
version=@extversion@

View File

@ -2,13 +2,12 @@ package cafeloader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.function.Consumer;
import java.util.zip.DataFormatException;
import java.util.zip.Inflater;
import generic.continues.RethrowContinuesFactory;
import ghidra.app.util.bin.BinaryReader;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
import ghidra.app.util.bin.format.elf.ElfConstants;
import ghidra.app.util.bin.format.elf.ElfException;
import ghidra.app.util.bin.format.elf.ElfSectionHeader;
@ -28,10 +27,10 @@ public class RplConverter {
public static final byte ELFOSABI_CAFE = (byte) 0xCA;
public static final byte ELFOSABI_VERSION_CAFE = (byte) 0xFE;
public static byte[] convertRpl(ByteProvider byteProvider, TaskMonitor monitor)
public static byte[] convertRpl(ByteProvider byteProvider, Consumer<String> errorConsumer)
throws ElfException, IOException, DataFormatException {
// Read elf header
RplHeader elfHeader = RplHeader.createRplHeader(RethrowContinuesFactory.INSTANCE, byteProvider);
RplHeader elfHeader = new RplHeader(byteProvider, errorConsumer);
BinaryReader reader = elfHeader.getReader();
// Write elf header
@ -55,18 +54,18 @@ public class RplConverter {
out.write(dc.getBytes((short) 0)); // phentsize
out.write(dc.getBytes((short) 0)); // phnum
out.write(dc.getBytes(elfHeader.e_shentsize()));
out.write(dc.getBytes(elfHeader.e_shnum()));
out.write(dc.getBytes(elfHeader.e_shstrndx()));
out.write(dc.getBytes((short)elfHeader.getSectionHeaderCount()));
out.write(dc.getBytes((short)elfHeader.e_shstrndx()));
out.write(new byte[0x40 - 0x34]); // padding until section headers
// Read sections
long sectionDataOffset = elfHeader.e_shoff() + (elfHeader.e_shnum() * elfHeader.e_shentsize());
long sectionDataOffset = elfHeader.e_shoff() + ((long) elfHeader.getSectionHeaderCount() * elfHeader.e_shentsize());
ByteArrayOutputStream sectionData = new ByteArrayOutputStream();
for (int i = 0; i < elfHeader.e_shnum(); ++i) {
long index = elfHeader.e_shoff() + (i * elfHeader.e_shentsize());
for (int i = 0; i < elfHeader.getSectionHeaderCount(); ++i) {
long index = elfHeader.e_shoff() + ((long) i * elfHeader.e_shentsize());
reader.setPointerIndex(index);
ElfSectionHeader sectionHeader = RplSectionHeader.createElfSectionHeader((FactoryBundledWithBinaryReader) reader, elfHeader);
ElfSectionHeader sectionHeader = new RplSectionHeader(reader, elfHeader);
long size = sectionHeader.getSize();
reader.setPointerIndex(sectionHeader.getOffset());

View File

@ -1,19 +1,16 @@
package cafeloader;
import java.lang.Throwable;
import java.util.function.Consumer;
import generic.continues.GenericFactory;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.format.elf.ElfException;
import ghidra.app.util.bin.format.elf.ElfHeader;
public class RplHeader extends ElfHeader
{
public static RplHeader createRplHeader(GenericFactory factory, ByteProvider provider)
throws ElfException {
RplHeader elfHeader = (RplHeader) factory.create(RplHeader.class);
elfHeader.initElfHeader(factory, provider);
return elfHeader;
public RplHeader(ByteProvider provider, Consumer<String> errorConsumer) throws ElfException {
super(provider, errorConsumer);
}
@Override

View File

@ -2,11 +2,10 @@ package ghidra.app.util.bin.format.elf;
import java.io.IOException;
import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader;
import ghidra.app.util.bin.BinaryReader;
public class RplSectionHeader extends ElfSectionHeader {
public static ElfSectionHeader createElfSectionHeader(FactoryBundledWithBinaryReader reader,
ElfHeader header) throws IOException {
return ElfSectionHeader.createElfSectionHeader(reader, header);
public RplSectionHeader(BinaryReader reader, ElfHeader header) throws IOException {
super(reader, header);
}
}

View File

@ -9,13 +9,12 @@ import java.util.Collection;
import java.util.List;
import java.util.zip.DataFormatException;
import generic.continues.GenericFactory;
import ghidra.app.util.Option;
import ghidra.app.util.bin.ByteArrayProvider;
import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.format.elf.ElfException;
import ghidra.app.util.bin.format.elf.ElfHeader;
import ghidra.app.util.importer.MessageLog;
import ghidra.app.util.importer.MessageLogContinuesFactory;
import ghidra.program.model.lang.LanguageCompilerSpecPair;
import ghidra.program.model.listing.Program;
import ghidra.util.exception.CancelledException;
@ -70,18 +69,13 @@ public class CafeLoader extends ElfLoader {
@Override
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program program,
TaskMonitor monitor, MessageLog log) throws IOException {
TaskMonitor monitor, MessageLog log) throws IOException, CancelledException {
try {
GenericFactory factory = MessageLogContinuesFactory.create(log);
byte[] data = RplConverter.convertRpl(provider, monitor);
RplHeader rpl = RplHeader.createRplHeader(factory, new ByteArrayProvider(data));
byte[] data = RplConverter.convertRpl(provider, log::appendMsg);
RplHeader rpl = new RplHeader(new ByteArrayProvider(data), log::appendMsg);
ElfProgramBuilder.loadElf(rpl, program, options, log, monitor);
} catch (ElfException e) {
throw new IOException(e.getMessage());
} catch (CancelledException e) {
throw new IOException(e.getMessage());
} catch (DataFormatException e) {
throw new IOException(e.getMessage());
} catch (ElfException | DataFormatException var8) {
throw new IOException(var8.getMessage());
}
}
}