Rizin
unix-like reverse engineering framework and cli tools
cil_dis.c File Reference
#include <rz_types.h>
#include <rz_asm.h>
#include <rz_endian.h>
#include <rz_util/rz_strbuf.h>
#include "cil_dis.h"
#include "opcodes_single.def"
#include "opcodes_double.def"
#include "opcodes_prefix.def"

Go to the source code of this file.

Classes

struct  CILOpcodeReader
 

Macros

#define DEF_READ_GENERIC(bytes, readtype, fmt)
 
#define read_ShortInlineVar   read_generic8
 
#define read_ShortInlineI   read_generic8
 
#define read_InlineVar   read_generic16
 
#define read_InlineI   read_generic32
 
#define read_InlineSig   read_generic32
 
#define read_InlineType   read_generic32
 
#define read_InlineField   read_generic32
 
#define read_InlineString   read_generic32
 
#define read_InlineTok   read_generic32
 
#define read_InlineI8   read_generic64
 
#define read_ShortInlineR   read_generic_float
 
#define read_InlineR   read_generic_double
 
#define OPCODE_SINGLE(name, string, param, byte, control)   [name] = { .str = string, .read_param = read_##param },
 
#define OPCODE_DOUBLE(name, string, param, byte, control)   [name] = { .str = string, .read_param = read_##param },
 
#define OPCODE_PREFIX(name, string, param, byte, control)
 

Functions

static int read_InlineNone (int *pos, CILOp *op, const ut8 *buf, int len)
 
static int read_InlineMethod (int *pos, CILOp *op, const ut8 *buf, int len)
 
static int read_InlineBrTarget (int *pos, CILOp *op, const ut8 *buf, int len)
 
static int read_ShortInlineBrTarget (int *pos, CILOp *op, const ut8 *buf, int len)
 
static int read_InlineSwitch (int *pos, CILOp *op, const ut8 *buf, int len)
 
int cil_dis (CILOp *op, const ut8 *buf, int len)
 Disassemble a CIL buffer. More...
 

Variables

static const CILOpcodeReader opcode_readers_single []
 
static const CILOpcodeReader opcode_readers_double []
 

Detailed Description

The read_## functions are dispatched based on the opcode param they take the position in by pointer and can alter it, and return a nonzero value if an error occurs

The position is always the index of the next byte to read. If, after incrementing by the number of bytes to be read, the index == the buffer length, the read has gone to the end of the buffer and should succeed. If index > buffer length, the read is past the bounds and should fail

The opcode_readers arrays include the opcode mnemonic, the appropriate parameter reader to call, and whether or not the opcode is a prefix opcode

eg. OPCODE_SINGLE(CIL_OP_NOP, "nop", InlineNone, 0x00, NEXT) -> CILOpcodeReader opcode_readers_single[] = { [CIL_OP_NOP] = { .str = "nop", .read_param = read_InlineNone }, ... }

Definition in file cil_dis.c.

Macro Definition Documentation

◆ DEF_READ_GENERIC

#define DEF_READ_GENERIC (   bytes,
  readtype,
  fmt 
)
Value:
static int read_generic##readtype(int *pos, CILOp *op, const ut8 *buf, int len) { \
if (*pos + bytes > len) { \
return -1; \
} \
rz_strbuf_appendf(&op->strbuf, fmt, rz_read_at_le##readtype(buf, *pos)); \
*pos += bytes; \
return 0; \
}
size_t len
Definition: 6502dis.c:15
static ut8 bytes[32]
Definition: asm_arc.c:23
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
Definition: cil_dis.h:27
int pos
Definition: main.c:11
Definition: dis.c:32

Definition at line 23 of file cil_dis.c.

◆ OPCODE_DOUBLE

#define OPCODE_DOUBLE (   name,
  string,
  param,
  byte,
  control 
)    [name] = { .str = string, .read_param = read_##param },

Definition at line 134 of file cil_dis.c.

◆ OPCODE_PREFIX

#define OPCODE_PREFIX (   name,
  string,
  param,
  byte,
  control 
)
Value:
[name] = { \
.prefix = true, \
.str = string, \
.read_param = read_##param \
},
const char * name
Definition: op.c:541
#define read_(fd, buf, count)
Definition: sdb_private.h:19

Definition at line 135 of file cil_dis.c.

◆ OPCODE_SINGLE

#define OPCODE_SINGLE (   name,
  string,
  param,
  byte,
  control 
)    [name] = { .str = string, .read_param = read_##param },

Definition at line 128 of file cil_dis.c.

◆ read_InlineField

#define read_InlineField   read_generic32

Definition at line 53 of file cil_dis.c.

◆ read_InlineI

#define read_InlineI   read_generic32

Definition at line 50 of file cil_dis.c.

◆ read_InlineI8

#define read_InlineI8   read_generic64

Definition at line 57 of file cil_dis.c.

◆ read_InlineR

#define read_InlineR   read_generic_double

Definition at line 60 of file cil_dis.c.

◆ read_InlineSig

#define read_InlineSig   read_generic32

Definition at line 51 of file cil_dis.c.

◆ read_InlineString

#define read_InlineString   read_generic32

Definition at line 54 of file cil_dis.c.

◆ read_InlineTok

#define read_InlineTok   read_generic32

Definition at line 55 of file cil_dis.c.

◆ read_InlineType

#define read_InlineType   read_generic32

Definition at line 52 of file cil_dis.c.

◆ read_InlineVar

#define read_InlineVar   read_generic16

Definition at line 48 of file cil_dis.c.

◆ read_ShortInlineI

#define read_ShortInlineI   read_generic8

Definition at line 46 of file cil_dis.c.

◆ read_ShortInlineR

#define read_ShortInlineR   read_generic_float

Definition at line 59 of file cil_dis.c.

◆ read_ShortInlineVar

#define read_ShortInlineVar   read_generic8

Definition at line 45 of file cil_dis.c.

Function Documentation

◆ cil_dis()

int cil_dis ( CILOp op,
const ut8 buf,
int  len 
)

Disassemble a CIL buffer.

Returns
0 on success, -1 on fail

Definition at line 150 of file cil_dis.c.

150  {
151  int pos = 0;
152  if (pos >= len) { // pos + 1 > len
153  return -1;
154  }
155 
156  ut8 byte;
157  rz_strbuf_init(&op->strbuf);
158 
159 start: // Taken after a prefix opcode has been consumed
160  byte = buf[pos++];
161 
162  CILOpcodeReader opcode_reader;
163  if (byte != 0xFE) { // Single-byte
164  op->byte1 = byte;
165  opcode_reader = opcode_readers_single[byte];
166  } else { // Double-byte
167  if (pos >= len) { // pos + 1 > len
168  return -1; // OOB
169  }
170 
171  op->byte1 = byte;
172  op->byte2 = byte = buf[pos++];
173  opcode_reader = opcode_readers_double[byte];
174  }
175 
176  if (!opcode_reader.str) {
177  return -1; // Invalid
178  }
179 
180  // Mnemonic
181  if (!rz_strbuf_append(&op->strbuf, opcode_reader.str)) {
182  return -1;
183  }
184 
185  // Dispatch based on opcode `param`
186  if (opcode_reader.read_param(&pos, op, buf, len)) {
187  return -1;
188  }
189 
190  if (opcode_reader.prefix) {
191  if (!rz_strbuf_append(&op->strbuf, " ")) { // extra space
192  return -1;
193  }
194  goto start; // continue
195  }
196 
197  op->size = pos;
198  return 0;
199 }
static const CILOpcodeReader opcode_readers_single[]
Definition: cil_dis.c:129
static const CILOpcodeReader opcode_readers_double[]
Definition: cil_dis.c:140
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API void rz_strbuf_init(RzStrBuf *sb)
Definition: strbuf.c:33
char * str
Definition: cil_dis.c:111
int(* read_param)(int *pos, CILOp *op, const ut8 *buf, int len)
Definition: cil_dis.c:112

References len, opcode_readers_double, opcode_readers_single, pos, CILOpcodeReader::prefix, CILOpcodeReader::read_param, rz_strbuf_append(), rz_strbuf_init(), start, and CILOpcodeReader::str.

Referenced by cil_analyze_op(), and disassemble().

◆ read_InlineBrTarget()

static int read_InlineBrTarget ( int pos,
CILOp op,
const ut8 buf,
int  len 
)
static

Definition at line 74 of file cil_dis.c.

74  {
75  if (*pos + sizeof(st32) > len) {
76  return -1;
77  }
78  st32 target = rz_read_at_le32(buf, *pos);
79  rz_strbuf_appendf(&op->strbuf, " %d", target);
80  op->target = target;
81  *pos += sizeof(st32);
82  return 0;
83 }
static ut32 rz_read_at_le32(const void *src, size_t offset)
Definition: rz_endian.h:248
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define st32
Definition: rz_types_base.h:12

References len, pos, rz_read_at_le32(), rz_strbuf_appendf(), and st32.

◆ read_InlineMethod()

static int read_InlineMethod ( int pos,
CILOp op,
const ut8 buf,
int  len 
)
static

Definition at line 63 of file cil_dis.c.

63  {
64  if (*pos + sizeof(ut32) > len) {
65  return -1;
66  }
67  ut32 tok = rz_read_at_le32(buf, *pos);
68  rz_strbuf_appendf(&op->strbuf, " 0x%X", tok);
69  op->tok = tok;
70  *pos += sizeof(ut32);
71  return 0;
72 }
uint32_t ut32

References len, pos, rz_read_at_le32(), and rz_strbuf_appendf().

◆ read_InlineNone()

static int read_InlineNone ( int pos,
CILOp op,
const ut8 buf,
int  len 
)
static

Definition at line 41 of file cil_dis.c.

41  {
42  return 0;
43 }

◆ read_InlineSwitch()

static int read_InlineSwitch ( int pos,
CILOp op,
const ut8 buf,
int  len 
)
static

Definition at line 96 of file cil_dis.c.

96  {
97  if (*pos + sizeof(ut32) > len) {
98  return -1;
99  }
100 
102  *pos += sizeof(ut32);
103  if (*pos + count * 4 > len) {
104  return -1;
105  }
106  *pos += count * 4;
107  return 0;
108 }
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
static ut32 rz_read_le32(const void *src)
Definition: rz_endian.h:239

References count, len, pos, and rz_read_le32().

◆ read_ShortInlineBrTarget()

static int read_ShortInlineBrTarget ( int pos,
CILOp op,
const ut8 buf,
int  len 
)
static

Definition at line 85 of file cil_dis.c.

85  {
86  if (*pos + sizeof(st8) > len) {
87  return -1;
88  }
89  st8 target = rz_read_at_le8(buf, *pos);
90  rz_strbuf_appendf(&op->strbuf, " %hhd", target);
91  op->target = target;
92  *pos += sizeof(st8);
93  return 0;
94 }
static ut8 rz_read_at_le8(const void *src, size_t offset)
Definition: rz_endian.h:194
#define st8
Definition: rz_types_base.h:16

References len, pos, rz_read_at_le8(), rz_strbuf_appendf(), and st8.

Variable Documentation

◆ opcode_readers_double

const CILOpcodeReader opcode_readers_double[]
static
Initial value:
= {
[0xFF] = { 0 }
}

Definition at line 140 of file cil_dis.c.

Referenced by cil_dis().

◆ opcode_readers_single

const CILOpcodeReader opcode_readers_single[]
static
Initial value:
= {
[0xFF] = { 0 }
}

Definition at line 129 of file cil_dis.c.

Referenced by cil_dis().