mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-22 15:21:18 +00:00
Initial support for Wii/GC DOL binaries
This commit is contained in:
parent
6c278703af
commit
ae3af810a6
@ -128,6 +128,8 @@ static int analop(RAnal *a, RAnalOp *op, ut64 addr, const ut8 *buf, int len) {
|
||||
case PPC_INS_BL:
|
||||
case PPC_INS_BLA:
|
||||
op->type = R_ANAL_OP_TYPE_CALL;
|
||||
op->jump = (ut64)(ut32)insn->detail->ppc.operands[0].imm;
|
||||
op->fail = addr+4;
|
||||
break;
|
||||
case PPC_INS_BLR:
|
||||
case PPC_INS_BLRL:
|
||||
|
@ -11,7 +11,7 @@ ALL_TARGETS=
|
||||
FORMATS=any.mk elf.mk elf64.mk pe.mk pe64.mk te.mk mach0.mk
|
||||
FORMATS+=bios.mk mach064.mk fatmach0.mk dyldcache.mk java.mk
|
||||
FORMATS+=dex.mk fs.mk ningb.mk coff.mk ningba.mk xbe.mk zimg.mk
|
||||
FORMATS+=omf.mk cgc.mk
|
||||
FORMATS+=omf.mk cgc.mk dol.mk
|
||||
include $(FORMATS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
202
libr/bin/p/bin_dol.c
Normal file
202
libr/bin/p/bin_dol.c
Normal file
@ -0,0 +1,202 @@
|
||||
/* radare - LGPL - 2015 - pancake */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_bin.h>
|
||||
#include <string.h>
|
||||
|
||||
#if 0
|
||||
Start End Length Description
|
||||
0x0 0x3 4 File offset to start of Text0
|
||||
0x04 0x1b 24 File offsets for Text1..6
|
||||
0x1c 0x47 44 File offsets for Data0..10
|
||||
0x48 0x4B 4 Loading address for Text0
|
||||
0x4C 0x8F 68 Loading addresses for Text1..6, Data0..10
|
||||
0x90 0xD7 72 Section sizes for Text0..6, Data0..10
|
||||
0xD8 0xDB 4 BSS address
|
||||
0xDC 0xDF 4 BSS size
|
||||
0xE0 0xE3 4 Entry point
|
||||
0xE4 0xFF padding
|
||||
#endif
|
||||
|
||||
#define N_TEXT 7
|
||||
#define N_DATA 11
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
ut32 text_paddr[N_TEXT];
|
||||
ut32 data_paddr[N_DATA];
|
||||
ut32 text_vaddr[N_TEXT];
|
||||
ut32 data_vaddr[N_DATA];
|
||||
ut32 text_size[N_TEXT];
|
||||
ut32 data_size[N_DATA];
|
||||
ut32 bss_addr;
|
||||
ut32 bss_size;
|
||||
ut32 entrypoint;
|
||||
ut32 padding[10];
|
||||
// 0x100 -- start of data section
|
||||
} DolHeader;
|
||||
|
||||
static int check(RBinFile *arch);
|
||||
static int check_bytes(const ut8 *buf, ut64 length);
|
||||
|
||||
static int check(RBinFile *arch) {
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
return check_bytes (bytes, sz);
|
||||
}
|
||||
|
||||
static int check_bytes(const ut8 *buf, ut64 length) {
|
||||
if (!buf || length < 6) return false;
|
||||
return (!memcmp (buf, "\x00\x00\x01\x00\x00\x00", 6));
|
||||
}
|
||||
|
||||
static void * load_bytes(RBinFile *arch, const ut8 *buf, ut64 sz, ut64 loadaddr, Sdb *sdb) {
|
||||
bool has_dol_extension = false;
|
||||
DolHeader * dol = R_NEW0 (DolHeader);
|
||||
char *lowername, *ext;
|
||||
lowername = strdup (arch->file);
|
||||
if (sz < sizeof (DolHeader))
|
||||
return NULL;
|
||||
r_str_case (lowername, 0);
|
||||
ext = strstr (lowername, ".dol");
|
||||
if (ext && ext[4] == 0) {
|
||||
has_dol_extension = true;
|
||||
}
|
||||
free (lowername);
|
||||
if (has_dol_extension) {
|
||||
r_buf_fread_at (arch->buf, 0, (void*)dol, "67I", 1);
|
||||
//r_buf_fread_at (arch->buf, 0, (void*)dol, "67i", 1);
|
||||
if (arch && arch->o && arch->o->bin_obj) {
|
||||
arch->o->bin_obj = dol;
|
||||
}
|
||||
return (void*)dol;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int load(RBinFile *arch) {
|
||||
const ut8 *bytes = arch ? r_buf_buffer (arch->buf) : NULL;
|
||||
ut64 sz = arch ? r_buf_size (arch->buf): 0;
|
||||
if (!arch || !arch->o)
|
||||
return false;
|
||||
arch->o->bin_obj = load_bytes (arch, bytes,
|
||||
sz, arch->o->loadaddr, arch->sdb);
|
||||
return check_bytes (bytes, sz);
|
||||
}
|
||||
|
||||
static RList* sections(RBinFile *arch) {
|
||||
int i;
|
||||
RList *ret;
|
||||
RBinSection *s;
|
||||
DolHeader *dol;
|
||||
if (!arch || !arch->o || !arch->o->bin_obj)
|
||||
return NULL;
|
||||
dol = arch->o->bin_obj;
|
||||
if (!(ret = r_list_new ())) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* text sections */
|
||||
for (i=0; i<N_TEXT; i++) {
|
||||
if (!dol->text_paddr[i] || !dol->text_vaddr[i])
|
||||
continue;
|
||||
s = R_NEW0 (RBinSection);
|
||||
snprintf (s->name, sizeof (s->name), "text_%d", i);
|
||||
s->paddr = dol->text_paddr[i];
|
||||
s->vaddr = dol->text_vaddr[i];
|
||||
s->size = dol->text_size[i];
|
||||
s->vsize = s->size;
|
||||
s->srwx = r_str_rwx ("mr-x");
|
||||
r_list_append (ret, s);
|
||||
}
|
||||
/* data sections */
|
||||
for (i=0; i<N_DATA; i++) {
|
||||
if (!dol->data_paddr[i] || !dol->data_vaddr[i])
|
||||
continue;
|
||||
s = R_NEW0 (RBinSection);
|
||||
snprintf (s->name, sizeof (s->name), "data_%d", i);
|
||||
s->paddr = dol->data_paddr[i];
|
||||
s->vaddr = dol->data_vaddr[i];
|
||||
s->size = dol->data_size[i];
|
||||
s->vsize = s->size;
|
||||
s->srwx = r_str_rwx ("mr--");
|
||||
r_list_append (ret, s);
|
||||
}
|
||||
/* bss section */
|
||||
s = R_NEW0 (RBinSection);
|
||||
strcpy (s->name, "bss");
|
||||
s->paddr = 0;
|
||||
s->vaddr = dol->bss_addr;
|
||||
s->size = dol->bss_size;
|
||||
s->vsize = s->size;
|
||||
s->srwx = r_str_rwx ("-rw-");
|
||||
r_list_append (ret, s);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList* entries(RBinFile *arch) {
|
||||
RList *ret;
|
||||
RBinAddr *addr;
|
||||
DolHeader *dol;
|
||||
if (!arch || !arch->o || !arch->o->bin_obj) {
|
||||
return NULL;
|
||||
}
|
||||
ret = r_list_new ();
|
||||
addr = R_NEW0 (RBinAddr);
|
||||
dol = arch->o->bin_obj;
|
||||
addr->vaddr = (ut64)dol->entrypoint;
|
||||
addr->paddr = addr->vaddr & 0xFFFF;
|
||||
r_list_append (ret, addr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RBinInfo* info(RBinFile *arch) {
|
||||
RBinInfo *ret = R_NEW0 (RBinInfo);
|
||||
if (!ret) return NULL;
|
||||
|
||||
if (!arch || !arch->buf) {
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
ret->file = strdup (arch->file);
|
||||
ret->big_endian = true;
|
||||
ret->type = strdup ("ROM");
|
||||
ret->machine = strdup ("Nintendo Wii");
|
||||
ret->os = strdup ("wii-ios");
|
||||
ret->arch = strdup ("ppc");
|
||||
ret->has_va = true;
|
||||
ret->bits = 32;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ut64 baddr(RBinFile *arch) {
|
||||
return 0x80b00000; // XXX
|
||||
}
|
||||
|
||||
struct r_bin_plugin_t r_bin_plugin_dol = {
|
||||
.name = "dol",
|
||||
.desc = "Nintendo Dolphin binary format",
|
||||
.license = "BSD",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.get_sdb = NULL,
|
||||
.load = &load,
|
||||
.check = &check,
|
||||
.baddr = &baddr,
|
||||
.check_bytes = &check_bytes,
|
||||
.entries = &entries,
|
||||
.sections = §ions,
|
||||
.info = &info,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_dol,
|
||||
.version = R2_VERSION
|
||||
};
|
||||
#endif
|
||||
|
10
libr/bin/p/dol.mk
Normal file
10
libr/bin/p/dol.mk
Normal file
@ -0,0 +1,10 @@
|
||||
OBJ_DOLPHIN=bin_dol.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_DOLPHIN}
|
||||
TARGET_DOLPHIN=bin_dol.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_DOLPHIN}
|
||||
|
||||
${TARGET_DOLPHIN}: ${OBJ_DOLPHIN}
|
||||
${CC} $(call libname,bin_dol) ${CFLAGS} $(OBJ_DOLPHIN) $(LINK) $(LDFLAGS) \
|
||||
-L../../magic -lr_magic
|
@ -270,7 +270,7 @@ typedef struct r_bin_section_t {
|
||||
ut64 vsize;
|
||||
ut64 vaddr;
|
||||
ut64 paddr;
|
||||
ut64 srwx;
|
||||
ut32 srwx;
|
||||
// per section platform info
|
||||
const char *arch;
|
||||
int bits;
|
||||
@ -539,6 +539,7 @@ extern RBinXtrPlugin r_bin_xtr_plugin_dyldcache;
|
||||
extern RBinPlugin r_bin_plugin_zimg;
|
||||
extern RBinPlugin r_bin_plugin_omf;
|
||||
extern RBinPlugin r_bin_plugin_art;
|
||||
extern RBinPlugin r_bin_plugin_dol;
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
@ -94,6 +94,7 @@ bin.bios
|
||||
bin.cgc
|
||||
bin.coff
|
||||
bin.dex
|
||||
bin.dol
|
||||
bin.elf
|
||||
bin.elf64
|
||||
bin.fs
|
||||
|
Loading…
x
Reference in New Issue
Block a user