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 # 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...`. Once the extension is installed, you can import a .rpx/.rpl file via `File->Import File...`.

View File

@ -49,3 +49,17 @@ else {
jar { jar {
duplicatesStrategy 'exclude' 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@ name=@extname@
description=Simple extension to open Wii U binaries (.rpx/.rpl) description=Simple extension to open Wii U binaries (.rpx/.rpl)
author= Maschell author= Maschell
createdOn= 11/10/2019 createdOn= 12/11/2022
version=@extversion@ version=@extversion@

View File

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

View File

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

View File

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

View File

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