Rizin
unix-like reverse engineering framework and cli tools
bin_smd.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2015-2018 pancake <pancake@nopcode.org>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <rz_bin.h>
5 
6 typedef struct gen_hdr {
22 
23 typedef struct gen_vect {
24  union {
25  struct {
90  };
92  };
94 
95 static ut64 baddr(RzBinFile *bf) {
96  return 0;
97 }
98 
99 static bool check_buffer(RzBuffer *b) {
100  if (rz_buf_size(b) > 0x190) {
101  ut8 buf[4];
102  rz_buf_read_at(b, 0x100, buf, sizeof(buf));
103  return !memcmp(buf, "SEGA", 4);
104  }
105  return false;
106 }
107 
108 static bool load_buffer(RzBinFile *bf, RzBinObject *obj, RzBuffer *b, Sdb *sdb) {
109  return check_buffer(b);
110 }
111 
112 static RzBinInfo *info(RzBinFile *bf) {
113  RzBinInfo *ret = NULL;
114  if (!(ret = RZ_NEW0(RzBinInfo))) {
115  return NULL;
116  }
117  ret->file = strdup(bf->file);
118  ret->type = strdup("ROM");
119  ret->machine = strdup("Sega Megadrive");
120  ut8 tmp[32];
121  rz_buf_read_at(bf->buf, 0x100, tmp, sizeof(tmp));
122  ret->bclass = rz_str_ndup((char *)tmp, 32);
123  ret->os = strdup("smd");
124  ret->arch = strdup("m68k");
125  ret->bits = 16;
126  ret->has_va = 1;
127  ret->big_endian = 1;
128  return ret;
129 }
130 
131 static void addsym(RzList *ret, const char *name, ut64 addr) {
133  if (!ptr) {
134  return;
135  }
136  ptr->name = strdup(name ? name : "");
137  ptr->paddr = ptr->vaddr = addr;
138  ptr->size = 0;
139  ptr->ordinal = 0;
140  rz_list_append(ret, ptr);
141 }
142 
143 static void showstr(const char *str, const ut8 *s, int len) {
144  char *msg = rz_str_ndup((const char *)s, len);
145  eprintf("%s: %s\n", str, msg);
146  free(msg);
147 }
148 
149 static RzList *symbols(RzBinFile *bf) {
150  RzList *ret = NULL;
151  const char *name = NULL;
152  int i;
153 
154  if (!(ret = rz_list_newf((RzListFree)rz_bin_symbol_free))) {
155  return NULL;
156  }
157  SMD_Header hdr;
158  int left = rz_buf_read_at(bf->buf, 0x100, (ut8 *)&hdr, sizeof(hdr));
159  if (left < sizeof(SMD_Header)) {
160  return NULL;
161  }
162  // TODO: store all this stuff in SDB
163  addsym(ret, "rom_start", rz_read_be32(&hdr.RomStart));
164  addsym(ret, "rom_end", rz_read_be32(&hdr.RomEnd));
165  addsym(ret, "ram_start", rz_read_be32(&hdr.RamStart));
166  addsym(ret, "ram_end", rz_read_be32(&hdr.RamEnd));
167  showstr("Copyright", hdr.CopyRights, 32);
168  showstr("DomesticName", hdr.DomesticName, 48);
169  showstr("OverseasName", hdr.OverseasName, 48);
170  showstr("ProductCode", hdr.ProductCode, 14);
171  eprintf("Checksum: 0x%04x\n", (ut32)hdr.CheckSum);
172  showstr("Peripherials", hdr.Peripherials, 16);
173  showstr("SramCode", hdr.SramCode, 12);
174  showstr("ModemCode", hdr.ModemCode, 12);
175  showstr("CountryCode", hdr.CountryCode, 16);
176  ut32 vtable[64];
177  rz_buf_read_at(bf->buf, 0, (ut8 *)&vtable, sizeof(ut32) * 64);
178  /* parse vtable */
179  for (i = 0; i < 64; i++) {
180  switch (i) {
181  case 0: name = "SSP"; break;
182  case 1: name = "Reset"; break;
183  case 2: name = "BusErr"; break;
184  case 3: name = "AdrErr"; break;
185  case 4: name = "InvOpCode"; break;
186  case 5: name = "DivBy0"; break;
187  case 6: name = "Check"; break;
188  case 7: name = "TrapV"; break;
189  case 8: name = "GPF"; break;
190  case 9: name = "Trace"; break;
191  case 10: name = "Reserv0"; break;
192  case 11: name = "Reserv1"; break;
193  case 12: name = "Reserv2"; break;
194  case 13: name = "Reserv3"; break;
195  case 14: name = "Reserv4"; break;
196  case 15: name = "BadInt"; break;
197  case 16: name = "Reserv10"; break;
198  case 17: name = "Reserv11"; break;
199  case 18: name = "Reserv12"; break;
200  case 19: name = "Reserv13"; break;
201  case 20: name = "Reserv14"; break;
202  case 21: name = "Reserv15"; break;
203  case 22: name = "Reserv16"; break;
204  case 23: name = "Reserv17"; break;
205  case 24: name = "BadIRQ"; break;
206  case 25: name = "IRQ1"; break;
207  case 26: name = "EXT"; break;
208  case 27: name = "IRQ3"; break;
209  case 28: name = "HBLANK"; break;
210  case 29: name = "IRQ5"; break;
211  case 30: name = "VBLANK"; break;
212  case 31: name = "IRQ7"; break;
213  case 32: name = "Trap0"; break;
214  case 33: name = "Trap1"; break;
215  case 34: name = "Trap2"; break;
216  case 35: name = "Trap3"; break;
217  case 36: name = "Trap4"; break;
218  case 37: name = "Trap5"; break;
219  case 38: name = "Trap6"; break;
220  case 39: name = "Trap7"; break;
221  case 40: name = "Trap8"; break;
222  case 41: name = "Trap9"; break;
223  case 42: name = "Trap10"; break;
224  case 43: name = "Trap11"; break;
225  case 44: name = "Trap12"; break;
226  case 45: name = "Trap13"; break;
227  case 46: name = "Trap14"; break;
228  case 47: name = "Trap15"; break;
229  case 48: name = "Reserv30"; break;
230  case 49: name = "Reserv31"; break;
231  case 50: name = "Reserv32"; break;
232  case 51: name = "Reserv33"; break;
233  case 52: name = "Reserv34"; break;
234  case 53: name = "Reserv35"; break;
235  case 54: name = "Reserv36"; break;
236  case 55: name = "Reserv37"; break;
237  case 56: name = "Reserv38"; break;
238  case 57: name = "Reserv39"; break;
239  case 58: name = "Reserv3A"; break;
240  case 59: name = "Reserv3B"; break;
241  case 60: name = "Reserv3C"; break;
242  case 61: name = "Reserv3D"; break;
243  case 62: name = "Reserv3E"; break;
244  case 63: name = "Reserv3F"; break;
245  default: name = NULL;
246  }
247  if (name && vtable[i]) {
248  ut32 addr = rz_read_be32(&vtable[i]);
249  addsym(ret, name, addr);
250  }
251  }
252  return ret;
253 }
254 
255 static RzList *sections(RzBinFile *bf) {
256  RzList *ret = NULL;
257  if (!(ret = rz_list_new())) {
258  return NULL;
259  }
260  RzBinSection *ptr;
261  if (!(ptr = RZ_NEW0(RzBinSection))) {
262  return ret;
263  }
264  ptr->name = strdup("vtable");
265  ptr->paddr = ptr->vaddr = 0;
266  ptr->size = ptr->vsize = 0x100;
267  ptr->perm = RZ_PERM_R;
268  rz_list_append(ret, ptr);
269 
270  if (!(ptr = RZ_NEW0(RzBinSection))) {
271  return ret;
272  }
273  ptr->name = strdup("header");
274  ptr->paddr = ptr->vaddr = 0x100;
275  ptr->size = ptr->vsize = sizeof(SMD_Header);
276  ptr->perm = RZ_PERM_R;
277  rz_list_append(ret, ptr);
278 
279  if (!(ptr = RZ_NEW0(RzBinSection))) {
280  return ret;
281  }
282  ptr->name = strdup("text");
283  ptr->paddr = ptr->vaddr = 0x100 + sizeof(SMD_Header);
284  {
285  SMD_Header hdr = { { 0 } };
286  rz_buf_read_at(bf->buf, 0x100, (ut8 *)&hdr, sizeof(hdr));
288  ptr->vaddr += baddr;
289  }
290  ptr->size = ptr->vsize = rz_buf_size(bf->buf) - ptr->paddr;
291  ptr->perm = RZ_PERM_RX;
292  rz_list_append(ret, ptr);
293  return ret;
294 }
295 
296 static RzList *entries(RzBinFile *bf) { // Should be 3 offsets pointed by NMI, RESET, IRQ after mapping && default = 1st CHR
297  RzList *ret;
298  RzBinAddr *ptr = NULL;
299  if (!(ret = rz_list_new())) {
300  return NULL;
301  }
302  if (!(ptr = RZ_NEW0(RzBinAddr))) {
303  return ret;
304  }
305  if (bf->size < sizeof(SMD_Vectors)) {
306  eprintf("ERR: binfile too small!\n");
307  ptr->paddr = ptr->vaddr = 0x100 + sizeof(SMD_Header);
308  rz_list_append(ret, ptr);
309  } else {
310  SMD_Vectors vectors;
311  rz_buf_read_at(bf->buf, 0, (ut8 *)&vectors, sizeof(vectors));
312  ptr->paddr = ptr->vaddr = rz_read_be32(&vectors.Reset);
313  rz_list_append(ret, ptr);
314  }
315  return ret;
316 }
317 
318 static RzList *strings(RzBinFile *bf) {
319  return rz_bin_file_strings(bf, 0, false);
320 }
321 
323  .name = "smd",
324  .desc = "SEGA Genesis/Megadrive",
325  .license = "LGPL3",
326  .load_buffer = &load_buffer,
327  .check_buffer = &check_buffer,
328  .baddr = &baddr,
329  .entries = &entries,
331  .sections = &sections,
332  .symbols = &symbols,
333  .strings = &strings,
334  .info = &info,
335  .minstrlen = 10,
336  .strfilter = 'U'
337 };
338 
339 #ifndef RZ_PLUGIN_INCORE
342  .data = &rz_bin_plugin_smd,
344 };
345 #endif
size_t len
Definition: 6502dis.c:15
lzma_index ** i
Definition: index.h:629
RZ_API RZ_OWN RzList * rz_bin_file_strings(RZ_NONNULL RzBinFile *bf, size_t min_length, bool raw_strings)
Generates a RzList struct containing RzBinString from a given RzBinFile.
Definition: bfile_string.c:325
RZ_API void rz_bin_symbol_free(RzBinSymbol *sym)
Definition: bin.c:175
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_smd.c:108
static void showstr(const char *str, const ut8 *s, int len)
Definition: bin_smd.c:143
static RzList * symbols(RzBinFile *bf)
Definition: bin_smd.c:149
static void addsym(RzList *ret, const char *name, ut64 addr)
Definition: bin_smd.c:131
static RzList * strings(RzBinFile *bf)
Definition: bin_smd.c:318
RZ_API RzLibStruct rizin_plugin
Definition: bin_smd.c:340
static bool check_buffer(RzBuffer *b)
Definition: bin_smd.c:99
static RzBinInfo * info(RzBinFile *bf)
Definition: bin_smd.c:112
static ut64 baddr(RzBinFile *bf)
Definition: bin_smd.c:95
struct gen_vect SMD_Vectors
static RzList * entries(RzBinFile *bf)
Definition: bin_smd.c:296
static RzList * sections(RzBinFile *bf)
Definition: bin_smd.c:255
struct gen_hdr SMD_Header
RzBinPlugin rz_bin_plugin_smd
Definition: bin_smd.c:322
#define RZ_API
#define NULL
Definition: cris-opc.c:27
uint16_t ut16
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
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
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")
#define eprintf(x, y...)
Definition: rlcc.c:7
static RzSocket * s
Definition: rtr.c:28
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
RZ_API ut64 rz_buf_size(RZ_NONNULL RzBuffer *b)
Return the size of the buffer.
Definition: buf.c:1225
static ut32 rz_read_be32(const void *src)
Definition: rz_endian.h:87
@ RZ_LIB_TYPE_BIN
Definition: rz_lib.h:75
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API char * rz_str_ndup(RZ_NULLABLE const char *ptr, int len)
Create new copy of string ptr limited to size len.
Definition: str.c:1006
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_PERM_RX
Definition: rz_types.h:97
#define RZ_VERSION
Definition: rz_version.h:8
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119
#define b(i)
Definition: sha256.c:42
Definition: bin_smd.c:6
ut8 ProductCode[14]
Definition: bin_smd.c:10
ut16 CheckSum
Definition: bin_smd.c:11
ut8 ModemCode[12]
Definition: bin_smd.c:18
ut8 DomesticName[48]
Definition: bin_smd.c:8
ut8 Peripherials[16]
Definition: bin_smd.c:12
ut8 Reserved[40]
Definition: bin_smd.c:19
ut8 CopyRights[32]
Definition: bin_smd.c:7
ut32 RomEnd
Definition: bin_smd.c:14
ut8 CountryCode[16]
Definition: bin_smd.c:20
ut32 RamStart
Definition: bin_smd.c:15
ut8 SramCode[12]
Definition: bin_smd.c:17
ut32 RomStart
Definition: bin_smd.c:13
ut8 OverseasName[48]
Definition: bin_smd.c:9
ut32 RamEnd
Definition: bin_smd.c:16
ut32 HBLANK
Definition: bin_smd.c:54
ut32 DivBy0
Definition: bin_smd.c:31
ut32 Trap4
Definition: bin_smd.c:62
ut32 Reserv15
Definition: bin_smd.c:47
ut32 BusErr
Definition: bin_smd.c:28
ut32 Reserv35
Definition: bin_smd.c:79
ut32 Reserv32
Definition: bin_smd.c:76
ut32 SSP
Definition: bin_smd.c:26
ut32 Reserv3F
Definition: bin_smd.c:89
ut32 Reserv13
Definition: bin_smd.c:45
ut32 Trap7
Definition: bin_smd.c:65
ut32 EXT
Definition: bin_smd.c:52
ut32 TrapV
Definition: bin_smd.c:33
ut32 Trap8
Definition: bin_smd.c:66
ut32 Reserv33
Definition: bin_smd.c:77
ut32 Reserv16
Definition: bin_smd.c:48
ut32 Reserv10
Definition: bin_smd.c:42
ut32 Trap12
Definition: bin_smd.c:70
ut32 AdrErr
Definition: bin_smd.c:29
ut32 Reserv30
Definition: bin_smd.c:74
ut32 Reserv2
Definition: bin_smd.c:38
ut32 Trap10
Definition: bin_smd.c:68
ut32 Trap13
Definition: bin_smd.c:71
ut32 IRQ5
Definition: bin_smd.c:55
ut32 Reserv3D
Definition: bin_smd.c:87
ut32 Trap3
Definition: bin_smd.c:61
ut32 IRQ1
Definition: bin_smd.c:51
ut32 Reserv3C
Definition: bin_smd.c:86
ut32 Trap9
Definition: bin_smd.c:67
ut32 Trap1
Definition: bin_smd.c:59
ut32 Reserv11
Definition: bin_smd.c:43
ut32 Trap11
Definition: bin_smd.c:69
ut32 Check
Definition: bin_smd.c:32
ut32 VBLANK
Definition: bin_smd.c:56
ut32 Reset
Definition: bin_smd.c:27
ut32 Trap5
Definition: bin_smd.c:63
ut32 Reserv4
Definition: bin_smd.c:40
ut32 Trap6
Definition: bin_smd.c:64
ut32 Trap0
Definition: bin_smd.c:58
ut32 GPF
Definition: bin_smd.c:34
ut32 Reserv1
Definition: bin_smd.c:37
ut32 Reserv3E
Definition: bin_smd.c:88
ut32 Reserv31
Definition: bin_smd.c:75
ut32 vectors[64]
Definition: bin_smd.c:91
ut32 Reserv12
Definition: bin_smd.c:44
ut32 BadInt
Definition: bin_smd.c:41
ut32 Reserv38
Definition: bin_smd.c:82
ut32 Reserv3
Definition: bin_smd.c:39
ut32 Reserv37
Definition: bin_smd.c:81
ut32 Reserv39
Definition: bin_smd.c:83
ut32 Reserv34
Definition: bin_smd.c:78
ut32 Trap2
Definition: bin_smd.c:60
ut32 IRQ3
Definition: bin_smd.c:53
ut32 Trap14
Definition: bin_smd.c:72
ut32 Reserv14
Definition: bin_smd.c:46
ut32 Reserv3A
Definition: bin_smd.c:84
ut32 Reserv0
Definition: bin_smd.c:36
ut32 Reserv3B
Definition: bin_smd.c:85
ut32 Trap15
Definition: bin_smd.c:73
ut32 Trace
Definition: bin_smd.c:35
ut32 BadIRQ
Definition: bin_smd.c:50
ut32 Reserv17
Definition: bin_smd.c:49
ut32 IRQ7
Definition: bin_smd.c:57
ut32 InvOpCode
Definition: bin_smd.c:30
ut32 Reserv36
Definition: bin_smd.c:80
Definition: z80asm.h:102
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
XX curplugin == o->plugin.
Definition: rz_bin.h:298
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 * bclass
Definition: rz_bin.h:212
char * file
Definition: rz_bin.h:210
char * arch
Definition: rz_bin.h:214
int big_endian
Definition: rz_bin.h:235
char * name
Definition: rz_bin.h:509
char * version
Definition: rz_bin.h:512
char * name
Definition: rz_bin.h:619
char * name
Definition: rz_bin.h:675
ut32 ordinal
Definition: rz_bin.h:692
Definition: sdb.h:63
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58