Rizin
unix-like reverse engineering framework and cli tools
pyc_dis.c File Reference
#include "pyc_dis.h"

Go to the source code of this file.

Functions

static const char * parse_arg (pyc_opcode_object *op, ut32 oparg, RzList *names, RzList *consts, RzList *varnames, RzList *interned_table, RzList *freevars, RzList *cellvars, RzList *opcode_arg_fmt)
 
int rz_pyc_disasm (RzAsmOp *opstruct, const ut8 *code, RzList *cobjs, RzList *interned_table, ut64 pc, pyc_opcodes *ops)
 
static char * generic_array_obj_to_string (RzList *l)
 

Variables

static const char * cmp_op [] = { "<", "<=", "==", "!=", ">", ">=", "in", "not in", "is", "is not", "exception match", "BAD" }
 

Function Documentation

◆ generic_array_obj_to_string()

static char * generic_array_obj_to_string ( RzList l)
static

Definition at line 154 of file pyc_dis.c.

154  {
155  RzListIter *iter = NULL;
156  pyc_object *e = NULL;
157 
158  RzStrBuf *rbuf = rz_strbuf_new(NULL);
159 
160  rz_list_foreach (l, iter, e) {
161  rz_strbuf_append(rbuf, e->data);
162  rz_strbuf_append(rbuf, ",");
163  }
164 
165  char *buf = rz_strbuf_get(rbuf);
166 
167  /* remove last , */
168  buf[strlen(buf) - 1] = '\0';
169  char *r = rz_str_newf("(%s)", buf);
170 
171  rz_strbuf_free(rbuf);
172  return r;
173 }
#define e(frag)
#define NULL
Definition: cris-opc.c:27
#define r
Definition: crypto_rc6.c:12
voidpf void * buf
Definition: ioapi.h:138
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_API void rz_strbuf_free(RzStrBuf *sb)
Definition: strbuf.c:358

References e, NULL, r, rz_str_newf(), rz_strbuf_append(), rz_strbuf_free(), rz_strbuf_get(), and rz_strbuf_new().

Referenced by parse_arg().

◆ parse_arg()

static const char * parse_arg ( pyc_opcode_object op,
ut32  oparg,
RzList names,
RzList consts,
RzList varnames,
RzList interned_table,
RzList freevars,
RzList cellvars,
RzList opcode_arg_fmt 
)
static

Definition at line 65 of file pyc_dis.c.

65  {
66  pyc_object *t = NULL;
67  const char *arg = NULL;
68  pyc_code_object *tmp_cobj;
69  pyc_arg_fmt *fmt;
70  RzListIter *i = NULL;
71 
72  // version-specific formatter for certain opcodes
73  rz_list_foreach (opcode_arg_fmt, i, fmt)
74  if (!strcmp(fmt->op_name, op->op_name)) {
75  return fmt->formatter(oparg);
76  }
77 
78  if (op->type & HASCONST) {
79  t = (pyc_object *)rz_list_get_n(consts, oparg);
80  if (t == NULL) {
81  return NULL;
82  }
83  switch (t->type) {
84  case TYPE_CODE_v0:
85  case TYPE_CODE_v1:
86  tmp_cobj = t->data;
87  arg = rz_str_newf("CodeObject(%s) from %s", (char *)tmp_cobj->name->data, (char *)tmp_cobj->filename->data);
88  break;
89  case TYPE_TUPLE:
90  case TYPE_SET:
91  case TYPE_FROZENSET:
92  case TYPE_LIST:
93  case TYPE_SMALL_TUPLE:
95  break;
96  case TYPE_STRING:
97  case TYPE_INTERNED:
98  case TYPE_STRINGREF:
99  arg = rz_str_newf("'%s'", (char *)t->data);
100  break;
101  default:
102  arg = rz_str_new(t->data);
103  }
104  }
105  if (op->type & HASNAME) {
106  t = (pyc_object *)rz_list_get_n(names, oparg);
107  if (t == NULL) {
108  return NULL;
109  }
110  arg = rz_str_new(t->data);
111  }
112  if ((op->type & HASJREL) || (op->type & HASJABS)) {
113  arg = rz_str_newf("%u", oparg);
114  }
115  if (op->type & HASLOCAL) {
116  t = (pyc_object *)rz_list_get_n(varnames, oparg);
117  if (!t)
118  return NULL;
119  arg = rz_str_new(t->data);
120  }
121  if (op->type & HASCOMPARE) {
122  arg = rz_str_new(cmp_op[oparg]);
123  }
124  if (op->type & HASFREE) {
125  if (!cellvars || !freevars) {
126  arg = rz_str_newf("%u", oparg);
127  return arg;
128  }
129 
130  if (oparg < rz_list_length(cellvars)) {
131  t = (pyc_object *)rz_list_get_n(cellvars, oparg);
132  } else if ((oparg - rz_list_length(cellvars)) < rz_list_length(freevars)) {
133  t = (pyc_object *)rz_list_get_n(freevars, oparg);
134  } else {
135  arg = rz_str_newf("%u", oparg);
136  return arg;
137  }
138  if (!t) {
139  return NULL;
140  }
141 
142  arg = rz_str_new(t->data);
143  }
144  if (op->type & HASNARGS) {
145  arg = rz_str_newf("%u", oparg);
146  }
147  if (op->type & HASVARGS) {
148  arg = rz_str_newf("%u", oparg);
149  }
150 
151  return arg;
152 }
lzma_index ** i
Definition: index.h:629
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
@ TYPE_STRINGREF
Definition: marshal.h:38
@ TYPE_LIST
Definition: marshal.h:28
@ TYPE_TUPLE
Definition: marshal.h:41
@ TYPE_SMALL_TUPLE
Definition: marshal.h:36
@ TYPE_INTERNED
Definition: marshal.h:26
@ TYPE_CODE_v1
Definition: marshal.h:18
@ TYPE_SET
Definition: marshal.h:33
@ TYPE_CODE_v0
Definition: marshal.h:17
@ TYPE_STRING
Definition: marshal.h:39
@ TYPE_FROZENSET
Definition: marshal.h:24
@ HASNAME
Definition: opcode.h:23
@ HASCOMPARE
Definition: opcode.h:16
@ HASLOCAL
Definition: opcode.h:22
@ HASJREL
Definition: opcode.h:21
@ HASCONST
Definition: opcode.h:18
@ HASNARGS
Definition: opcode.h:24
@ HASVARGS
Definition: opcode.h:26
@ HASFREE
Definition: opcode.h:19
@ HASJABS
Definition: opcode.h:20
static char * generic_array_obj_to_string(RzList *l)
Definition: pyc_dis.c:154
static const char * cmp_op[]
Definition: pyc_dis.c:7
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
Definition: names.h:123
char * op_name
Definition: opcode.h:55
const char *(* formatter)(ut32 oparg)
Definition: opcode.h:56
pyc_object * filename
Definition: marshal.h:68
pyc_object * name
Definition: marshal.h:69
void * data
Definition: marshal.h:52
pyc_marshal_type type
Definition: marshal.h:51
Definition: dis.c:32

References arg(), cmp_op, pyc_object::data, pyc_code_object::filename, pyc_arg_fmt::formatter, generic_array_obj_to_string(), HASCOMPARE, HASCONST, HASFREE, HASJABS, HASJREL, HASLOCAL, HASNAME, HASNARGS, HASVARGS, i, pyc_code_object::name, NULL, pyc_arg_fmt::op_name, rz_list_get_n(), rz_list_length(), rz_str_new(), rz_str_newf(), pyc_object::type, TYPE_CODE_v0, TYPE_CODE_v1, TYPE_FROZENSET, TYPE_INTERNED, TYPE_LIST, TYPE_SET, TYPE_SMALL_TUPLE, TYPE_STRING, TYPE_STRINGREF, and TYPE_TUPLE.

Referenced by rz_pyc_disasm().

◆ rz_pyc_disasm()

int rz_pyc_disasm ( RzAsmOp opstruct,
const ut8 code,
RzList cobjs,
RzList interned_table,
ut64  pc,
pyc_opcodes ops 
)

Definition at line 11 of file pyc_dis.c.

11  {
12  pyc_code_object *cobj = NULL, *t = NULL;
13  ut32 i = 0, oparg;
14  st64 start_offset, end_offset;
15  RzListIter *iter = NULL;
16 
17  rz_list_foreach (cobjs, iter, t) {
18  start_offset = t->start_offset;
19  end_offset = t->end_offset;
20  if (start_offset <= pc && pc < end_offset) { // pc in [start_offset, end_offset)
21  cobj = t;
22  break;
23  }
24  }
25 
26  if (cobj) {
27  /* TODO: adding line number and offset */
28  RzList *varnames = cobj->varnames->data;
29  RzList *consts = cobj->consts->data;
30  RzList *names = cobj->names->data;
31  RzList *freevars = cobj->freevars->data;
32  RzList *cellvars = cobj->cellvars->data;
33 
34  ut8 op = code[i];
35  i++;
36  char *name = ops->opcodes[op].op_name;
37  rz_strbuf_set(&opstruct->buf_asm, name);
38  if (!name) {
39  return 0;
40  }
41  if (op >= ops->have_argument) {
42  if (ops->bits == 16) {
43  oparg = code[i] + code[i + 1] * 256;
44  i += 2;
45  } else {
46  oparg = code[i];
47  i += 1;
48  }
49  const char *arg = parse_arg(&ops->opcodes[op], oparg, names, consts, varnames, interned_table, freevars, cellvars, ops->opcode_arg_fmt);
50  if (arg != NULL) {
51  rz_strbuf_appendf(&opstruct->buf_asm, "%20s", arg);
52  free((char *)arg);
53  }
54  } else if (ops->bits == 8) {
55  i += 1;
56  }
57 
58  return i;
59  }
60  return 0;
61 }
static struct @29 ops[]
ut8 op
Definition: 6502dis.c:13
uint32_t ut32
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
uint8_t ut8
Definition: lh5801.h:11
static const char * parse_arg(pyc_opcode_object *op, ut32 oparg, RzList *names, RzList *consts, RzList *varnames, RzList *interned_table, RzList *freevars, RzList *cellvars, RzList *opcode_arg_fmt)
Definition: pyc_dis.c:65
RZ_API const char * rz_strbuf_set(RzStrBuf *sb, const char *s)
Definition: strbuf.c:153
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define st64
Definition: rz_types_base.h:10
Definition: inftree9.h:24
Definition: z80asm.h:102
pyc_object * names
Definition: marshal.h:64
pyc_object * varnames
Definition: marshal.h:65
pyc_object * freevars
Definition: marshal.h:66
pyc_object * cellvars
Definition: marshal.h:67
pyc_object * consts
Definition: marshal.h:63
RzStrBuf buf_asm
Definition: rz_asm.h:72

References rz_asm_op_t::buf_asm, pyc_code_object::cellvars, pyc_code_object::consts, pyc_object::data, free(), pyc_code_object::freevars, i, pyc_code_object::names, NULL, op, ops, parse_arg(), pc, rz_strbuf_appendf(), rz_strbuf_set(), st64, and pyc_code_object::varnames.

Referenced by disassemble().

Variable Documentation

◆ cmp_op

const char* cmp_op[] = { "<", "<=", "==", "!=", ">", ">=", "in", "not in", "is", "is not", "exception match", "BAD" }
static

Definition at line 7 of file pyc_dis.c.

Referenced by esil_branch_check_bit(), esil_branch_check_bit_imm(), and parse_arg().