Rizin
unix-like reverse engineering framework and cli tools
analysis_snes.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2015 condret <condr3t@protonmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include <string.h>
5 #include <rz_types.h>
6 #include <rz_lib.h>
7 #include <rz_asm.h>
8 #include <rz_analysis.h>
9 #include "../../asm/arch/snes/snes_op_table.h"
10 #include "../../asm/p/asm_snes.h"
11 
12 static int snes_anop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask) {
13  struct snes_asm_flags *snesflags = (struct snes_asm_flags *)analysis->plugin_data;
14  op->size = snes_op_get_size(snesflags->M, snesflags->X, &snes_op[data[0]]);
15  if (op->size > len) {
16  return op->size = 0;
17  }
18  op->nopcode = 1;
19  op->addr = addr;
21  switch (data[0]) {
22  case 0xea: // nop
24  break;
25  case 0xfb: // xce
27  break;
28  case 0x00: // brk
29  case 0x02: // cop
31  break;
32  case 0x1b: // tcs
33  case 0x3b: // tsc
34  case 0x5b: // tcd
35  case 0x7b: // tdc
36  case 0x8a: // txa
37  case 0x98: // tya
38  case 0x9a: // txs
39  case 0x9b: // txy
40  case 0xa8: // tay
41  case 0xaa: // tax
42  case 0xba: // tsx
43  case 0xbb: // tyx
45  break;
46  case 0x48: // pha
47  case 0x8b: // phb
48  case 0x0b: // phd
49  case 0x4b: // phk
50  case 0x08: // php
51  case 0xda: // phx
52  case 0x5a: // phy
54  break;
55  case 0x68: // pla
56  case 0xab: // plb
57  case 0x2b: // pld
58  case 0x28: // plp
59  case 0xfa: // plx
60  case 0x7a: // ply
62  break;
63  // adc
64  case 0x61:
65  case 0x63:
66  case 0x65:
67  case 0x67:
68  case 0x69:
69  case 0x6d:
70  case 0x6f:
71  case 0x71:
72  case 0x72:
73  case 0x73:
74  case 0x75:
75  case 0x77:
76  case 0x79:
77  case 0x7d:
78  case 0x7f:
79  // inc
80  case 0x1a:
81  case 0xe6:
82  case 0xee:
83  case 0xf6:
84  case 0xfe:
85  case 0xe8: // inx
86  case 0xc8: // iny
88  break;
89  // and
90  case 0x23:
91  case 0x25:
92  case 0x27:
93  case 0x29:
94  case 0x2d:
95  case 0x2f:
96  case 0x31:
97  case 0x32:
98  case 0x33:
99  case 0x35:
100  case 0x37:
101  case 0x39:
102  case 0x3d:
103  case 0x3f:
104  op->type = RZ_ANALYSIS_OP_TYPE_AND;
105  break;
106  // bit
107  case 0x24:
108  case 0x2c:
109  case 0x34:
110  case 0x3c:
111  case 0x89:
113  break;
114  // cmp
115  case 0xc1:
116  case 0xc3:
117  case 0xc5:
118  case 0xc7:
119  case 0xc9:
120  case 0xcd:
121  case 0xcf:
122  case 0xd1:
123  case 0xd2:
124  case 0xd3:
125  case 0xd5:
126  case 0xd7:
127  case 0xd9:
128  case 0xdd:
129  case 0xdf:
130  // cpx
131  case 0xe0:
132  case 0xe4:
133  case 0xec:
134  // cpy
135  case 0xc0:
136  case 0xc4:
137  case 0xcc:
138  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
139  break;
140  // ora
141  case 0x01:
142  case 0x03:
143  case 0x05:
144  case 0x07:
145  case 0x09:
146  case 0x0d:
147  case 0x0f:
148  case 0x11:
149  case 0x12:
150  case 0x13:
151  case 0x15:
152  case 0x17:
153  case 0x19:
154  case 0x1d:
155  case 0x1f:
156  op->type = RZ_ANALYSIS_OP_TYPE_OR;
157  break;
158  // eor
159  case 0x41:
160  case 0x43:
161  case 0x45:
162  case 0x47:
163  case 0x49:
164  case 0x4d:
165  case 0x4f:
166  case 0x51:
167  case 0x52:
168  case 0x53:
169  case 0x55:
170  case 0x57:
171  case 0x59:
172  case 0x5d:
173  case 0x5f:
174  op->type = RZ_ANALYSIS_OP_TYPE_XOR;
175  break;
176  // asl
177  case 0x06:
178  case 0x0a:
179  case 0x0e:
180  case 0x16:
181  case 0x1e:
182  op->type = RZ_ANALYSIS_OP_TYPE_SAL;
183  break;
184  // lsr
185  case 0x46:
186  case 0x4a:
187  case 0x4e:
188  case 0x56:
189  case 0x5e:
190  op->type = RZ_ANALYSIS_OP_TYPE_SHR;
191  break;
192  // rol
193  case 0x26:
194  case 0x2a:
195  case 0x2e:
196  case 0x36:
197  case 0x3e:
198  op->type = RZ_ANALYSIS_OP_TYPE_ROL;
199  break;
200  // ror
201  case 0x66:
202  case 0x6a:
203  case 0x6e:
204  case 0x76:
205  case 0x7e:
206  op->type = RZ_ANALYSIS_OP_TYPE_ROR;
207  break;
208  // sbc
209  case 0xe1:
210  case 0xe3:
211  case 0xe5:
212  case 0xe7:
213  case 0xe9:
214  case 0xed:
215  case 0xef:
216  case 0xf1:
217  case 0xf2:
218  case 0xf3:
219  case 0xf5:
220  case 0xf7:
221  case 0xf9:
222  case 0xfd:
223  case 0xff:
224  // dec
225  case 0x3a:
226  case 0xc6:
227  case 0xce:
228  case 0xd6:
229  case 0xde:
230  case 0xca: // dex
231  case 0x88: // dey
232  op->type = RZ_ANALYSIS_OP_TYPE_SUB;
233  break;
234  // sta
235  case 0x81:
236  case 0x83:
237  case 0x85:
238  case 0x87:
239  case 0x8d:
240  case 0x8f:
241  case 0x91:
242  case 0x92:
243  case 0x93:
244  case 0x95:
245  case 0x97:
246  case 0x99:
247  case 0x9d:
248  case 0x9f:
249  // stx
250  case 0x86:
251  case 0x8e:
252  case 0x96:
253  // sty
254  case 0x84:
255  case 0x8c:
256  case 0x94:
257  // stz
258  case 0x64:
259  case 0x74:
260  case 0x9c:
261  case 0x9e:
263  break;
264  // lda
265  case 0xa1:
266  case 0xa3:
267  case 0xa5:
268  case 0xa7:
269  case 0xa9:
270  case 0xad:
271  case 0xaf:
272  case 0xb1:
273  case 0xb2:
274  case 0xb3:
275  case 0xb5:
276  case 0xb7:
277  case 0xb9:
278  case 0xbd:
279  case 0xbf:
280  // ldx
281  case 0xa2:
282  case 0xa6:
283  case 0xae:
284  case 0xb6:
285  case 0xbe:
286  // ldy
287  case 0xa0:
288  case 0xa4:
289  case 0xac:
290  case 0xb4:
291  case 0xbc:
293  break;
294  case 0x4c: // jmp addr
295  op->eob = true;
296  op->jump = (addr & 0xFF0000) | rz_read_le16(data + 1);
297  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
298  break;
299  case 0x5c: // jmp long
300  op->eob = true;
301  op->jump = data[1] | data[2] << 8 | data[3] << 16;
302  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
303  break;
304  case 0x80: // bra
305  op->eob = true;
306  op->jump = addr + 2 + (st8)data[1];
307  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
308  break;
309  case 0x82: // brl
310  op->eob = true;
311  op->jump = addr + 3 + (st16)rz_read_le16(data + 1);
312  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
313  break;
314  case 0x6c: // jmp (addr)
315  case 0x7c: // jmp (addr,X)
316  case 0xdc: // jmp [addr]
317  op->eob = true;
319  break;
320  case 0x10: // bpl
321  case 0x30: // bmi
322  case 0x50: // bvc
323  case 0x70: // bvs
324  case 0x90: // bcc
325  case 0xb0: // bcs
326  op->eob = true;
327  op->jump = addr + 2 + (st8)data[1];
328  op->fail = addr + 2;
330  break;
331  case 0xd0: // bne
332  op->eob = true;
333  op->cond = RZ_TYPE_COND_NE;
334  op->jump = addr + 2 + (st8)data[1];
335  op->fail = addr + 2;
337  break;
338  case 0xf0: // beq
339  op->eob = true;
340  op->cond = RZ_TYPE_COND_EQ;
341  op->jump = addr + 2 + (st8)data[1];
342  op->fail = addr + 2;
344  break;
345  case 0x20: // jsr addr
346  op->jump = (addr & 0xFF0000) | rz_read_le16(data + 1);
348  break;
349  case 0x22: // jsr long
350  op->jump = data[1] | data[2] << 8 | data[3] << 16;
352  break;
353  case 0xfc: // jsr (addr,X)
355  break;
356  case 0x40: // rti
357  case 0x60: // rts
358  case 0x6b: // rtl
359  op->eob = true;
360  op->type = RZ_ANALYSIS_OP_TYPE_RET;
361  break;
362  case 0xc2: // rep
363  if (((st8)data[1]) & 0x10) {
364  snesflags->X = 0;
365  }
366  if (((st8)data[1]) & 0x20) {
367  snesflags->M = 0;
368  }
369  break;
370  case 0xe2: // sep
371  if (((st8)data[1]) & 0x10) {
372  snesflags->X = 1;
373  }
374  if (((st8)data[1]) & 0x20) {
375  snesflags->M = 1;
376  }
377  break;
378  }
379  return op->size;
380 }
381 
382 static bool snes_analysis_init(void **user) {
383  *user = RZ_NEW0(struct snes_asm_flags);
384  return *user != NULL;
385 }
386 
387 static bool snes_analysis_fini(void *user) {
388  rz_return_val_if_fail(user, false);
389  free(user);
390  return true;
391 }
392 
394  .name = "snes",
395  .desc = "SNES analysis plugin",
396  .license = "LGPL3",
397  .arch = "snes",
398  .bits = 16,
399  .init = snes_analysis_init,
400  .fini = snes_analysis_fini,
401  .op = &snes_anop,
402 };
403 
404 #ifndef RZ_PLUGIN_INCORE
407  .data = &rz_analysis_plugin_snes,
409 };
410 #endif
size_t len
Definition: 6502dis.c:15
#define mask()
static bool snes_analysis_fini(void *user)
RZ_API RzLibStruct rizin_plugin
RzAnalysisPlugin rz_analysis_plugin_snes
static bool snes_analysis_init(void **user)
static int snes_anop(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: analysis_snes.c:12
#define RZ_API
#define NULL
Definition: cris-opc.c:27
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
RzAnalysisOpMask
Definition: rz_analysis.h:439
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_SUB
Definition: rz_analysis.h:402
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_ROL
Definition: rz_analysis.h:420
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_AND
Definition: rz_analysis.h:411
@ RZ_ANALYSIS_OP_TYPE_SAL
Definition: rz_analysis.h:408
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_ROR
Definition: rz_analysis.h:419
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_XCHG
Definition: rz_analysis.h:421
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_OR
Definition: rz_analysis.h:410
@ RZ_ANALYSIS_OP_TYPE_STORE
Definition: rz_analysis.h:415
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_SHR
Definition: rz_analysis.h:406
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_ACMP
Definition: rz_analysis.h:400
@ RZ_ANALYSIS_OP_TYPE_XOR
Definition: rz_analysis.h:412
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
static ut16 rz_read_le16(const void *src)
Definition: rz_endian.h:206
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
@ RZ_TYPE_COND_EQ
Equal.
Definition: rz_type.h:184
@ RZ_TYPE_COND_NE
Not equal.
Definition: rz_type.h:185
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define st8
Definition: rz_types_base.h:16
#define st16
Definition: rz_types_base.h:14
#define RZ_VERSION
Definition: rz_version.h:8
static snes_op_t snes_op[]
Definition: snes_op_table.h:33
static int snes_op_get_size(int M_flag, int X_flag, snes_op_t *op)
Definition: snes_op_table.h:24
const char * version
Definition: rz_analysis.h:1239
void * plugin_data
Definition: rz_analysis.h:561
unsigned char M
Definition: asm_snes.h:9
unsigned char X
Definition: asm_snes.h:10
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58