Rizin
unix-like reverse engineering framework and cli tools
analysis_pyc.c File Reference
#include <rz_types.h>
#include <rz_lib.h>
#include <rz_util.h>
#include <rz_asm.h>
#include "../../asm/arch/pyc/pyc_dis.h"

Go to the source code of this file.

Functions

static int archinfo (RzAnalysis *analysis, int query)
 
static char * get_reg_profile (RzAnalysis *analysis)
 
static RzListget_pyc_code_obj (RzAnalysis *analysis)
 
static int pyc_op (RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
 
static bool finish (void *user)
 

Variables

RzAnalysisPlugin rz_analysis_plugin_pyc
 
RZ_API RzLibStruct rizin_plugin
 

Function Documentation

◆ archinfo()

static int archinfo ( RzAnalysis analysis,
int  query 
)
static

Definition at line 11 of file analysis_pyc.c.

11  {
12  if (!strcmp(analysis->cpu, "x86")) {
13  return -1;
14  }
15 
16  switch (query) {
18  return (analysis->bits == 16) ? 1 : 2;
20  return (analysis->bits == 16) ? 3 : 2;
21  default:
22  return -1;
23  }
24 }
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE
Definition: rz_analysis.h:99
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98

References rz_analysis_t::bits, rz_analysis_t::cpu, RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE, and RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE.

◆ finish()

static bool finish ( void *  user)
static

Definition at line 133 of file analysis_pyc.c.

133  {
134  pyc_opcodes *ops = (user);
135  free_opcode(ops);
136  return true;
137 }
static struct @29 ops[]
void free_opcode(pyc_opcodes *opcodes)
Definition: opcode.c:217

References free_opcode(), and ops.

Referenced by core_perform_auto_analysis(), dupl(), p_b_term(), repeat(), and stream_encode_in().

◆ get_pyc_code_obj()

static RzList* get_pyc_code_obj ( RzAnalysis analysis)
static

Definition at line 38 of file analysis_pyc.c.

38  {
39  RzBin *b = analysis->binb.bin;
40  RzBinPlugin *plugin = b->cur && b->cur->o ? b->cur->o->plugin : NULL;
41  bool is_pyc = (plugin && strcmp(plugin->name, "pyc") == 0);
42  if (!is_pyc) {
43  return NULL;
44  }
45  return ((RzBinPycObj *)b->cur->o->bin_obj)->shared;
46 }
#define NULL
Definition: cris-opc.c:27
#define b(i)
Definition: sha256.c:42
RzBinBind binb
Definition: rz_analysis.h:579
RzBin * bin
Definition: rz_bin.h:807
char * name
Definition: rz_bin.h:509

References b, rz_bin_bind_t::bin, rz_analysis_t::binb, rz_bin_plugin_t::name, and NULL.

Referenced by pyc_op().

◆ get_reg_profile()

static char* get_reg_profile ( RzAnalysis analysis)
static

Definition at line 26 of file analysis_pyc.c.

26  {
27  return strdup(
28  "=PC pc\n"
29  "=BP bp\n"
30  "=SP sp\n"
31  "=A0 sp\n"
32  "gpr sp .32 0 0\n" // stack pointer
33  "gpr pc .32 4 0\n" // program counter
34  "gpr bp .32 8 0\n" // base pointer // unused
35  );
36 }
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")

References strdup().

◆ pyc_op()

static int pyc_op ( RzAnalysis a,
RzAnalysisOp op,
ut64  addr,
const ut8 data,
int  len,
RzAnalysisOpMask  mask 
)
static

Definition at line 48 of file analysis_pyc.c.

48  {
49  pyc_opcodes *ops = (pyc_opcodes *)a->plugin_data;
50  RzList *cobjs = rz_list_get_n(get_pyc_code_obj(a), 0);
51  RzListIter *iter = NULL;
52  pyc_code_object *func = NULL, *t = NULL;
53  rz_list_foreach (cobjs, iter, t) {
54  if (RZ_BETWEEN(t->start_offset, addr, t->end_offset - 1)) { // addr in [start_offset, end_offset)
55  func = t;
56  break;
57  }
58  }
59  if (!func) {
60  return -1;
61  }
62 
63  ut64 func_base = func->start_offset;
64  ut32 extended_arg = 0, oparg = 0;
65  ut8 op_code = data[0];
66  op->addr = addr;
67  op->sign = true;
69  op->id = op_code;
70 
71  if (!pyc_opcodes_equal(ops, a->cpu)) {
73  ops = NULL;
74  }
75 
76  if (!ops) {
77  if (!(ops = get_opcode_by_version(a->cpu))) {
78  return -1;
79  }
80  a->plugin_data = ops;
81  }
82  bool is_python36 = a->bits == 8;
83  pyc_opcode_object *op_obj = &ops->opcodes[op_code];
84  if (!op_obj->op_name) {
86  op->size = 1;
87  goto analysis_end;
88  }
89 
90  op->size = is_python36 ? 2 : ((op_code >= ops->have_argument) ? 3 : 1);
91 
92  if (op_code >= ops->have_argument) {
93  if (!is_python36) {
94  oparg = data[1] + data[2] * 256 + extended_arg;
95  } else {
96  oparg = data[1] + extended_arg;
97  }
98  }
99 
100  if (op_obj->type & HASJABS) {
101  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
102  op->jump = func_base + oparg;
103 
104  if (op_obj->type & HASCONDITION) {
106  op->fail = addr + ((is_python36) ? 2 : 3);
107  }
108  goto analysis_end;
109  }
110  if (op_obj->type & HASJREL) {
111  op->type = RZ_ANALYSIS_OP_TYPE_JMP;
112  op->jump = addr + oparg + ((is_python36) ? 2 : 3);
113  op->fail = addr + ((is_python36) ? 2 : 3);
114 
115  if (op_obj->type & HASCONDITION) {
117  // op->fail = addr + ((is_python36)? 2: 3);
118  }
119  // goto analysis_end;
120  }
121 
122  if (op_obj->type & HASCOMPARE) {
123  op->type = RZ_ANALYSIS_OP_TYPE_CMP;
124  goto analysis_end;
125  }
126 
127  analysis_pyc_op(op, op_obj, oparg);
128 
129 analysis_end:
130  return op->size;
131 }
static RzList * get_pyc_code_obj(RzAnalysis *analysis)
Definition: analysis_pyc.c:38
uint32_t ut32
uint8_t ut8
Definition: lh5801.h:11
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
pyc_opcodes * get_opcode_by_version(char *version)
Definition: opcode.c:169
bool pyc_opcodes_equal(pyc_opcodes *op, const char *version)
Definition: opcode.c:151
void analysis_pyc_op(RzAnalysisOp *op, pyc_opcode_object *op_obj, ut32 oparg)
@ HASCONDITION
Definition: opcode.h:17
@ HASCOMPARE
Definition: opcode.h:16
@ HASJREL
Definition: opcode.h:21
@ HASJABS
Definition: opcode.h:20
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
#define RZ_BETWEEN(x, y, z)
#define a(i)
Definition: sha256.c:41
Definition: dis.c:12
st64 start_offset
Definition: marshal.h:72
char * op_name
Definition: opcode.h:38
Definition: dis.c:32
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static int addr
Definition: z80asm.c:58

References a, addr, analysis_pyc_op(), free_opcode(), get_opcode_by_version(), get_pyc_code_obj(), HASCOMPARE, HASCONDITION, HASJABS, HASJREL, NULL, pyc_opcode_object::op_name, ops, pyc_opcodes_equal(), RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CMP, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_BETWEEN, rz_list_get_n(), pyc_code_object::start_offset, pyc_opcode_object::type, and ut64().

Variable Documentation

◆ rizin_plugin

RZ_API RzLibStruct rizin_plugin
Initial value:
= {
}
RzAnalysisPlugin rz_analysis_plugin_pyc
Definition: analysis_pyc.c:139
@ RZ_LIB_TYPE_ANALYSIS
Definition: rz_lib.h:73
#define RZ_VERSION
Definition: rz_version.h:8
const char * version
Definition: rz_analysis.h:1239

Definition at line 153 of file analysis_pyc.c.

◆ rz_analysis_plugin_pyc

RzAnalysisPlugin rz_analysis_plugin_pyc
Initial value:
= {
.name = "pyc",
.desc = "Python bytecode analysis plugin",
.license = "LGPL3",
.arch = "pyc",
.bits = 16 | 8,
.archinfo = archinfo,
.get_reg_profile = get_reg_profile,
.op = &pyc_op,
.esil = false,
.fini = &finish,
}
static char * get_reg_profile(RzAnalysis *analysis)
Definition: analysis_pyc.c:26
static int pyc_op(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: analysis_pyc.c:48
static bool finish(void *user)
Definition: analysis_pyc.c:133
static int archinfo(RzAnalysis *analysis, int query)
Definition: analysis_pyc.c:11

Definition at line 139 of file analysis_pyc.c.