Rizin
unix-like reverse engineering framework and cli tools
bin_sfc.c File Reference
#include <rz_bin.h>
#include <rz_lib.h>
#include "sfc/sfc_specs.h"
#include <rz_endian.h>

Go to the source code of this file.

Functions

static bool check_buffer (RzBuffer *b)
 
static bool load_buffer (RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb)
 
static RzBinInfoinfo (RzBinFile *bf)
 
static void addrom (RzList *ret, const char *name, int i, ut64 paddr, ut64 vaddr, ut32 size)
 
static RzListsymbols (RzBinFile *bf)
 
static RzListsections (RzBinFile *bf)
 
static RzListmem (RzBinFile *bf)
 
static RzListentries (RzBinFile *bf)
 

Variables

RzBinPlugin rz_bin_plugin_sfc
 
RZ_API RzLibStruct rizin_plugin
 

Function Documentation

◆ addrom()

static void addrom ( RzList ret,
const char *  name,
int  i,
ut64  paddr,
ut64  vaddr,
ut32  size 
)
static

Definition at line 98 of file bin_sfc.c.

98  {
100  if (!ptr) {
101  return;
102  }
103  ptr->name = rz_str_newf("%s_%02x", name, i);
104  ptr->paddr = paddr;
105  ptr->vaddr = vaddr;
106  ptr->size = ptr->vsize = size;
107  ptr->perm = RZ_PERM_RX;
108  rz_list_append(ret, ptr);
109 }
lzma_index ** i
Definition: index.h:629
voidpf void uLong size
Definition: ioapi.h:138
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RX
Definition: rz_types.h:97
Definition: z80asm.h:102
char * name
Definition: rz_bin.h:619

References i, rz_bin_section_t::name, rz_bin_section_t::paddr, rz_bin_section_t::perm, rz_list_append(), RZ_NEW0, RZ_PERM_RX, rz_str_newf(), rz_bin_section_t::size, rz_bin_section_t::vaddr, and rz_bin_section_t::vsize.

Referenced by sections().

◆ check_buffer()

static bool check_buffer ( RzBuffer b)
static

Definition at line 9 of file bin_sfc.c.

9  {
11  // FIXME: this was commented out because it always evaluates to false.
12  // Need to be fixed by someone with SFC knowledge
13  // if ((length & 0x8000) == 0x200) {
14  // buf_hdr += 0x200;
15  // }
16  if (length < 0x8000) {
17  return false;
18  }
19  // determine if ROM is headered, and add a 0x200 gap if so.
20  ut16 cksum1;
21  if (!rz_buf_read_le16_at(b, 0x7fdc, &cksum1)) {
22  return false;
23  }
24 
25  ut16 cksum2;
26  if (!rz_buf_read_le16_at(b, 0x7fde, &cksum2)) {
27  return false;
28  }
29 
30  if (cksum1 == (ut16)~cksum2) {
31  return true;
32  }
33  if (length < 0xffee) {
34  return false;
35  }
36 
37  if (!rz_buf_read_le16_at(b, 0xffdc, &cksum1)) {
38  return false;
39  }
40 
41  if (!rz_buf_read_le16_at(b, 0xffde, &cksum2)) {
42  return false;
43  }
44 
45  return (cksum1 == (ut16)~cksum2);
46 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void length
Definition: sflib.h:133
uint16_t ut16
#define rz_buf_read_le16_at(b, addr, result)
Definition: rz_buf.h:270
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
#define b(i)
Definition: sha256.c:42
ut64(WINAPI *w32_GetEnabledXStateFeatures)()

References b, length, rz_buf_read_le16_at, rz_buf_size(), and ut64().

Referenced by load_buffer().

◆ entries()

static RzList* entries ( RzBinFile bf)
static

Definition at line 271 of file bin_sfc.c.

271  { // Should be 3 offsets pointed by NMI, RESET, IRQ after mapping && default = 1st CHR
272  RzList *ret;
273  if (!(ret = rz_list_new())) {
274  return NULL;
275  }
276  /*
277  RzBinAddr *ptr = NULL;
278  if (!(ptr = RZ_NEW0 (RzBinAddr))) {
279  return ret;
280  }
281  ptr->paddr = INES_HDR_SIZE;
282  ptr->vaddr = ROM_START_ADDRESS;
283  rz_list_append (ret, ptr);
284  */
285  return ret;
286 }
#define NULL
Definition: cris-opc.c:27
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235

References NULL, and rz_list_new().

◆ info()

static RzBinInfo* info ( RzBinFile bf)
static

Definition at line 52 of file bin_sfc.c.

52  {
53  sfc_int_hdr sfchdr = { { 0 } };
54  RzBinInfo *ret = NULL;
55  int hdroffset = 0;
56 #if THIS_IS_ALWAYS_FALSE_WTF
57  if ((bf->size & 0x8000) == 0x200) {
58  hdroffset = 0x200;
59  }
60 #endif
61  int reat = rz_buf_read_at(bf->buf, 0x7FC0 + hdroffset,
62  (ut8 *)&sfchdr, SFC_HDR_SIZE);
63  if (reat != SFC_HDR_SIZE) {
64  RZ_LOG_ERROR("Unable to read SFC/SNES header\n");
65  return NULL;
66  }
67 
68  if ((sfchdr.comp_check != (ut16) ~(sfchdr.checksum)) || ((sfchdr.rom_setup & 0x1) != 0)) {
69 
70  // if the fixed 0x33 byte or the LoROM indication are not found, then let's try interpreting the ROM as HiROM
71 
72  reat = rz_buf_read_at(bf->buf, 0xFFC0 + hdroffset, (ut8 *)&sfchdr, SFC_HDR_SIZE);
73  if (reat != SFC_HDR_SIZE) {
74  RZ_LOG_ERROR("Unable to read SFC/SNES header\n");
75  return NULL;
76  }
77 
78  if ((sfchdr.comp_check != (ut16) ~(sfchdr.checksum)) || ((sfchdr.rom_setup & 0x1) != 1)) {
79 
80  RZ_LOG_ERROR("Cannot determine if this is a LoROM or HiROM file\n");
81  return NULL;
82  }
83  }
84 
85  if (!(ret = RZ_NEW0(RzBinInfo))) {
86  return NULL;
87  }
88  ret->file = strdup(bf->file);
89  ret->type = strdup("ROM");
90  ret->machine = strdup("Super NES / Super Famicom");
91  ret->os = strdup("snes");
92  ret->arch = strdup("snes");
93  ret->bits = 16;
94  ret->has_va = 1;
95  return ret;
96 }
uint8_t ut8
Definition: lh5801.h:11
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
RZ_API st64 rz_buf_read_at(RZ_NONNULL RzBuffer *b, ut64 addr, RZ_NONNULL RZ_OUT ut8 *buf, ut64 len)
Read len bytes of the buffer at the specified address.
Definition: buf.c:1136
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
#define SFC_HDR_SIZE
Definition: sfc_specs.h:13
char * file
Definition: rz_bin.h:299
RzBuffer * buf
Definition: rz_bin.h:303
int has_va
Definition: rz_bin.h:228
char * type
Definition: rz_bin.h:211
char * os
Definition: rz_bin.h:219
char * machine
Definition: rz_bin.h:216
char * file
Definition: rz_bin.h:210
char * arch
Definition: rz_bin.h:214

References rz_bin_info_t::arch, rz_bin_info_t::bits, rz_bin_file_t::buf, rz_bin_info_t::file, rz_bin_file_t::file, rz_bin_info_t::has_va, rz_bin_info_t::machine, NULL, rz_bin_info_t::os, rz_buf_read_at(), RZ_LOG_ERROR, RZ_NEW0, SFC_HDR_SIZE, rz_bin_file_t::size, strdup(), and rz_bin_info_t::type.

◆ load_buffer()

static bool load_buffer ( RzBinFile bf,
RzBinObject obj,
RzBuffer b,
Sdb sdb 
)
static

Definition at line 48 of file bin_sfc.c.

48  {
49  return check_buffer(b);
50 }
static bool check_buffer(RzBuffer *b)
Definition: bin_sfc.c:9

References b, and check_buffer().

◆ mem()

static RzList* mem ( RzBinFile bf)
static

Definition at line 188 of file bin_sfc.c.

188  {
189  RzList *ret;
190  RzBinMem *m;
191  RzBinMem *m_bak;
192  if (!(ret = rz_list_new())) {
193  return NULL;
194  }
195  ret->free = free;
196  if (!(m = RZ_NEW0(RzBinMem))) {
197  rz_list_free(ret);
198  return NULL;
199  }
200  m->name = strdup("LOWRAM");
201  m->addr = LOWRAM_START_ADDRESS;
202  m->size = LOWRAM_SIZE;
203  m->perms = rz_str_rwx("rwx");
204  rz_list_append(ret, m);
205 
206  if (!(m = RZ_NEW0(RzBinMem))) {
207  return ret;
208  }
209  m->mirrors = rz_list_new();
210  m->name = strdup("LOWRAM_MIRROR");
212  m->size = LOWRAM_MIRROR_SIZE;
213  m->perms = rz_str_rwx("rwx");
214  rz_list_append(m->mirrors, m);
215  m_bak = m;
216  if (!(m = RZ_NEW0(RzBinMem))) {
217  rz_list_free(m_bak->mirrors);
218  return ret;
219  }
220  m->name = strdup("HIRAM");
221  m->addr = HIRAM_START_ADDRESS;
222  m->size = HIRAM_SIZE;
223  m->perms = rz_str_rwx("rwx");
224  rz_list_append(ret, m);
225  if (!(m = RZ_NEW0(RzBinMem))) {
226  return ret;
227  }
228  m->name = strdup("EXTRAM");
229  m->addr = EXTRAM_START_ADDRESS;
230  m->size = EXTRAM_SIZE;
231  m->perms = rz_str_rwx("rwx");
232  rz_list_append(ret, m);
233  if (!(m = RZ_NEW0(RzBinMem))) {
234  return ret;
235  }
236  m->name = strdup("PPU1_REG");
237  m->addr = PPU1_REG_ADDRESS;
238  m->size = PPU1_REG_SIZE;
239  m->perms = rz_str_rwx("rwx");
240  rz_list_append(ret, m);
241  if (!(m = RZ_NEW0(RzBinMem))) {
242  rz_list_free(ret);
243  return NULL;
244  }
245  m->name = strdup("DSP_REG");
246  m->addr = DSP_REG_ADDRESS;
247  m->size = DSP_REG_SIZE;
248  m->perms = rz_str_rwx("rwx");
249  rz_list_append(ret, m);
250  if (!(m = RZ_NEW0(RzBinMem))) {
251  rz_list_free(ret);
252  return NULL;
253  }
254  m->name = strdup("OLDJOY_REG");
255  m->addr = OLDJOY_REG_ADDRESS;
256  m->size = OLDJOY_REG_SIZE;
257  m->perms = rz_str_rwx("rwx");
258  rz_list_append(ret, m);
259  if (!(m = RZ_NEW0(RzBinMem))) {
260  rz_list_free(ret);
261  return NULL;
262  }
263  m->name = strdup("PPU2_REG");
264  m->addr = PPU2_REG_ADDRESS;
265  m->size = PPU2_REG_SIZE;
266  m->perms = rz_str_rwx("rwx");
267  rz_list_append(ret, m);
268  return ret;
269 }
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
RZ_API int rz_str_rwx(const char *str)
Definition: str.c:318
#define OLDJOY_REG_SIZE
Definition: sfc_specs.h:29
#define OLDJOY_REG_ADDRESS
Definition: sfc_specs.h:28
#define EXTRAM_START_ADDRESS
Definition: sfc_specs.h:43
#define LOWRAM_SIZE
Definition: sfc_specs.h:35
#define HIRAM_START_ADDRESS
Definition: sfc_specs.h:40
#define DSP_REG_ADDRESS
Definition: sfc_specs.h:25
#define PPU1_REG_ADDRESS
Definition: sfc_specs.h:22
#define PPU2_REG_ADDRESS
Definition: sfc_specs.h:31
#define PPU2_REG_SIZE
Definition: sfc_specs.h:32
#define DSP_REG_SIZE
Definition: sfc_specs.h:26
#define PPU1_REG_SIZE
Definition: sfc_specs.h:23
#define EXTRAM_SIZE
Definition: sfc_specs.h:44
#define LOWRAM_START_ADDRESS
Definition: sfc_specs.h:34
#define LOWRAM_MIRROR_START_ADDRESS
Definition: sfc_specs.h:37
#define LOWRAM_MIRROR_SIZE
Definition: sfc_specs.h:38
#define HIRAM_SIZE
Definition: sfc_specs.h:41
RzList * mirrors
Definition: rz_bin.h:784
RzListFree free
Definition: rz_list.h:21

References DSP_REG_ADDRESS, DSP_REG_SIZE, EXTRAM_SIZE, EXTRAM_START_ADDRESS, rz_list_t::free, free(), HIRAM_SIZE, HIRAM_START_ADDRESS, LOWRAM_MIRROR_SIZE, LOWRAM_MIRROR_START_ADDRESS, LOWRAM_SIZE, LOWRAM_START_ADDRESS, regress::m, rz_bin_mem_t::mirrors, NULL, OLDJOY_REG_ADDRESS, OLDJOY_REG_SIZE, PPU1_REG_ADDRESS, PPU1_REG_SIZE, PPU2_REG_ADDRESS, PPU2_REG_SIZE, rz_list_append(), rz_list_free(), rz_list_new(), RZ_NEW0, rz_str_rwx(), and strdup().

◆ sections()

static RzList* sections ( RzBinFile bf)
static

Definition at line 129 of file bin_sfc.c.

129  {
130  RzList *ret = NULL;
131  // RzBinSection *ptr = NULL;
132  int hdroffset = 0;
133  bool is_hirom = false;
134  int i = 0; // 0x8000-long bank number for loops
135 #if THIS_IS_ALWAYS_FALSE_WTF
136  if ((bf->size & 0x8000) == 0x200) {
137  hdroffset = 0x200;
138  }
139 #endif
140  sfc_int_hdr sfchdr = { { 0 } };
141 
142  int reat = rz_buf_read_at(bf->buf, 0x7FC0 + hdroffset, (ut8 *)&sfchdr, SFC_HDR_SIZE);
143  if (reat != SFC_HDR_SIZE) {
144  RZ_LOG_ERROR("Unable to read SFC/SNES header\n");
145  return NULL;
146  }
147 
148  if ((sfchdr.comp_check != (ut16) ~(sfchdr.checksum)) || ((sfchdr.rom_setup & 0x1) != 0)) {
149 
150  // if the fixed 0x33 byte or the LoROM indication are not found, then let's try interpreting the ROM as HiROM
151 
152  reat = rz_buf_read_at(bf->buf, 0xFFC0 + hdroffset, (ut8 *)&sfchdr, SFC_HDR_SIZE);
153  if (reat != SFC_HDR_SIZE) {
154  RZ_LOG_ERROR("Unable to read SFC/SNES header\n");
155  return NULL;
156  }
157 
158  if ((sfchdr.comp_check != (ut16) ~(sfchdr.checksum)) || ((sfchdr.rom_setup & 0x1) != 1)) {
159 
160  RZ_LOG_ERROR("Cannot determine if this is a LoROM or HiROM file\n");
161  return NULL;
162  }
163  is_hirom = true;
164  }
165 
166  if (!(ret = rz_list_new())) {
167  return NULL;
168  }
169 
170  if (is_hirom) {
171  for (i = 0; i < ((bf->size - hdroffset) / 0x8000); i++) {
172  // XXX check integer overflow here
173  addrom(ret, "ROM", i, hdroffset + i * 0x8000, 0x400000 + (i * 0x8000), 0x8000);
174  if (i % 2) {
175  addrom(ret, "ROM_MIRROR", i, hdroffset + i * 0x8000, (i * 0x8000), 0x8000);
176  }
177  }
178 
179  } else {
180  for (i = 0; i < ((bf->size - hdroffset) / 0x8000); i++) {
181 
182  addrom(ret, "ROM", i, hdroffset + i * 0x8000, 0x8000 + (i * 0x10000), 0x8000);
183  }
184  }
185  return ret;
186 }
static void addrom(RzList *ret, const char *name, int i, ut64 paddr, ut64 vaddr, ut32 size)
Definition: bin_sfc.c:98

References addrom(), rz_bin_file_t::buf, i, NULL, rz_buf_read_at(), rz_list_new(), RZ_LOG_ERROR, SFC_HDR_SIZE, and rz_bin_file_t::size.

◆ symbols()

static RzList* symbols ( RzBinFile bf)
static

Definition at line 125 of file bin_sfc.c.

125  {
126  return NULL;
127 }

References NULL.

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
.type = RZ_LIB_TYPE_BIN,
}
RzBinPlugin rz_bin_plugin_sfc
Definition: bin_sfc.c:288
@ RZ_LIB_TYPE_BIN
Definition: rz_lib.h:75
#define RZ_VERSION
Definition: rz_version.h:8
char * version
Definition: rz_bin.h:512

Definition at line 303 of file bin_sfc.c.

◆ rz_bin_plugin_sfc

RzBinPlugin rz_bin_plugin_sfc
Initial value:
= {
.name = "sfc",
.desc = "Super NES / Super Famicom ROM file",
.license = "LGPL3",
.load_buffer = &load_buffer,
.check_buffer = &check_buffer,
.entries = &entries,
.sections = sections,
.symbols = &symbols,
.info = &info,
.mem = &mem,
}
RZ_API RZ_OWN RzList * rz_bin_maps_of_file_sections(RZ_NONNULL RzBinFile *binfile)
Create a list of RzBinMap from RzBinSections queried from the given file.
Definition: bin.c:1040
static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb)
Definition: bin_sfc.c:48
static RzList * mem(RzBinFile *bf)
Definition: bin_sfc.c:188
static RzList * symbols(RzBinFile *bf)
Definition: bin_sfc.c:125
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_sfc.c:52
static RzList * entries(RzBinFile *bf)
Definition: bin_sfc.c:271
static RzList * sections(RzBinFile *bf)
Definition: bin_sfc.c:129

Definition at line 288 of file bin_sfc.c.