Rizin
unix-like reverse engineering framework and cli tools
opcode.c
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: 2020 FXTi <zjxiang1998@gmail.com>
2 // SPDX-License-Identifier: LGPL-3.0-only
3 
4 #include "opcode.h"
5 
7  { "1.0.1", opcode_10 },
8  { "1.1", opcode_11 },
9  { "1.2", opcode_12 },
10  { "1.3b1", opcode_13 },
11  { "1.4", opcode_14 },
12  { "1.4b1", opcode_14 },
13  { "1.5a1", opcode_15 },
14  { "1.6a2", opcode_16 },
15  { "2.0b1", opcode_20 },
16  { "2.1a1", opcode_21 },
17  { "2.1a2", opcode_21 },
18  { "2.2a0", opcode_22 },
19  { "2.2a1", opcode_22 },
20  { "2.3a0", opcode_23 },
21  { "2.4a0", opcode_24 },
22  { "2.4a2", opcode_24 },
23  { "2.4a3", opcode_24 },
24  { "2.5a0", opcode_25 },
25  { "2.5b2", opcode_25 },
26  { "2.5c3", opcode_25 },
27  { "2.6a0", opcode_26 },
28  { "2.6a1+", opcode_26 },
29  { "2.7a0", opcode_27 },
30  { "2.7a2+", opcode_27 },
31  { "3.0a1", opcode_30 },
32  { "3.0a1+", opcode_30 },
33  { "3.0a2", opcode_30 },
34  { "3.0a2+", opcode_30 },
35  { "3.0a3+", opcode_30 },
36  { "3.0a5+", opcode_30 },
37  { "3.0x", opcode_30 },
38  { "3.1a0", opcode_31 },
39  { "3.2a0", opcode_32 },
40  { "3.2a1+", opcode_32 },
41  { "3.2a2+", opcode_33 },
42  { "3.3.0a0", opcode_33 },
43  { "3.3.0a1+", opcode_33 },
44  { "3.3.0a3+", opcode_33 },
45  { "3.3a0", opcode_33 },
46  { "3.4.0a0", opcode_34 },
47  { "3.4.0a3+", opcode_34 },
48  { "3.4.0rc1+", opcode_34 },
49  { "3.5.0a0", opcode_35 },
50  { "3.5.0a4+", opcode_35 },
51  { "3.5.0b1+", opcode_35 },
52  { "3.5.0b2+", opcode_35 },
53  { "3.6.0a0", opcode_36 },
54  { "v3.6.0", opcode_36 },
55  { "v3.6.0a2", opcode_36 },
56  { "v3.6.0a3", opcode_36 },
57  { "v3.6.0a4", opcode_36 },
58  { "v3.6.0b1", opcode_36 },
59  { "v3.6.0b2", opcode_36 },
60  { "v3.6.0b3", opcode_36 },
61  { "v3.6.0b4", opcode_36 },
62  { "v3.6.0rc1", opcode_36 },
63  { "v3.6.0rc2", opcode_36 },
64  { "v3.6.1", opcode_36 },
65  { "v3.6.10", opcode_36 },
66  { "v3.6.10rc", opcode_36 },
67  { "v3.6.1rc1", opcode_36 },
68  { "v3.6.2", opcode_36 },
69  { "v3.6.2rc1", opcode_36 },
70  { "v3.6.2rc2", opcode_36 },
71  { "v3.6.3", opcode_36 },
72  { "v3.6.3rc1", opcode_36 },
73  { "v3.6.4", opcode_36 },
74  { "v3.6.4rc1", opcode_36 },
75  { "v3.6.5", opcode_36 },
76  { "v3.6.5rc1", opcode_36 },
77  { "v3.6.6", opcode_36 },
78  { "v3.6.6rc1", opcode_36 },
79  { "v3.6.7", opcode_36 },
80  { "v3.6.7rc1", opcode_36 },
81  { "v3.6.7rc2", opcode_36 },
82  { "v3.6.8", opcode_36 },
83  { "v3.6.8rc1", opcode_36 },
84  { "v3.6.9", opcode_36 },
85  { "v3.6.9rc1", opcode_36 },
86  { "v3.7.0", opcode_37 },
87  { "v3.7.0a1", opcode_37 },
88  { "v3.7.0a2", opcode_37 },
89  { "v3.7.0a3", opcode_37 },
90  { "v3.7.0a4", opcode_37 },
91  { "v3.7.0b1", opcode_37 },
92  { "v3.7.0b2", opcode_37 },
93  { "v3.7.0b3", opcode_37 },
94  { "v3.7.0b4", opcode_37 },
95  { "v3.7.0b5", opcode_37 },
96  { "v3.7.0rc1", opcode_37 },
97  { "v3.7.1", opcode_37 },
98  { "v3.7.1rc1", opcode_37 },
99  { "v3.7.1rc2", opcode_37 },
100  { "v3.7.2", opcode_37 },
101  { "v3.7.2rc1", opcode_37 },
102  { "v3.7.3", opcode_37 },
103  { "v3.7.3rc1", opcode_37 },
104  { "v3.7.4", opcode_37 },
105  { "v3.7.4rc1", opcode_37 },
106  { "v3.7.4rc2", opcode_37 },
107  { "v3.7.5", opcode_37 },
108  { "v3.7.5rc1", opcode_37 },
109  { "v3.7.6", opcode_37 },
110  { "v3.7.6rc1", opcode_37 },
111  { "v3.8.0", opcode_38 },
112  { "v3.8.0a1", opcode_38 },
113  { "v3.8.0a2", opcode_38 },
114  { "v3.8.0a3", opcode_38 },
115  { "v3.8.0a4", opcode_38 },
116  { "v3.8.0b1", opcode_38 },
117  { "v3.8.0b2", opcode_38 },
118  { "v3.8.0b3", opcode_38 },
119  { "v3.8.0b4", opcode_38 },
120  { "v3.8.0rc1", opcode_38 },
121  { "v3.8.1", opcode_38 },
122  { "v3.8.1rc1", opcode_38 },
123  { "v3.9.0a1", opcode_39 },
124  { "v3.9.0a2", opcode_39 },
125  { "v3.9.0a3", opcode_39 },
126  { "v3.9.0a5", opcode_39 },
127  { "v3.9.0a6", opcode_39 },
128  { "v3.9.0b1", opcode_39 },
129  { "v3.9.0b2", opcode_39 },
130  { "v3.9.0b3", opcode_39 },
131  { "v3.9.0b4", opcode_39 },
132  { "v3.9.0b5", opcode_39 },
133  { "v3.9.0rc1", opcode_39 },
134  { "v3.9.0rc2", opcode_39 },
135  { "v3.9.0", opcode_39 },
136  { "v3.9.1", opcode_39 },
137  { "v3.9.2", opcode_39 },
138  { "v3.9.3", opcode_39 },
139  { "v3.9.4", opcode_39 },
140  { "v3.9.5", opcode_39 },
141  { "v3.9.6", opcode_39 },
142  { "v3.9.7", opcode_39 },
143  { "v3.9.8", opcode_39 },
144  { "v3.9.9", opcode_39 },
145  { "v3.9.10", opcode_39 },
146  { "v3.9.11", opcode_39 },
147  { "v3.9.12", opcode_39 },
148  { NULL, NULL },
149 };
150 
152  if (version == NULL || op == NULL) {
153  return false;
154  }
155  version_opcode *vop = version_op;
156 
157  while (vop->version) {
158  if (!strcmp(vop->version, version)) {
159  if (vop->opcode_func == (pyc_opcodes * (*)())(op->version_sig)) {
160  return true;
161  }
162  }
163  vop++;
164  }
165 
166  return false;
167 }
168 
170  if (version == NULL) {
171  return NULL;
172  }
173  version_opcode *vop = version_op;
174 
175  while (vop->version) {
176  if (!strcmp(vop->version, version)) {
177  return vop->opcode_func();
178  }
179  vop++;
180  }
181 
182  return NULL; // No match version
183 }
184 
186  size_t i, j;
188  if (!ret) {
189  return NULL;
190  }
191  ret->have_argument = 90;
192  ret->opcodes = malloc(sizeof(pyc_opcode_object) * 256);
193  if (!ret->opcodes) {
194  free(ret);
195  return NULL;
196  }
197  for (i = 0; i < 256; i++) {
198  ret->opcodes[i].op_name = rz_str_newf("<%zu>", i);
199  if (!ret->opcodes[i].op_name) {
200  for (j = 0; j < i; j++) {
201  free(ret->opcodes[j].op_name);
202  }
203  free(ret->opcodes);
204  RZ_FREE(ret);
205  return NULL;
206  }
207  ret->opcodes[i].type = 0;
208  ret->opcodes[i].op_code = i;
209  ret->opcodes[i].op_push = 0;
210  ret->opcodes[i].op_pop = 0;
211  }
212 
214  return ret;
215 }
216 
218  size_t i;
219  if (opcodes == NULL || opcodes->opcodes == NULL) {
220  return;
221  }
222  for (i = 0; i < 256; i++) {
223  if (opcodes->opcodes[i].op_name) {
224  free(opcodes->opcodes[i].op_name);
225  }
226  }
227  free(opcodes->opcodes);
228  if (opcodes->opcode_arg_fmt) {
229  rz_list_free(opcodes->opcode_arg_fmt);
230  }
231  free(opcodes);
232 }
233 
234 void add_arg_fmt(pyc_opcodes *ret, char *op_name, const char *(*formatter)(ut32 oparg)) {
236  if (!fmt) {
237  return;
238  }
239  fmt->op_name = op_name;
240  fmt->formatter = formatter;
241  rz_list_append(ret->opcode_arg_fmt, fmt);
242 }
243 
244 void(def_opN)(struct op_parameter par) {
245  free(par.op_obj[par.op_code].op_name);
246  par.op_obj[par.op_code].op_name = strdup(par.op_name);
247  par.op_obj[par.op_code].op_code = par.op_code;
248  par.op_obj[par.op_code].op_pop = par.pop;
249  par.op_obj[par.op_code].op_push = par.push;
250  if (!par.fallthrough) {
251  par.op_obj[par.op_code].type |= NOFOLLOW;
252  }
253 }
254 
255 void(name_opN)(struct op_parameter par) {
256  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
257  par.op_obj[par.op_code].type |= HASNAME;
258 }
259 
260 void(local_opN)(struct op_parameter par) {
261  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
262  par.op_obj[par.op_code].type |= HASLOCAL;
263 }
264 
265 void(free_opN)(struct op_parameter par) {
266  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
267  par.op_obj[par.op_code].type |= HASFREE;
268 }
269 
270 void(store_opN)(struct op_parameter par) {
271  switch (par.func) {
272  case NAME_OP:
273  name_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
274  break;
275  case LOCAL_OP:
276  local_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
277  break;
278  case FREE_OP:
279  free_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
280  break;
281  case DEF_OP:
282  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
283  break;
284  default:
285  RZ_LOG_ERROR("Error in store_op in pyc/opcode.c, call function %u.\n", par.func);
286  return;
287  }
288  par.op_obj[par.op_code].type |= HASSTORE;
289 }
290 
291 void(varargs_op)(struct op_parameter par) {
292  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
293  par.op_obj[par.op_code].type |= HASVARGS;
294 }
295 
296 void(const_opN)(struct op_parameter par) {
297  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
298  par.op_obj[par.op_code].type |= HASCONST;
299 }
300 
301 void(compare_op)(struct op_parameter par) {
302  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
303  par.op_obj[par.op_code].type |= HASCOMPARE;
304 }
305 
306 void(jabs_opN)(struct op_parameter par) {
307  def_op00(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push, .fallthrough = par.fallthrough);
308  par.op_obj[par.op_code].type |= HASJABS;
309  if (par.conditional) {
310  par.op_obj[par.op_code].type |= HASCONDITION;
311  }
312 }
313 
314 void(jrel_opN)(struct op_parameter par) {
315  def_op00(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push, .fallthrough = par.fallthrough);
316  par.op_obj[par.op_code].type |= HASJREL;
317  if (par.conditional) {
318  par.op_obj[par.op_code].type |= HASCONDITION;
319  }
320 }
321 
322 void(nargs_op)(struct op_parameter par) {
323  def_op(.op_obj = par.op_obj, .op_name = par.op_name, .op_code = par.op_code, .pop = par.pop, .push = par.push);
324  par.op_obj[par.op_code].type |= HASNARGS;
325 }
326 
327 void(rm_op)(struct op_parameter par) {
328  pyc_opcode_object *op_obj = &par.op_obj[par.op_code];
329  if (op_obj->op_code == par.op_code && !strcmp(op_obj->op_name, par.op_name)) {
330  free(op_obj->op_name);
331  op_obj->op_name = rz_str_newf("<%u>", par.op_code);
332  op_obj->type = op_obj->op_pop = op_obj->op_push = 0;
333  } else {
334  RZ_LOG_ERROR("Error in rm_op() while constructing opcodes for .pyc file: \n .op_code = %u, .op_name = %s", par.op_code, par.op_name);
335  }
336 }
lzma_index ** i
Definition: index.h:629
OPCODE_DESC opcodes[]
Definition: avr_esil.c:1270
#define NULL
Definition: cris-opc.c:27
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
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_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 void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
void * malloc(size_t size)
Definition: malloc.c:123
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")
void free_opcode(pyc_opcodes *opcodes)
Definition: opcode.c:217
pyc_opcodes * new_pyc_opcodes()
Definition: opcode.c:185
void() rm_op(struct op_parameter par)
Definition: opcode.c:327
void() free_opN(struct op_parameter par)
Definition: opcode.c:265
void() const_opN(struct op_parameter par)
Definition: opcode.c:296
pyc_opcodes * get_opcode_by_version(char *version)
Definition: opcode.c:169
void() local_opN(struct op_parameter par)
Definition: opcode.c:260
void() def_opN(struct op_parameter par)
Definition: opcode.c:244
void() store_opN(struct op_parameter par)
Definition: opcode.c:270
static version_opcode version_op[]
Definition: opcode.c:6
void() varargs_op(struct op_parameter par)
Definition: opcode.c:291
bool pyc_opcodes_equal(pyc_opcodes *op, const char *version)
Definition: opcode.c:151
void() compare_op(struct op_parameter par)
Definition: opcode.c:301
void() jrel_opN(struct op_parameter par)
Definition: opcode.c:314
void add_arg_fmt(pyc_opcodes *ret, char *op_name, const char *(*formatter)(ut32 oparg))
Definition: opcode.c:234
void() name_opN(struct op_parameter par)
Definition: opcode.c:255
void() jabs_opN(struct op_parameter par)
Definition: opcode.c:306
void() nargs_op(struct op_parameter par)
Definition: opcode.c:322
pyc_opcodes * opcode_24(void)
Definition: opcode_24.c:6
pyc_opcodes * opcode_15(void)
Definition: opcode_15.c:6
pyc_opcodes * opcode_12(void)
Definition: opcode_12.c:6
pyc_opcodes * opcode_37(void)
Definition: opcode_37.c:6
pyc_opcodes * opcode_32(void)
Definition: opcode_32.c:6
#define free_op(...)
Definition: opcode.h:141
#define local_op(...)
Definition: opcode.h:137
pyc_opcodes * opcode_23(void)
Definition: opcode_23.c:6
pyc_opcodes * opcode_31(void)
Definition: opcode_31.c:6
pyc_opcodes * opcode_26(void)
Definition: opcode_26.c:6
pyc_opcodes * opcode_14(void)
Definition: opcode_14.c:6
#define def_op00(...)
Definition: opcode.h:129
pyc_opcodes * opcode_25(void)
Definition: opcode_25.c:6
pyc_opcodes * opcode_11(void)
Definition: opcode_11.c:6
pyc_opcodes * opcode_38(void)
Definition: opcode_38.c:6
pyc_opcodes * opcode_27(void)
Definition: opcode_27.c:6
pyc_opcodes * opcode_21(void)
Definition: opcode_21.c:6
pyc_opcodes * opcode_13(void)
Definition: opcode_13.c:6
pyc_opcodes * opcode_10(void)
Definition: opcode_10.c:6
pyc_opcodes * opcode_16(void)
Definition: opcode_16.c:6
pyc_opcodes * opcode_39(void)
Definition: opcode_39.c:6
pyc_opcodes * opcode_33(void)
Definition: opcode_33.c:6
pyc_opcodes * opcode_34(void)
Definition: opcode_34.c:6
#define def_op(...)
Definition: opcode.h:127
pyc_opcodes * opcode_36(void)
Definition: opcode_36.c:6
pyc_opcodes * opcode_22(void)
Definition: opcode_22.c:6
pyc_opcodes * opcode_30(void)
Definition: opcode_30.c:6
pyc_opcodes * opcode_20(void)
Definition: opcode_20.c:6
@ LOCAL_OP
Definition: opcode.h:32
@ DEF_OP
Definition: opcode.h:34
@ FREE_OP
Definition: opcode.h:33
@ NAME_OP
Definition: opcode.h:31
@ HASNAME
Definition: opcode.h:23
@ HASCONDITION
Definition: opcode.h:17
@ HASCOMPARE
Definition: opcode.h:16
@ HASLOCAL
Definition: opcode.h:22
@ HASSTORE
Definition: opcode.h:25
@ HASJREL
Definition: opcode.h:21
@ HASCONST
Definition: opcode.h:18
@ NOFOLLOW
Definition: opcode.h:27
@ HASNARGS
Definition: opcode.h:24
@ HASVARGS
Definition: opcode.h:26
@ HASFREE
Definition: opcode.h:19
@ HASJABS
Definition: opcode.h:20
pyc_opcodes * opcode_35(void)
Definition: opcode_35.c:6
#define name_op(...)
Definition: opcode.h:133
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
#define RZ_NEW0(x)
Definition: rz_types.h:284
#define RZ_FREE(x)
Definition: rz_types.h:369
pyc_opcode_object * op_obj
Definition: opcode.h:117
char * op_name
Definition: opcode.h:55
const char *(* formatter)(ut32 oparg)
Definition: opcode.h:56
char * op_name
Definition: opcode.h:38
ut8 have_argument
Definition: opcode.h:47
pyc_opcode_object * opcodes
Definition: opcode.h:51
RzList * opcode_arg_fmt
Definition: opcode.h:50
pyc_opcodes *(* opcode_func)()
Definition: opcode.h:61
char * version
Definition: opcode.h:60
Definition: dis.c:32