RzAnalysisILVM wraps around the low-level RzILVM and enables emulation of real code from disassembly, rather than raw IL. Analysis plugins now don't actively initialize the vm anymore, but return a fully declarative description RzAnalysisILConfig of how to set up the vm and optionally its initial state. This also enables multiple IL vms to exist at the same time as plugins can not mess with the global vm anymore. See the added integration test for an example.
2304 lines
103 KiB
C
2304 lines
103 KiB
C
// SPDX-FileCopyrightText: 2009-2021 nibble <nibble.ds@gmail.com>
|
|
// SPDX-FileCopyrightText: 2009-2021 pancake <pancake@nopcode.org>
|
|
// SPDX-FileCopyrightText: 2009-2021 xvilka <anton.kochkov@gmail.com>
|
|
// SPDX-License-Identifier: LGPL-3.0-only
|
|
|
|
#ifndef RZ_ANALYSIS_H
|
|
#define RZ_ANALYSIS_H
|
|
|
|
/* use old refs and function storage */
|
|
// still required by core in lot of places
|
|
#define USE_VARSUBS 0
|
|
|
|
#include <rz_types.h>
|
|
#include <rz_io.h>
|
|
#include <rz_reg.h>
|
|
#include <rz_list.h>
|
|
#include <rz_search.h>
|
|
#include <rz_util.h>
|
|
#include <rz_bind.h>
|
|
#include <rz_syscall.h>
|
|
#include <set.h>
|
|
#include <rz_flag.h>
|
|
#include <rz_bin.h>
|
|
#include <rz_type.h>
|
|
#include <rz_il.h>
|
|
#include <rz_arch.h>
|
|
#include <rz_cmd.h>
|
|
|
|
#define esilprintf(op, fmt, ...) rz_strbuf_setf(&op->esil, fmt, ##__VA_ARGS__)
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
RZ_LIB_VERSION_HEADER(rz_analysis);
|
|
|
|
/* dwarf processing context */
|
|
typedef struct rz_analysis_dwarf_context {
|
|
const RzBinDwarfDebugInfo *info;
|
|
HtUP /*<offset, RzBinDwarfLocList*>*/ *loc;
|
|
// const RzBinDwarfCfa *cfa; TODO
|
|
} RzAnalysisDwarfContext;
|
|
|
|
// TODO: save memory2 : fingerprints must be pointers to a buffer
|
|
// containing a dupped file in memory
|
|
|
|
/* save memory:
|
|
bb_has_ops=1 -> 600M
|
|
bb_has_ops=0 -> 350MB
|
|
*/
|
|
|
|
typedef struct {
|
|
struct rz_analysis_t *analysis;
|
|
int type;
|
|
int rad;
|
|
SdbForeachCallback cb;
|
|
void *user;
|
|
int count;
|
|
struct rz_analysis_function_t *fcn;
|
|
PJ *pj;
|
|
} RzAnalysisMetaUserItem;
|
|
|
|
typedef struct rz_analysis_range_t {
|
|
ut64 from;
|
|
ut64 to;
|
|
int bits;
|
|
ut64 rb_max_addr;
|
|
RBNode rb;
|
|
} RzAnalysisRange;
|
|
|
|
#define RZ_ANALYSIS_GET_OFFSET(x, y, z) \
|
|
(x && x->binb.bin && x->binb.get_offset) ? x->binb.get_offset(x->binb.bin, y, z) : -1
|
|
enum {
|
|
RZ_ANALYSIS_DATA_TYPE_NULL = 0,
|
|
RZ_ANALYSIS_DATA_TYPE_UNKNOWN = 1,
|
|
RZ_ANALYSIS_DATA_TYPE_STRING = 2,
|
|
RZ_ANALYSIS_DATA_TYPE_WIDE_STRING = 3,
|
|
RZ_ANALYSIS_DATA_TYPE_POINTER = 4,
|
|
RZ_ANALYSIS_DATA_TYPE_NUMBER = 5,
|
|
RZ_ANALYSIS_DATA_TYPE_INVALID = 6,
|
|
RZ_ANALYSIS_DATA_TYPE_HEADER = 7,
|
|
RZ_ANALYSIS_DATA_TYPE_SEQUENCE = 8,
|
|
RZ_ANALYSIS_DATA_TYPE_PATTERN = 9,
|
|
};
|
|
|
|
// used from core/analysis.c
|
|
#define RZ_ANALYSIS_ADDR_TYPE_EXEC 1
|
|
#define RZ_ANALYSIS_ADDR_TYPE_READ 1 << 1
|
|
#define RZ_ANALYSIS_ADDR_TYPE_WRITE 1 << 2
|
|
#define RZ_ANALYSIS_ADDR_TYPE_FLAG 1 << 3
|
|
#define RZ_ANALYSIS_ADDR_TYPE_FUNC 1 << 4
|
|
#define RZ_ANALYSIS_ADDR_TYPE_HEAP 1 << 5
|
|
#define RZ_ANALYSIS_ADDR_TYPE_STACK 1 << 6
|
|
#define RZ_ANALYSIS_ADDR_TYPE_REG 1 << 7
|
|
#define RZ_ANALYSIS_ADDR_TYPE_PROGRAM 1 << 8
|
|
#define RZ_ANALYSIS_ADDR_TYPE_LIBRARY 1 << 9
|
|
#define RZ_ANALYSIS_ADDR_TYPE_ASCII 1 << 10
|
|
#define RZ_ANALYSIS_ADDR_TYPE_SEQUENCE 1 << 11
|
|
|
|
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE 0
|
|
#define RZ_ANALYSIS_ARCHINFO_MAX_OP_SIZE 1
|
|
#define RZ_ANALYSIS_ARCHINFO_ALIGN 2
|
|
#define RZ_ANALYSIS_ARCHINFO_DATA_ALIGN 4
|
|
|
|
/* copypaste from rz_asm.h */
|
|
|
|
#define RZ_ANALYSIS_GET_OFFSET(x, y, z) \
|
|
(x && x->binb.bin && x->binb.get_offset) ? x->binb.get_offset(x->binb.bin, y, z) : -1
|
|
|
|
#define RZ_ANALYSIS_GET_NAME(x, y, z) \
|
|
(x && x->binb.bin && x->binb.get_name) ? x->binb.get_name(x->binb.bin, y, z) : NULL
|
|
|
|
/* type = (RZ_ANALYSIS_VAR_TYPE_BYTE & RZ_ANALYSIS_VAR_TYPE_SIZE_MASK) |
|
|
* ( RANAL_VAR_TYPE_SIGNED & RANAL_VAR_TYPE_SIGN_MASK) |
|
|
* ( RANAL_VAR_TYPE_CONST & RANAL_VAR_TYPE_MODIFIER_MASK)
|
|
*/
|
|
typedef struct rz_analysis_type_var_t {
|
|
char *name;
|
|
int index;
|
|
int scope;
|
|
ut16 type; // contain (type || signedness || modifier)
|
|
ut8 size;
|
|
union {
|
|
ut8 v8;
|
|
ut16 v16;
|
|
ut32 v32;
|
|
ut64 v64;
|
|
} value;
|
|
} RzAnalysisTypeVar;
|
|
|
|
typedef struct rz_analysis_type_ptr_t {
|
|
char *name;
|
|
ut16 type; // contain (type || signedness || modifier)
|
|
ut8 size;
|
|
union {
|
|
ut8 v8;
|
|
ut16 v16;
|
|
ut32 v32;
|
|
ut64 v64;
|
|
} value;
|
|
} RzAnalysisTypePtr;
|
|
|
|
typedef struct rz_analysis_type_array_t {
|
|
char *name;
|
|
ut16 type; // contain (type || signedness || modifier)
|
|
ut8 size;
|
|
ut64 count;
|
|
union {
|
|
ut8 *v8;
|
|
ut16 *v16;
|
|
ut32 *v32;
|
|
ut64 *v64;
|
|
} value;
|
|
} RzAnalysisTypeArray;
|
|
|
|
typedef struct rz_analysis_type_struct_t RzAnalysisTypeStruct;
|
|
typedef struct rz_analysis_type_t RzAnalysisType;
|
|
|
|
struct rz_analysis_type_struct_t {
|
|
char *name;
|
|
ut8 type;
|
|
ut32 size;
|
|
void *parent;
|
|
RzAnalysisType *items;
|
|
};
|
|
|
|
typedef struct rz_analysis_type_union_t {
|
|
char *name;
|
|
ut8 type;
|
|
ut32 size;
|
|
void *parent;
|
|
RzAnalysisType *items;
|
|
} RzAnalysisTypeUnion;
|
|
|
|
typedef struct rz_analysis_type_alloca_t {
|
|
long address;
|
|
long size;
|
|
void *parent;
|
|
RzAnalysisType *items;
|
|
} RzAnalysisTypeAlloca;
|
|
|
|
enum {
|
|
RZ_ANALYSIS_FQUALIFIER_NONE = 0,
|
|
RZ_ANALYSIS_FQUALIFIER_STATIC = 1,
|
|
RZ_ANALYSIS_FQUALIFIER_VOLATILE = 2,
|
|
RZ_ANALYSIS_FQUALIFIER_INLINE = 3,
|
|
RZ_ANALYSIS_FQUALIFIER_NAKED = 4,
|
|
RZ_ANALYSIS_FQUALIFIER_VIRTUAL = 5,
|
|
};
|
|
|
|
#define RZ_ANALYSIS_CC_MAXARG 16
|
|
|
|
enum {
|
|
RZ_ANALYSIS_FCN_TYPE_NULL = 0,
|
|
RZ_ANALYSIS_FCN_TYPE_FCN = 1 << 0,
|
|
RZ_ANALYSIS_FCN_TYPE_LOC = 1 << 1,
|
|
RZ_ANALYSIS_FCN_TYPE_SYM = 1 << 2,
|
|
RZ_ANALYSIS_FCN_TYPE_IMP = 1 << 3,
|
|
RZ_ANALYSIS_FCN_TYPE_INT = 1 << 4, /* privileged function - ends with iret/reti/.. */
|
|
RZ_ANALYSIS_FCN_TYPE_ROOT = 1 << 5, /* matching flag */
|
|
RZ_ANALYSIS_FCN_TYPE_ANY = -1 /* all the bits set */
|
|
};
|
|
|
|
#define RZ_ANALYSIS_DIFF_THRESHOLD (0.5)
|
|
|
|
#define RzAnalysisBlock struct rz_analysis_bb_t
|
|
|
|
enum {
|
|
RZ_ANALYSIS_DIFF_TYPE_NULL = 0,
|
|
RZ_ANALYSIS_DIFF_TYPE_MATCH = 'm',
|
|
RZ_ANALYSIS_DIFF_TYPE_UNMATCH = 'u'
|
|
};
|
|
|
|
typedef struct rz_analysis_diff_t {
|
|
int type;
|
|
ut64 addr;
|
|
double dist;
|
|
char *name;
|
|
ut32 size;
|
|
} RzAnalysisDiff;
|
|
|
|
typedef struct rz_analysis_attr_t RzAnalysisAttr;
|
|
|
|
struct rz_analysis_attr_t {
|
|
char *key;
|
|
long value;
|
|
RzAnalysisAttr *next;
|
|
};
|
|
|
|
/* Stores useful function metadata */
|
|
/* TODO: Think about moving more stuff to this structure? */
|
|
typedef struct rz_analysis_fcn_meta_t {
|
|
// _min and _max are calculated lazily when queried.
|
|
// On changes, they will either be updated (if this can be done trivially) or invalidated.
|
|
// They are invalid iff _min == UT64_MAX.
|
|
ut64 _min; // PRIVATE, min address, use rz_analysis_function_min_addr() to access
|
|
ut64 _max; // PRIVATE, max address, use rz_analysis_function_max_addr() to access
|
|
|
|
int numrefs; // number of cross references
|
|
int numcallrefs; // number of calls
|
|
} RzAnalysisFcnMeta;
|
|
|
|
typedef struct rz_analysis_function_t {
|
|
char *name;
|
|
int bits; // ((> bits 0) (set-bits bits))
|
|
int type;
|
|
const char *cc; // calling convention, should come from RzAnalysis.constpool
|
|
ut64 addr;
|
|
HtUP /*<ut64, char *>*/ *labels;
|
|
HtPP /*<char *, ut64 *>*/ *label_addrs;
|
|
RzPVector vars;
|
|
RzType *ret_type;
|
|
HtUP /*<st64, RzPVector<RzAnalysisVar *>>*/ *inst_vars; // offset of instructions => the variables they access
|
|
ut64 reg_save_area; // size of stack area pre-reserved for saving registers
|
|
st64 bp_off; // offset of bp inside owned stack frame
|
|
st64 stack; // stack frame size
|
|
int maxstack;
|
|
int ninstr;
|
|
bool is_pure;
|
|
bool is_variadic;
|
|
bool has_changed; // true if function may have changed since last anaysis TODO: set this attribute where necessary
|
|
bool bp_frame;
|
|
bool is_noreturn; // true if function does not return
|
|
ut8 *fingerprint; // TODO: make is fuzzy and smarter
|
|
int argnum; // number of arguments;
|
|
size_t fingerprint_size;
|
|
RzAnalysisDiff *diff;
|
|
RzList *bbs; // TODO: should be RzPVector
|
|
RzAnalysisFcnMeta meta;
|
|
RzList *imports; // maybe bound to class?
|
|
struct rz_analysis_t *analysis; // this function is associated with this instance
|
|
} RzAnalysisFunction;
|
|
|
|
typedef struct rz_analysis_func_arg_t {
|
|
const char *name;
|
|
const char *fmt;
|
|
const char *cc_source;
|
|
RzType *orig_c_type;
|
|
RzType *c_type;
|
|
ut64 size;
|
|
ut64 src; // Function-call argument value or pointer to it
|
|
} RzAnalysisFuncArg;
|
|
|
|
struct rz_analysis_type_t {
|
|
char *name;
|
|
ut32 type;
|
|
ut32 size;
|
|
RzList *content;
|
|
};
|
|
|
|
typedef enum {
|
|
RZ_META_TYPE_ANY = -1,
|
|
RZ_META_TYPE_DATA = 'd', //< marks the data as data (not a code)
|
|
RZ_META_TYPE_CODE = 'c', //< marks the data as code
|
|
RZ_META_TYPE_STRING = 's', //< marks the data as string
|
|
RZ_META_TYPE_FORMAT = 'f', //< sets the specified format (pf) to the data
|
|
RZ_META_TYPE_MAGIC = 'm', //< sets the magic string to the data
|
|
RZ_META_TYPE_HIDE = 'h', //< set the data as hidden
|
|
RZ_META_TYPE_COMMENT = 'C', //< attaches the comment to the data
|
|
RZ_META_TYPE_HIGHLIGHT = 'H', //< sets the specified highlight to the data
|
|
RZ_META_TYPE_VARTYPE = 't', //< sets the specified type to the variable/address
|
|
} RzAnalysisMetaType;
|
|
|
|
/* meta */
|
|
typedef struct rz_analysis_meta_item_t {
|
|
RzAnalysisMetaType type;
|
|
int subtype;
|
|
char *str;
|
|
size_t size;
|
|
const RzSpace *space;
|
|
} RzAnalysisMetaItem;
|
|
|
|
// anal
|
|
typedef enum {
|
|
RZ_ANALYSIS_OP_FAMILY_UNKNOWN = -1,
|
|
RZ_ANALYSIS_OP_FAMILY_CPU = 0, /* normal cpu instruction */
|
|
RZ_ANALYSIS_OP_FAMILY_FPU, /* fpu (floating point) */
|
|
RZ_ANALYSIS_OP_FAMILY_MMX, /* multimedia instruction (packed data) */
|
|
RZ_ANALYSIS_OP_FAMILY_SSE, /* extended multimedia instruction (packed data) */
|
|
RZ_ANALYSIS_OP_FAMILY_PRIV, /* privileged instruction */
|
|
RZ_ANALYSIS_OP_FAMILY_CRYPTO, /* cryptographic instructions */
|
|
RZ_ANALYSIS_OP_FAMILY_THREAD, /* thread/lock/sync instructions */
|
|
RZ_ANALYSIS_OP_FAMILY_VIRT, /* virtualization instructions */
|
|
RZ_ANALYSIS_OP_FAMILY_SECURITY, /* security instructions */
|
|
RZ_ANALYSIS_OP_FAMILY_IO, /* IO instructions (i.e. IN/OUT) */
|
|
RZ_ANALYSIS_OP_FAMILY_LAST
|
|
} RzAnalysisOpFamily;
|
|
|
|
#if 0
|
|
On x86 according to Wikipedia
|
|
|
|
Prefix group 1
|
|
0xF0: LOCK prefix
|
|
0xF2: REPNE/REPNZ prefix
|
|
0xF3: REP or REPE/REPZ prefix
|
|
Prefix group 2
|
|
0x2E: CS segment override
|
|
0x36: SS segment override
|
|
0x3E: DS segment override
|
|
0x26: ES segment override
|
|
0x64: FS segment override
|
|
0x65: GS segment override
|
|
0x2E: Branch not taken (hinting)
|
|
0x3E: Branch taken
|
|
Prefix group 3
|
|
0x66: Operand-size override prefix
|
|
Prefix group 4
|
|
0x67: Address-size override prefix
|
|
#endif
|
|
typedef enum {
|
|
RZ_ANALYSIS_OP_PREFIX_COND = 1,
|
|
RZ_ANALYSIS_OP_PREFIX_REP = 1 << 1,
|
|
RZ_ANALYSIS_OP_PREFIX_REPNE = 1 << 2,
|
|
RZ_ANALYSIS_OP_PREFIX_LOCK = 1 << 3,
|
|
RZ_ANALYSIS_OP_PREFIX_LIKELY = 1 << 4,
|
|
RZ_ANALYSIS_OP_PREFIX_UNLIKELY = 1 << 5,
|
|
RZ_ANALYSIS_OP_PREFIX_HWLOOP_END = 1 << 6, /* Hexagon specific. Last instruction in a hardware loop */
|
|
/* TODO: add segment override typemods? */
|
|
} RzAnalysisOpPrefix;
|
|
|
|
// XXX: this definition is plain wrong. use enum or empower bits
|
|
#define RZ_ANALYSIS_OP_TYPE_MASK 0x8000ffff
|
|
#define RZ_ANALYSIS_OP_HINT_MASK 0xf0000000
|
|
typedef enum {
|
|
RZ_ANALYSIS_OP_TYPE_COND = 0x80000000, // TODO must be moved to prefix?
|
|
// TODO: MOVE TO PREFIX .. it is used by analysis_java.. must be updated
|
|
RZ_ANALYSIS_OP_TYPE_REP = 0x40000000, /* repeats next instruction N times */
|
|
RZ_ANALYSIS_OP_TYPE_MEM = 0x20000000, // TODO must be moved to prefix?
|
|
RZ_ANALYSIS_OP_TYPE_REG = 0x10000000, // operand is a register
|
|
RZ_ANALYSIS_OP_TYPE_IND = 0x08000000, // operand is indirect
|
|
RZ_ANALYSIS_OP_TYPE_NULL = 0,
|
|
RZ_ANALYSIS_OP_TYPE_JMP = 1, /* mandatory jump */
|
|
RZ_ANALYSIS_OP_TYPE_UJMP = 2, /* unknown jump (register or so) */
|
|
RZ_ANALYSIS_OP_TYPE_RJMP = RZ_ANALYSIS_OP_TYPE_REG | RZ_ANALYSIS_OP_TYPE_UJMP,
|
|
RZ_ANALYSIS_OP_TYPE_IJMP = RZ_ANALYSIS_OP_TYPE_IND | RZ_ANALYSIS_OP_TYPE_UJMP,
|
|
RZ_ANALYSIS_OP_TYPE_IRJMP = RZ_ANALYSIS_OP_TYPE_IND | RZ_ANALYSIS_OP_TYPE_REG | RZ_ANALYSIS_OP_TYPE_UJMP,
|
|
RZ_ANALYSIS_OP_TYPE_CJMP = RZ_ANALYSIS_OP_TYPE_COND | RZ_ANALYSIS_OP_TYPE_JMP, /* conditional jump */
|
|
RZ_ANALYSIS_OP_TYPE_RCJMP = RZ_ANALYSIS_OP_TYPE_REG | RZ_ANALYSIS_OP_TYPE_CJMP, /* conditional jump register */
|
|
RZ_ANALYSIS_OP_TYPE_MJMP = RZ_ANALYSIS_OP_TYPE_MEM | RZ_ANALYSIS_OP_TYPE_JMP, /* memory jump */
|
|
RZ_ANALYSIS_OP_TYPE_MCJMP = RZ_ANALYSIS_OP_TYPE_MEM | RZ_ANALYSIS_OP_TYPE_CJMP, /* memory conditional jump */
|
|
RZ_ANALYSIS_OP_TYPE_UCJMP = RZ_ANALYSIS_OP_TYPE_COND | RZ_ANALYSIS_OP_TYPE_UJMP, /* conditional unknown jump */
|
|
RZ_ANALYSIS_OP_TYPE_CALL = 3, /* call to subroutine (branch+link) */
|
|
RZ_ANALYSIS_OP_TYPE_UCALL = 4, /* unknown call (register or so) */
|
|
RZ_ANALYSIS_OP_TYPE_RCALL = RZ_ANALYSIS_OP_TYPE_REG | RZ_ANALYSIS_OP_TYPE_UCALL,
|
|
RZ_ANALYSIS_OP_TYPE_ICALL = RZ_ANALYSIS_OP_TYPE_IND | RZ_ANALYSIS_OP_TYPE_UCALL,
|
|
RZ_ANALYSIS_OP_TYPE_IRCALL = RZ_ANALYSIS_OP_TYPE_IND | RZ_ANALYSIS_OP_TYPE_REG | RZ_ANALYSIS_OP_TYPE_UCALL,
|
|
RZ_ANALYSIS_OP_TYPE_CCALL = RZ_ANALYSIS_OP_TYPE_COND | RZ_ANALYSIS_OP_TYPE_CALL, /* conditional call to subroutine */
|
|
RZ_ANALYSIS_OP_TYPE_UCCALL = RZ_ANALYSIS_OP_TYPE_COND | RZ_ANALYSIS_OP_TYPE_UCALL, /* conditional unknown call */
|
|
RZ_ANALYSIS_OP_TYPE_RET = 5, /* returns from subroutine */
|
|
RZ_ANALYSIS_OP_TYPE_CRET = RZ_ANALYSIS_OP_TYPE_COND | RZ_ANALYSIS_OP_TYPE_RET, /* conditional return from subroutine */
|
|
RZ_ANALYSIS_OP_TYPE_ILL = 6, /* illegal instruction // trap */
|
|
RZ_ANALYSIS_OP_TYPE_UNK = 7, /* unknown opcode type */
|
|
RZ_ANALYSIS_OP_TYPE_NOP = 8, /* does nothing */
|
|
RZ_ANALYSIS_OP_TYPE_MOV = 9, /* register move */
|
|
RZ_ANALYSIS_OP_TYPE_CMOV = 9 | RZ_ANALYSIS_OP_TYPE_COND, /* conditional move */
|
|
RZ_ANALYSIS_OP_TYPE_TRAP = 10, /* it's a trap! */
|
|
RZ_ANALYSIS_OP_TYPE_SWI = 11, /* syscall, software interrupt */
|
|
RZ_ANALYSIS_OP_TYPE_CSWI = 11 | RZ_ANALYSIS_OP_TYPE_COND, /* syscall, software interrupt */
|
|
RZ_ANALYSIS_OP_TYPE_UPUSH = 12, /* unknown push of data into stack */
|
|
RZ_ANALYSIS_OP_TYPE_RPUSH = RZ_ANALYSIS_OP_TYPE_UPUSH | RZ_ANALYSIS_OP_TYPE_REG, /* push register */
|
|
RZ_ANALYSIS_OP_TYPE_PUSH = 13, /* push value into stack */
|
|
RZ_ANALYSIS_OP_TYPE_POP = 14, /* pop value from stack to register */
|
|
RZ_ANALYSIS_OP_TYPE_CMP = 15, /* compare something */
|
|
RZ_ANALYSIS_OP_TYPE_ACMP = 16, /* compare via and */
|
|
RZ_ANALYSIS_OP_TYPE_ADD = 17,
|
|
RZ_ANALYSIS_OP_TYPE_SUB = 18,
|
|
RZ_ANALYSIS_OP_TYPE_IO = 19,
|
|
RZ_ANALYSIS_OP_TYPE_MUL = 20,
|
|
RZ_ANALYSIS_OP_TYPE_DIV = 21,
|
|
RZ_ANALYSIS_OP_TYPE_SHR = 22,
|
|
RZ_ANALYSIS_OP_TYPE_SHL = 23,
|
|
RZ_ANALYSIS_OP_TYPE_SAL = 24,
|
|
RZ_ANALYSIS_OP_TYPE_SAR = 25,
|
|
RZ_ANALYSIS_OP_TYPE_OR = 26,
|
|
RZ_ANALYSIS_OP_TYPE_AND = 27,
|
|
RZ_ANALYSIS_OP_TYPE_XOR = 28,
|
|
RZ_ANALYSIS_OP_TYPE_NOR = 29,
|
|
RZ_ANALYSIS_OP_TYPE_NOT = 30,
|
|
RZ_ANALYSIS_OP_TYPE_STORE = 31, /* store from register to memory */
|
|
RZ_ANALYSIS_OP_TYPE_LOAD = 32, /* load from memory to register */
|
|
RZ_ANALYSIS_OP_TYPE_LEA = 33, /* TODO add ulea */
|
|
RZ_ANALYSIS_OP_TYPE_LEAVE = 34,
|
|
RZ_ANALYSIS_OP_TYPE_ROR = 35,
|
|
RZ_ANALYSIS_OP_TYPE_ROL = 36,
|
|
RZ_ANALYSIS_OP_TYPE_XCHG = 37,
|
|
RZ_ANALYSIS_OP_TYPE_MOD = 38,
|
|
RZ_ANALYSIS_OP_TYPE_SWITCH = 39,
|
|
RZ_ANALYSIS_OP_TYPE_CASE = 40,
|
|
RZ_ANALYSIS_OP_TYPE_LENGTH = 41,
|
|
RZ_ANALYSIS_OP_TYPE_CAST = 42,
|
|
RZ_ANALYSIS_OP_TYPE_NEW = 43,
|
|
RZ_ANALYSIS_OP_TYPE_ABS = 44,
|
|
RZ_ANALYSIS_OP_TYPE_CPL = 45, /* complement */
|
|
RZ_ANALYSIS_OP_TYPE_CRYPTO = 46,
|
|
RZ_ANALYSIS_OP_TYPE_SYNC = 47,
|
|
// RZ_ANALYSIS_OP_TYPE_DEBUG = 43, // monitor/trace/breakpoint
|
|
#if 0
|
|
RZ_ANALYSIS_OP_TYPE_PRIV = 40, /* privileged instruction */
|
|
RZ_ANALYSIS_OP_TYPE_FPU = 41, /* floating point stuff */
|
|
#endif
|
|
} _RzAnalysisOpType;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_OP_MASK_BASIC = 0, // Just fills basic op info , it's fast
|
|
RZ_ANALYSIS_OP_MASK_ESIL = 1, // It fills RzAnalysisop->esil info
|
|
RZ_ANALYSIS_OP_MASK_VAL = 2, // It fills RzAnalysisop->dst/src info
|
|
RZ_ANALYSIS_OP_MASK_HINT = 4, // It calls rz_analysis_op_hint to override analysis options
|
|
RZ_ANALYSIS_OP_MASK_OPEX = 8, // It fills RzAnalysisop->opex info
|
|
RZ_ANALYSIS_OP_MASK_DISASM = 16, // It fills RzAnalysisop->mnemonic // should be RzAnalysisOp->disasm // only from rz_core_analysis_op()
|
|
RZ_ANALYSIS_OP_MASK_ALL = 1 | 2 | 4 | 8 | 16
|
|
} RzAnalysisOpMask;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_VAR_SCOPE_LOCAL = 0x01
|
|
} _RzAnalysisVarScope;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_STACK_NULL = 0,
|
|
RZ_ANALYSIS_STACK_NOP,
|
|
RZ_ANALYSIS_STACK_INC,
|
|
RZ_ANALYSIS_STACK_GET,
|
|
RZ_ANALYSIS_STACK_SET,
|
|
RZ_ANALYSIS_STACK_RESET,
|
|
RZ_ANALYSIS_STACK_ALIGN,
|
|
} RzAnalysisStackOp;
|
|
|
|
enum {
|
|
RZ_ANALYSIS_REFLINE_TYPE_UTF8 = 1,
|
|
RZ_ANALYSIS_REFLINE_TYPE_WIDE = 2, /* reflines have a space between them */
|
|
RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_BEFORE = 4, /* do not consider starts/ends of
|
|
* reflines (used for comment lines before disasm) */
|
|
RZ_ANALYSIS_REFLINE_TYPE_MIDDLE_AFTER = 8 /* as above but for lines after disasm */
|
|
};
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_RET_NOP = 0,
|
|
RZ_ANALYSIS_RET_ERROR = -1, // Basic block ended because of analysis error.
|
|
RZ_ANALYSIS_RET_END = -4, // Basic block ended because of return instruction.
|
|
RZ_ANALYSIS_RET_BRANCH = -5, // Basic block ended because of branch instruction.
|
|
RZ_ANALYSIS_RET_COND = -6, // Basic block ended because of conditional return.
|
|
} RzAnalysisBBEndCause;
|
|
|
|
typedef struct rz_analysis_case_obj_t {
|
|
ut64 addr;
|
|
ut64 jump;
|
|
ut64 value;
|
|
} RzAnalysisCaseOp;
|
|
|
|
typedef struct rz_analysis_switch_obj_t {
|
|
ut64 addr;
|
|
ut64 min_val;
|
|
ut64 def_val;
|
|
ut64 max_val;
|
|
RzList /*<RzAnalysisCaseOp>*/ *cases;
|
|
} RzAnalysisSwitchOp;
|
|
|
|
struct rz_analysis_t;
|
|
struct rz_analysis_bb_t;
|
|
typedef struct rz_analysis_callbacks_t {
|
|
int (*on_fcn_new)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn);
|
|
int (*on_fcn_delete)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn);
|
|
int (*on_fcn_rename)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn, const char *oldname);
|
|
int (*on_fcn_bb_new)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn, struct rz_analysis_bb_t *bb);
|
|
} RzAnalysisCallbacks;
|
|
|
|
#define RZ_ANALYSIS_ESIL_GOTO_LIMIT 4096
|
|
|
|
typedef struct rz_analysis_options_t {
|
|
int depth;
|
|
int graph_depth;
|
|
bool vars; // analysisyze local var and arguments
|
|
bool varname_stack; // name vars based on their offset in the stack
|
|
int cjmpref;
|
|
int jmpref;
|
|
int jmpabove;
|
|
bool ijmp;
|
|
bool jmpmid; // continue analysis after jmp into middle of insn
|
|
bool loads;
|
|
bool ignbithints;
|
|
int followdatarefs;
|
|
int searchstringrefs;
|
|
int followbrokenfcnsrefs;
|
|
int bb_max_size;
|
|
bool trycatch;
|
|
bool norevisit;
|
|
int afterjmp; // continue analysis after jmp eax or forward jmp // option
|
|
int aftertrap; // continue analysis after trap instructions
|
|
int recont; // continue on recurse analysis mode
|
|
int noncode;
|
|
int nopskip; // skip nops at the beginning of functions
|
|
int hpskip; // skip `mov reg,reg` and `lea reg,[reg]`
|
|
int jmptbl; // analyze jump tables
|
|
int jmptbl_maxcount; // maximum amount of entries to analyse in a jump table
|
|
int nonull;
|
|
bool pushret; // analyze push+ret as jmp
|
|
bool armthumb; //
|
|
bool endsize; // chop function size which is known to be buggy but goodie too
|
|
bool delay;
|
|
int tailcall;
|
|
bool retpoline;
|
|
} RzAnalysisOptions;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_CPP_ABI_ITANIUM = 0,
|
|
RZ_ANALYSIS_CPP_ABI_MSVC
|
|
} RzAnalysisCPPABI;
|
|
|
|
typedef struct rz_analysis_hint_cb_t {
|
|
// add more cbs as needed
|
|
void (*on_bits)(struct rz_analysis_t *a, ut64 addr, int bits, bool set);
|
|
} RHintCb;
|
|
|
|
typedef struct rz_analysis_il_vm_t RzAnalysisILVM;
|
|
|
|
typedef struct rz_analysis_t {
|
|
char *cpu; // analysis.cpu
|
|
char *os; // asm.os
|
|
int bits; // asm.bits
|
|
int lineswidth; // asm.lines.width
|
|
int big_endian; // cfg.bigendian
|
|
int sleep; // analysis.sleep, sleep some usecs before analyzing more (avoid 100% cpu usages)
|
|
RzAnalysisCPPABI cpp_abi; // analysis.cpp.abi
|
|
void *plugin_data;
|
|
void *core;
|
|
ut64 gp; // analysis.gp, global pointer. used for mips. but can be used by other arches too in the future
|
|
RBTree bb_tree; // all basic blocks by address. They can overlap each other, but must never start at the same address.
|
|
RzList *fcns;
|
|
HtUP *ht_addr_fun; // address => function
|
|
HtPP *ht_name_fun; // name => function
|
|
RzReg *reg;
|
|
ut8 *last_disasm_reg;
|
|
RzSyscall *syscall;
|
|
int diff_ops;
|
|
double diff_thbb;
|
|
double diff_thfcn;
|
|
RzIOBind iob;
|
|
RzFlagBind flb;
|
|
RzFlagSet flg_class_set;
|
|
RzFlagGet flg_class_get;
|
|
RzFlagSet flg_fcn_set;
|
|
RzBinBind binb; // Set only from core when an analysis plugin is called.
|
|
RzCoreBind coreb;
|
|
int maxreflines; // asm.lines.maxref
|
|
int esil_goto_limit; // esil.gotolimit
|
|
int pcalign; // asm.pcalign
|
|
struct rz_analysis_esil_t *esil;
|
|
RzAnalysisILVM *il_vm; ///< user-faced VM, NEVER use this for any analysis passes!
|
|
struct rz_analysis_plugin_t *cur;
|
|
RzAnalysisRange *limit; // analysis.from, analysis.to
|
|
RzList *plugins;
|
|
Sdb *sdb_noret;
|
|
Sdb *sdb_fmts;
|
|
Sdb *sdb_zigns;
|
|
HtUP *ht_xrefs_from;
|
|
HtUP *ht_xrefs_to;
|
|
bool recursive_noreturn; // analysis.rnr
|
|
RzSpaces zign_spaces;
|
|
char *zign_path; // dir.zigns
|
|
PrintfCallback cb_printf;
|
|
// moved from RzAnalysisFcn
|
|
Sdb *sdb; // root
|
|
HtUP /*<RzVector<RzAnalysisAddrHintRecord>>*/ *addr_hints; // all hints that correspond to a single address
|
|
RBTree /*<RzAnalysisArchHintRecord>*/ arch_hints;
|
|
RBTree /*<RzAnalysisArchBitsRecord>*/ bits_hints;
|
|
RHintCb hint_cbs;
|
|
RzIntervalTree meta;
|
|
RzSpaces meta_spaces;
|
|
RzTypeDB *typedb; // Types management
|
|
HtUP *type_links; // Type links to the memory address or register
|
|
Sdb *sdb_cc; // calling conventions
|
|
Sdb *sdb_classes;
|
|
Sdb *sdb_classes_attrs;
|
|
RzAnalysisCallbacks cb;
|
|
RzAnalysisOptions opt;
|
|
RzList *reflines;
|
|
// RzList *noreturn;
|
|
RzListComparator columnSort;
|
|
int stackptr;
|
|
bool (*log)(struct rz_analysis_t *analysis, const char *msg);
|
|
bool (*read_at)(struct rz_analysis_t *analysis, ut64 addr, ut8 *buf, int len);
|
|
bool verbose;
|
|
int seggrn;
|
|
RzFlagGetAtAddr flag_get;
|
|
RzEvent *ev;
|
|
RzList /*<char *>*/ *imports; // global imports
|
|
SetU *visited;
|
|
RzStrConstPool constpool;
|
|
RzList *leaddrs;
|
|
RzArchTarget *arch_target;
|
|
RzArchPlatformTarget *platform_target;
|
|
HtPP *ht_global_var; // global variables
|
|
RBTree global_var_tree; // global variables by address. must not overlap
|
|
} RzAnalysis;
|
|
|
|
typedef enum rz_analysis_addr_hint_type_t {
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_JUMP,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_FAIL,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_STACKFRAME,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_PTR,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_RET,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_NEW_BITS,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_SIZE,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_SYNTAX,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_OPTYPE,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_OPCODE,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH,
|
|
RZ_ANALYSIS_ADDR_HINT_TYPE_VAL
|
|
} RzAnalysisAddrHintType;
|
|
|
|
typedef struct rz_analysis_addr_hint_record_t {
|
|
RzAnalysisAddrHintType type;
|
|
union {
|
|
char *type_offset;
|
|
int nword;
|
|
ut64 jump;
|
|
ut64 fail;
|
|
int newbits;
|
|
int immbase;
|
|
ut64 ptr;
|
|
ut64 retval;
|
|
char *syntax;
|
|
char *opcode;
|
|
char *esil;
|
|
int optype;
|
|
ut64 size;
|
|
ut64 stackframe;
|
|
ut64 val;
|
|
};
|
|
} RzAnalysisAddrHintRecord;
|
|
|
|
typedef struct rz_analysis_hint_t {
|
|
ut64 addr;
|
|
ut64 ptr;
|
|
ut64 val; // used to hint jmp rax
|
|
ut64 jump;
|
|
ut64 fail;
|
|
ut64 ret; // hint for function ret values
|
|
char *arch;
|
|
char *opcode;
|
|
char *syntax;
|
|
char *esil;
|
|
char *offset;
|
|
ut32 type;
|
|
ut64 size;
|
|
int bits;
|
|
int new_bits; // change asm.bits after evaluating this instruction
|
|
int immbase;
|
|
bool high; // highlight hint
|
|
int nword;
|
|
ut64 stackframe;
|
|
} RzAnalysisHint;
|
|
|
|
typedef RzAnalysisFunction *(*RzAnalysisGetFcnIn)(RzAnalysis *analysis, ut64 addr, int type);
|
|
typedef RzAnalysisHint *(*RzAnalysisGetHint)(RzAnalysis *analysis, ut64 addr);
|
|
|
|
typedef struct rz_analysis_bind_t {
|
|
RzAnalysis *analysis;
|
|
RzAnalysisGetFcnIn get_fcn_in;
|
|
RzAnalysisGetHint get_hint;
|
|
} RzAnalysisBind;
|
|
|
|
typedef const char *(*RzAnalysisLabelAt)(RzAnalysisFunction *fcn, ut64);
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_VAR_KIND_REG = 'r',
|
|
RZ_ANALYSIS_VAR_KIND_BPV = 'b',
|
|
RZ_ANALYSIS_VAR_KIND_SPV = 's'
|
|
} RzAnalysisVarKind;
|
|
|
|
#define VARPREFIX "var"
|
|
#define ARGPREFIX "arg"
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_VAR_ACCESS_TYPE_PTR = 0,
|
|
RZ_ANALYSIS_VAR_ACCESS_TYPE_READ = (1 << 0),
|
|
RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE = (1 << 1)
|
|
} RzAnalysisVarAccessType;
|
|
|
|
typedef struct rz_analysis_var_access_t {
|
|
const char *reg; // register used for access
|
|
st64 offset; // relative to the function's entrypoint
|
|
st64 stackptr; // delta added to register to get the var, e.g. [rbp - 0x10]
|
|
ut8 type; // RzAnalysisVarAccessType bits
|
|
} RzAnalysisVarAccess;
|
|
|
|
// generic for args and locals
|
|
typedef struct rz_analysis_var_t {
|
|
RzAnalysisFunction *fcn;
|
|
char *name; // name of the variable
|
|
RzAnalysisVarKind kind;
|
|
bool isarg;
|
|
int delta; /* delta offset inside stack frame */
|
|
char *regname; // name of the register
|
|
RzVector /*<RzAnalysisVarAccess>*/ accesses; // ordered by offset, touch this only through API or expect uaf
|
|
char *comment;
|
|
RzVector /*<RzTypeConstraint>*/ constraints;
|
|
RzType *type; // var type
|
|
|
|
// below members are just for caching, TODO: remove them and do it better
|
|
int argnum;
|
|
} RzAnalysisVar;
|
|
|
|
/**
|
|
* \brief Global variables
|
|
*/
|
|
typedef struct rz_analysis_var_global_t {
|
|
RBNode rb; ///< RBTree node for address management
|
|
char *name; ///< name of the variable
|
|
ut64 addr; ///< address of the global variable
|
|
RzType *type; ///< type of the variable
|
|
RzVector /*<RzTypeConstraint>*/ constraints;
|
|
RZ_BORROW RzAnalysis *analysis; ///< analysis pertaining to this global variable
|
|
} RzAnalysisVarGlobal;
|
|
|
|
// Refers to a variable or a struct field inside a variable, only for varsub
|
|
RZ_DEPRECATE typedef struct rz_analysis_var_field_t {
|
|
char *name;
|
|
st64 delta;
|
|
bool field;
|
|
} RzAnalysisVarField;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_ACC_UNKNOWN = 0,
|
|
RZ_ANALYSIS_ACC_R = (1 << 0),
|
|
RZ_ANALYSIS_ACC_W = (1 << 1),
|
|
} RzAnalysisValueAccess;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_VAL_UNK,
|
|
RZ_ANALYSIS_VAL_REG,
|
|
RZ_ANALYSIS_VAL_MEM,
|
|
RZ_ANALYSIS_VAL_IMM,
|
|
} RzAnalysisValueType;
|
|
|
|
// base+reg+regdelta*mul+delta
|
|
typedef struct rz_analysis_value_t {
|
|
RzAnalysisValueType type;
|
|
RzAnalysisValueAccess access;
|
|
int absolute; // if true, unsigned cast is used
|
|
int memref; // is memory reference? which size? 1, 2 ,4, 8
|
|
ut64 base; // numeric address
|
|
st64 delta; // numeric delta
|
|
st64 imm; // immediate value
|
|
int mul; // multiplier (reg*4+base)
|
|
RzRegItem *seg; // segment selector register
|
|
RzRegItem *reg; // register / register base used (-1 if no reg)
|
|
RzRegItem *regdelta; // register index used (-1 if no reg)
|
|
ut64 plugin_specific; // Can be used differently by each analysis plugin.
|
|
} RzAnalysisValue;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_OP_DIR_READ = 1,
|
|
RZ_ANALYSIS_OP_DIR_WRITE = 2,
|
|
RZ_ANALYSIS_OP_DIR_EXEC = 4,
|
|
RZ_ANALYSIS_OP_DIR_REF = 8,
|
|
} RzAnalysisOpDirection;
|
|
|
|
typedef enum rz_analysis_data_type_t {
|
|
RZ_ANALYSIS_DATATYPE_NULL = 0,
|
|
RZ_ANALYSIS_DATATYPE_ARRAY,
|
|
RZ_ANALYSIS_DATATYPE_OBJECT, // instance
|
|
RZ_ANALYSIS_DATATYPE_STRING,
|
|
RZ_ANALYSIS_DATATYPE_CLASS,
|
|
RZ_ANALYSIS_DATATYPE_BOOLEAN,
|
|
RZ_ANALYSIS_DATATYPE_INT16,
|
|
RZ_ANALYSIS_DATATYPE_INT32,
|
|
RZ_ANALYSIS_DATATYPE_INT64,
|
|
RZ_ANALYSIS_DATATYPE_FLOAT,
|
|
} RzAnalysisDataType;
|
|
|
|
typedef RzILOpEffect *RzAnalysisLiftedILOp;
|
|
|
|
typedef struct rz_analysis_op_t {
|
|
char *mnemonic; /* mnemonic.. it actually contains the args too, we should replace rasm with this */
|
|
ut64 addr; /* address */
|
|
ut32 type; /* type of opcode */
|
|
RzAnalysisOpPrefix prefix; /* type of opcode prefix (rep,lock,..) */
|
|
ut32 type2; /* used by java */
|
|
RzAnalysisStackOp stackop; /* operation on stack? */
|
|
RzTypeCond cond; /* condition type */
|
|
int size; /* size in bytes of opcode */
|
|
int nopcode; /* number of bytes representing the opcode (not the arguments) TODO: find better name */
|
|
int cycles; /* cpu-cycles taken by instruction */
|
|
int failcycles; /* conditional cpu-cycles */
|
|
RzAnalysisOpFamily family; /* family of opcode */
|
|
int id; /* instruction id */
|
|
bool eob; /* end of block (boolean) */
|
|
bool sign; /* operates on signed values, false by default */
|
|
/* Run N instructions before executing the current one */
|
|
int delay; /* delay N slots (mips, ..)*/
|
|
ut64 jump; /* true jmp */
|
|
ut64 fail; /* false jmp */
|
|
RzAnalysisOpDirection direction;
|
|
st64 ptr; /* reference to memory */ /* XXX signed? */
|
|
ut64 val; /* reference to value */ /* XXX signed? */
|
|
RzAnalysisValue analysis_vals[6]; /* Analyzable values */
|
|
int ptrsize; /* f.ex: zero extends for 8, 16 or 32 bits only */
|
|
st64 stackptr; /* stack pointer */
|
|
int refptr; /* if (0) ptr = "reference" else ptr = "load memory of refptr bytes" */
|
|
ut64 mmio_address; // mmio address
|
|
RzAnalysisValue *src[3];
|
|
RzAnalysisValue *dst;
|
|
RzList *access; /* RzAnalysisValue access information */
|
|
RzStrBuf esil;
|
|
RzStrBuf opex;
|
|
RzAnalysisLiftedILOp il_op;
|
|
const char *reg; /* destination register */
|
|
const char *ireg; /* register used for indirect memory computation*/
|
|
int scale;
|
|
ut64 disp;
|
|
RzAnalysisSwitchOp *switch_op;
|
|
RzAnalysisHint hint;
|
|
RzAnalysisDataType datatype;
|
|
} RzAnalysisOp;
|
|
|
|
#define RZ_TYPE_COND_SINGLE(x) (!x->arg[1] || x->arg[0] == x->arg[1])
|
|
|
|
typedef struct rz_analysis_cond_t {
|
|
RzTypeCond type; // filled by CJMP opcode
|
|
RzAnalysisValue *arg[2]; // filled by CMP opcode
|
|
} RzAnalysisCond;
|
|
|
|
typedef struct rz_analysis_bb_t {
|
|
RBNode _rb; // private, node in the RBTree
|
|
ut64 _max_end; // private, augmented value for RBTree
|
|
|
|
ut64 addr;
|
|
ut64 size;
|
|
ut64 jump;
|
|
ut64 fail;
|
|
bool traced;
|
|
ut32 colorize;
|
|
ut8 *fingerprint;
|
|
RzAnalysisDiff *diff;
|
|
RzAnalysisCond *cond;
|
|
RzAnalysisSwitchOp *switch_op;
|
|
ut16 *op_pos; // offsets of instructions in this block, count is ninstr - 1 (first is always 0)
|
|
ut8 *op_bytes;
|
|
ut8 *parent_reg_arena;
|
|
int op_pos_size; // size of the op_pos array
|
|
int ninstr;
|
|
int stackptr;
|
|
int parent_stackptr;
|
|
ut64 cmpval;
|
|
const char *cmpreg;
|
|
ut32 bbhash; // calculated with xxhash
|
|
|
|
RzList *fcns;
|
|
RzAnalysis *analysis;
|
|
int ref;
|
|
#undef RzAnalysisBlock
|
|
} RzAnalysisBlock;
|
|
|
|
typedef struct rz_analysis_task_item {
|
|
RzAnalysisFunction *fcn; // current function
|
|
RzAnalysisBlock *block; // block being analyzed
|
|
st64 stack; // stack pointer value for variable analysis
|
|
ut64 start_address; // if block = NULL, creates block at address, else continues analysis from here
|
|
} RzAnalysisTaskItem;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_REF_TYPE_NULL = 0,
|
|
RZ_ANALYSIS_REF_TYPE_CODE = 'c', // code ref
|
|
RZ_ANALYSIS_REF_TYPE_CALL = 'C', // code ref (call)
|
|
RZ_ANALYSIS_REF_TYPE_DATA = 'd', // mem ref
|
|
RZ_ANALYSIS_REF_TYPE_STRING = 's' // string ref
|
|
} RzAnalysisXRefType;
|
|
|
|
typedef struct rz_analysis_ref_t {
|
|
ut64 from;
|
|
ut64 to;
|
|
RzAnalysisXRefType type;
|
|
} RzAnalysisXRef;
|
|
RZ_API const char *rz_analysis_ref_type_tostring(RzAnalysisXRefType t);
|
|
|
|
/* represents a reference line from one address (from) to another (to) */
|
|
typedef struct rz_analysis_refline_t {
|
|
ut64 from;
|
|
ut64 to;
|
|
int index;
|
|
int level;
|
|
int type;
|
|
int direction;
|
|
} RzAnalysisRefline;
|
|
|
|
typedef struct rz_analysis_cycle_frame_t {
|
|
ut64 naddr; // next addr
|
|
RzList *hooks;
|
|
struct rz_analysis_cycle_frame_t *prev;
|
|
} RzAnalysisCycleFrame;
|
|
|
|
typedef struct rz_analysis_cycle_hook_t { // rename ?
|
|
ut64 addr;
|
|
int cycles;
|
|
} RzAnalysisCycleHook;
|
|
|
|
typedef struct rz_analysis_esil_word_t {
|
|
int type;
|
|
const char *str;
|
|
} RzAnalysisEsilWord;
|
|
|
|
// only flags that affect control flow
|
|
enum {
|
|
RZ_ANALYSIS_ESIL_FLAG_ZERO = 1,
|
|
RZ_ANALYSIS_ESIL_FLAG_CARRY = 2,
|
|
RZ_ANALYSIS_ESIL_FLAG_OVERFLOW = 4,
|
|
RZ_ANALYSIS_ESIL_FLAG_PARITY = 8,
|
|
RZ_ANALYSIS_ESIL_FLAG_SIGN = 16,
|
|
// ...
|
|
};
|
|
|
|
enum {
|
|
RZ_ANALYSIS_TRAP_NONE = 0,
|
|
RZ_ANALYSIS_TRAP_UNHANDLED = 1,
|
|
RZ_ANALYSIS_TRAP_BREAKPOINT = 2,
|
|
RZ_ANALYSIS_TRAP_DIVBYZERO = 3,
|
|
RZ_ANALYSIS_TRAP_WRITE_ERR = 4,
|
|
RZ_ANALYSIS_TRAP_READ_ERR = 5,
|
|
RZ_ANALYSIS_TRAP_EXEC_ERR = 6,
|
|
RZ_ANALYSIS_TRAP_INVALID = 7,
|
|
RZ_ANALYSIS_TRAP_UNALIGNED = 8,
|
|
RZ_ANALYSIS_TRAP_TODO = 9,
|
|
RZ_ANALYSIS_TRAP_HALT = 10,
|
|
};
|
|
|
|
enum {
|
|
RZ_ANALYSIS_ESIL_PARM_INVALID = 0,
|
|
RZ_ANALYSIS_ESIL_PARM_REG,
|
|
RZ_ANALYSIS_ESIL_PARM_NUM,
|
|
};
|
|
|
|
typedef struct rz_analysis_ref_char {
|
|
char *str;
|
|
char *cols;
|
|
} RzAnalysisRefStr;
|
|
|
|
// must be a char
|
|
#define ESIL_INTERNAL_PREFIX '$'
|
|
#define ESIL_STACK_NAME "esil.ram"
|
|
#define ANALYSIS_ESIL struct rz_analysis_esil_t
|
|
|
|
typedef struct rz_analysis_esil_source_t {
|
|
ut32 id;
|
|
ut32 claimed;
|
|
void *content;
|
|
} RzAnalysisEsilSource;
|
|
|
|
RZ_API void rz_analysis_esil_sources_init(ANALYSIS_ESIL *esil);
|
|
RZ_API ut32 rz_analysis_esil_load_source(ANALYSIS_ESIL *esil, const char *path);
|
|
RZ_API void *rz_analysis_esil_get_source(ANALYSIS_ESIL *esil, ut32 src_id);
|
|
RZ_API bool rz_analysis_esil_claim_source(ANALYSIS_ESIL *esil, ut32 src_id);
|
|
RZ_API void rz_analysis_esil_release_source(ANALYSIS_ESIL *esil, ut32 src_id);
|
|
RZ_API void rz_analysis_esil_sources_fini(ANALYSIS_ESIL *esil);
|
|
|
|
typedef bool (*RzAnalysisEsilInterruptCB)(ANALYSIS_ESIL *esil, ut32 interrupt, void *user);
|
|
|
|
typedef struct rz_analysis_esil_interrupt_handler_t {
|
|
const ut32 num;
|
|
const char *name;
|
|
void *(*init)(ANALYSIS_ESIL *esil);
|
|
RzAnalysisEsilInterruptCB cb;
|
|
void (*fini)(void *user);
|
|
} RzAnalysisEsilInterruptHandler;
|
|
|
|
typedef struct rz_analysis_esil_change_reg_t {
|
|
int idx;
|
|
ut64 data;
|
|
} RzAnalysisEsilRegChange;
|
|
|
|
typedef struct rz_analysis_esil_change_mem_t {
|
|
int idx;
|
|
ut8 data;
|
|
} RzAnalysisEsilMemChange;
|
|
|
|
typedef struct rz_analysis_esil_trace_t {
|
|
int idx;
|
|
int end_idx;
|
|
HtUP *registers;
|
|
HtUP *memory;
|
|
RzRegArena *arena[RZ_REG_TYPE_LAST];
|
|
ut64 stack_addr;
|
|
ut64 stack_size;
|
|
ut8 *stack_data;
|
|
// RzVector<RzILTraceInstruction>
|
|
RzPVector *instructions;
|
|
} RzAnalysisEsilTrace;
|
|
|
|
typedef int (*RzAnalysisEsilHookRegWriteCB)(ANALYSIS_ESIL *esil, const char *name, ut64 *val);
|
|
|
|
typedef struct rz_analysis_esil_callbacks_t {
|
|
void *user;
|
|
/* callbacks */
|
|
int (*hook_flag_read)(ANALYSIS_ESIL *esil, const char *flag, ut64 *num);
|
|
int (*hook_command)(ANALYSIS_ESIL *esil, const char *op);
|
|
int (*hook_mem_read)(ANALYSIS_ESIL *esil, ut64 addr, ut8 *buf, int len);
|
|
int (*mem_read)(ANALYSIS_ESIL *esil, ut64 addr, ut8 *buf, int len);
|
|
int (*hook_mem_write)(ANALYSIS_ESIL *esil, ut64 addr, const ut8 *buf, int len);
|
|
int (*mem_write)(ANALYSIS_ESIL *esil, ut64 addr, const ut8 *buf, int len);
|
|
int (*hook_reg_read)(ANALYSIS_ESIL *esil, const char *name, ut64 *res, int *size);
|
|
int (*reg_read)(ANALYSIS_ESIL *esil, const char *name, ut64 *res, int *size);
|
|
RzAnalysisEsilHookRegWriteCB hook_reg_write;
|
|
int (*reg_write)(ANALYSIS_ESIL *esil, const char *name, ut64 val);
|
|
} RzAnalysisEsilCallbacks;
|
|
|
|
typedef struct rz_analysis_esil_t {
|
|
RzAnalysis *analysis;
|
|
char **stack;
|
|
ut64 addrmask;
|
|
int stacksize;
|
|
int stackptr;
|
|
ut32 skip;
|
|
int nowrite;
|
|
int iotrap;
|
|
int exectrap;
|
|
int repeat;
|
|
int parse_stop;
|
|
int parse_goto;
|
|
int parse_goto_count;
|
|
int verbose;
|
|
ut64 flags;
|
|
ut64 address;
|
|
ut64 stack_addr;
|
|
ut32 stack_size;
|
|
int delay; // mapped to $ds in ESIL
|
|
ut64 jump_target; // mapped to $jt in ESIL
|
|
int jump_target_set; // mapped to $js in ESIL
|
|
int trap;
|
|
ut32 trap_code; // extend into a struct to store more exception info?
|
|
// parity flag? done with cur
|
|
ut64 old; // used for carry-flagging and borrow-flagging
|
|
ut64 cur; // used for carry-flagging and borrow-flagging
|
|
ut8 lastsz; // in bits //used for signature-flag
|
|
/* native ops and custom ops */
|
|
HtPP *ops;
|
|
RzStrBuf current_opstr;
|
|
RzIDStorage *sources;
|
|
HtUP *interrupts;
|
|
/* deep esil parsing fills this */
|
|
Sdb *stats;
|
|
RzAnalysisEsilTrace *trace;
|
|
RzAnalysisEsilCallbacks cb;
|
|
// this is so cursed, can we please remove external commands from esil internals.
|
|
// Function pointers are fine, but not commands
|
|
char *cmd_step; // rizin (external) command to run before a step is performed
|
|
char *cmd_step_out; // rizin (external) command to run after a step is performed
|
|
char *cmd_intr; // rizin (external) command to run when an interrupt occurs
|
|
char *cmd_trap; // rizin (external) command to run when a trap occurs
|
|
char *cmd_mdev; // rizin (external) command to run when an memory mapped device address is used
|
|
char *cmd_todo; // rizin (external) command to run when esil expr contains TODO
|
|
char *cmd_ioer; // rizin (external) command to run when esil fails to IO
|
|
char *mdev_range; // string containing the rz_str_range to match for read/write accesses
|
|
bool (*cmd)(ANALYSIS_ESIL *esil, const char *name, ut64 a0, ut64 a1);
|
|
void *user;
|
|
int stack_fd; // ahem, let's not do this
|
|
} RzAnalysisEsil;
|
|
|
|
/* Alias RegChange and MemChange */
|
|
typedef RzAnalysisEsilRegChange RzAnalysisRzilRegChange;
|
|
typedef RzAnalysisEsilMemChange RzAnalysisRzilMemChange;
|
|
|
|
/* Alias esil strace */
|
|
typedef RzAnalysisEsilTrace RzAnalysisRzilTrace;
|
|
|
|
/**
|
|
* \brief Description of the contents of a single IL variable
|
|
*/
|
|
typedef struct rz_analysis_il_init_state_var_t {
|
|
RZ_NONNULL const char *name;
|
|
RZ_NONNULL RzILVal *val;
|
|
} RzAnalysisILInitStateVar;
|
|
|
|
/**
|
|
* \brief Description of an initial state of an RzAnalysisILVM
|
|
*
|
|
* This may be used by an analysis plugin to communicate how to initialize
|
|
* variables/registers for a clean vm.
|
|
* Everything unspecified by this may be initialized to anything (for example
|
|
* whatever contents the RzReg currently has).
|
|
*/
|
|
typedef struct rz_analysis_il_init_state_t {
|
|
RzVector /* <RzAnalysisILInitStateVar> */ vars; ///< Contents of global variables
|
|
} RzAnalysisILInitState;
|
|
|
|
/**
|
|
* \brief Description of the global context of an RzAnalysisILVM
|
|
*
|
|
* This defines all information needed to initialize an IL vm in order to run
|
|
* in a declarative way, in particular:
|
|
*
|
|
* * Size of the program counter: given explicitly in `pc_size`
|
|
* * Endian: given explicitly in `big_endian`
|
|
* * Memories: currently always one memory with index 0 bound against IO, with key size given by `mem_key_size` and value size of 8
|
|
* * Registers: currently implicit, derived from the register profile with `rz_il_reg_binding_derive()`
|
|
* * Labels: given explicitly in `labels`
|
|
* * Initial State of Variables: optionally given in `init_state`
|
|
*/
|
|
typedef struct rz_analysis_il_config_t {
|
|
ut32 pc_size; ///< size of the program counter in bits
|
|
bool big_endian;
|
|
ut32 mem_key_size; ///< address size for memory 0, bound against IO
|
|
RzPVector /* <RzILEffectLabel> */ labels; ///< global labels, primarily for syscall/hook callbacks
|
|
RZ_NULLABLE RzAnalysisILInitState *init_state; ///< optional, initial contents for variables/registers, etc.
|
|
// more information might go in here, for example additional memories, register bindings, etc.
|
|
} RzAnalysisILConfig;
|
|
|
|
/**
|
|
* \brief High-level RzIL vm to emulate disassembled code
|
|
*
|
|
* This builds upon the low-level `RzILVM`, which by itself does not know about
|
|
* IO and lifting, and enables emulation of instructions obtained by disassembling
|
|
* and lifting with analysis plugins.
|
|
*/
|
|
struct rz_analysis_il_vm_t {
|
|
RZ_NONNULL RzILVM *vm; ///< low-level vm to execute IL code
|
|
RZ_NONNULL RzBuffer *io_buf; ///< buffer to use for memory 0 (io)
|
|
RZ_NONNULL RzILRegBinding *reg_binding; ///< specifies which (global) variables are bound to registers
|
|
} /* RzAnalysisILVM */;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_IL_STEP_RESULT_SUCCESS,
|
|
RZ_ANALYSIS_IL_STEP_RESULT_NOT_SET_UP,
|
|
RZ_ANALYSIS_IL_STEP_IL_RUNTIME_ERROR,
|
|
RZ_ANALYSIS_IL_STEP_INVALID_OP
|
|
} RzAnalysisILStepResult;
|
|
|
|
#undef ESIL
|
|
|
|
typedef struct rz_analysis_esil_interrupt_t {
|
|
RzAnalysisEsilInterruptHandler *handler;
|
|
void *user;
|
|
ut32 src_id;
|
|
RzAnalysisEsil *esil;
|
|
} RzAnalysisEsilInterrupt;
|
|
|
|
enum {
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_UNKNOWN = 0x1,
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_CONTROL_FLOW,
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_MEM_READ = 0x4,
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_MEM_WRITE = 0x8,
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_REG_WRITE = 0x10,
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_MATH = 0x20,
|
|
RZ_ANALYSIS_ESIL_OP_TYPE_CUSTOM = 0x40
|
|
};
|
|
|
|
typedef bool (*RzAnalysisEsilOpCb)(RzAnalysisEsil *esil);
|
|
|
|
typedef struct rz_analysis_esil_operation_t {
|
|
RzAnalysisEsilOpCb code;
|
|
ut32 push; // amount of operands pushed
|
|
ut32 pop; // amount of operands popped
|
|
ut32 type;
|
|
} RzAnalysisEsilOp;
|
|
|
|
// this is 80-bit offsets so we can address every piece of esil in an instruction
|
|
typedef struct rz_analysis_esil_expr_offset_t {
|
|
ut64 off;
|
|
ut16 idx;
|
|
} RzAnalysisEsilEOffset;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_ESIL_BLOCK_ENTER_NORMAL = 0,
|
|
RZ_ANALYSIS_ESIL_BLOCK_ENTER_TRUE,
|
|
RZ_ANALYSIS_ESIL_BLOCK_ENTER_FALSE,
|
|
RZ_ANALYSIS_ESIL_BLOCK_ENTER_GLUE,
|
|
} RzAnalysisEsilBlockEnterType;
|
|
|
|
typedef struct rz_analysis_esil_basic_block_t {
|
|
RzAnalysisEsilEOffset first;
|
|
RzAnalysisEsilEOffset last;
|
|
char *expr; // synthesized esil-expression for this block
|
|
RzAnalysisEsilBlockEnterType enter; // maybe more type is needed here
|
|
} RzAnalysisEsilBB;
|
|
|
|
// TODO: rm data + len
|
|
typedef int (*RzAnalysisOpCallback)(RzAnalysis *a, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask);
|
|
|
|
typedef bool (*RzAnalysisRegProfCallback)(RzAnalysis *a);
|
|
typedef char *(*RzAnalysisRegProfGetCallback)(RzAnalysis *a);
|
|
typedef int (*RzAnalysisFPBBCallback)(RzAnalysis *a, RzAnalysisBlock *bb);
|
|
typedef int (*RzAnalysisFPFcnCallback)(RzAnalysis *a, RzAnalysisFunction *fcn);
|
|
typedef int (*RzAnalysisDiffBBCallback)(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisFunction *fcn2);
|
|
typedef int (*RzAnalysisDiffFcnCallback)(RzAnalysis *analysis, RzList *fcns, RzList *fcns2);
|
|
typedef int (*RzAnalysisDiffEvalCallback)(RzAnalysis *analysis);
|
|
|
|
typedef int (*RzAnalysisEsilCB)(RzAnalysisEsil *esil);
|
|
typedef int (*RzAnalysisEsilLoopCB)(RzAnalysisEsil *esil, RzAnalysisOp *op);
|
|
typedef int (*RzAnalysisEsilTrapCB)(RzAnalysisEsil *esil, int trap_type, int trap_code);
|
|
|
|
typedef RzAnalysisILConfig *(*RzAnalysisILConfigCB)(RzAnalysis *analysis);
|
|
|
|
typedef struct rz_analysis_plugin_t {
|
|
const char *name;
|
|
const char *desc;
|
|
const char *license;
|
|
const char *arch;
|
|
const char *author;
|
|
const char *version;
|
|
int bits;
|
|
int esil; // can do esil or not
|
|
int fileformat_type;
|
|
bool (*init)(void **user);
|
|
bool (*fini)(void *user);
|
|
// int (*reset_counter) (RzAnalysis *analysis, ut64 start_addr);
|
|
int (*archinfo)(RzAnalysis *analysis, int query);
|
|
ut8 *(*analysis_mask)(RzAnalysis *analysis, int size, const ut8 *data, ut64 at);
|
|
RzList *(*preludes)(RzAnalysis *analysis);
|
|
|
|
/**
|
|
* The actual bit-size of an address for given analysis.bits.
|
|
* If unimplemented or returns <= 0, analysis.bits will be used as-is.
|
|
*/
|
|
int (*address_bits)(RzAnalysis *analysis, int bits);
|
|
|
|
// legacy rz_analysis_functions
|
|
RzAnalysisOpCallback op;
|
|
|
|
RzAnalysisRegProfGetCallback get_reg_profile;
|
|
RzAnalysisFPBBCallback fingerprint_bb;
|
|
RzAnalysisFPFcnCallback fingerprint_fcn;
|
|
RzAnalysisDiffBBCallback diff_bb;
|
|
RzAnalysisDiffFcnCallback diff_fcn;
|
|
RzAnalysisDiffEvalCallback diff_eval;
|
|
|
|
RzAnalysisEsilCB esil_init; // initialize esil-related stuff
|
|
RzAnalysisEsilLoopCB esil_post_loop; // cycle-counting, firing interrupts, ...
|
|
RzAnalysisEsilTrapCB esil_trap; // traps / exceptions
|
|
RzAnalysisEsilCB esil_fini; // deinitialize
|
|
RzAnalysisILConfigCB il_config; ///< return an IL config to execute lifted code of the given analysis' arch/cpu/bits
|
|
|
|
} RzAnalysisPlugin;
|
|
|
|
/*----------------------------------------------------------------------------------------------*/
|
|
int *(rz_analysis_compare)(RzAnalysisFunction, RzAnalysisFunction);
|
|
/*----------------------------------------------------------------------------------------------*/
|
|
|
|
#ifdef RZ_API
|
|
/* --------- */ /* REFACTOR */ /* ---------- */
|
|
RZ_API RzListRange *rz_listrange_new(void);
|
|
RZ_API void rz_listrange_free(RzListRange *s);
|
|
RZ_API void rz_listrange_add(RzListRange *s, RzAnalysisFunction *f);
|
|
RZ_API void rz_listrange_del(RzListRange *s, RzAnalysisFunction *f);
|
|
RZ_API void rz_listrange_resize(RzListRange *s, RzAnalysisFunction *f, int newsize);
|
|
RZ_API RzAnalysisFunction *rz_listrange_find_in_range(RzListRange *s, ut64 addr);
|
|
RZ_API RzAnalysisFunction *rz_listrange_find_root(RzListRange *s, ut64 addr);
|
|
/* --------- */ /* REFACTOR */ /* ---------- */
|
|
/* type.c */
|
|
RZ_API RzAnalysisType *rz_analysis_type_new(void);
|
|
RZ_API void rz_analysis_type_add(RzAnalysis *l, RzAnalysisType *t);
|
|
RZ_API RzAnalysisType *rz_analysis_type_find(RzAnalysis *a, const char *name);
|
|
RZ_API void rz_analysis_type_list(RzAnalysis *a, short category, short enabled);
|
|
RZ_API const char *rz_analysis_datatype_to_string(RzAnalysisDataType t);
|
|
RZ_API RzAnalysisType *rz_analysis_str_to_type(RzAnalysis *a, const char *s);
|
|
RZ_API bool rz_analysis_op_nonlinear(int t);
|
|
RZ_API bool rz_analysis_op_ismemref(int t);
|
|
RZ_API const char *rz_analysis_optype_to_string(int t);
|
|
RZ_API int rz_analysis_optype_from_string(const char *type);
|
|
RZ_API const char *rz_analysis_op_family_to_string(int n);
|
|
RZ_API int rz_analysis_op_family_from_string(const char *f);
|
|
RZ_API int rz_analysis_op_hint(RzAnalysisOp *op, RzAnalysisHint *hint);
|
|
RZ_API RzAnalysisType *rz_analysis_type_free(RzAnalysisType *t);
|
|
RZ_API RzAnalysisType *rz_analysis_type_loadfile(RzAnalysis *a, const char *path);
|
|
|
|
/* block.c */
|
|
typedef bool (*RzAnalysisBlockCb)(RzAnalysisBlock *block, void *user);
|
|
typedef bool (*RzAnalysisAddrCb)(ut64 addr, void *user);
|
|
|
|
// lifetime
|
|
RZ_API void rz_analysis_block_ref(RzAnalysisBlock *bb);
|
|
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb);
|
|
|
|
// Create one block covering the given range.
|
|
// This will fail if the range overlaps any existing blocks.
|
|
RZ_API RzAnalysisBlock *rz_analysis_create_block(RzAnalysis *analysis, ut64 addr, ut64 size);
|
|
|
|
static inline bool rz_analysis_block_contains(RzAnalysisBlock *bb, ut64 addr) {
|
|
return addr >= bb->addr && addr < bb->addr + bb->size;
|
|
}
|
|
|
|
// Split the block at the given address into two blocks.
|
|
// bb will stay the first block, the second block will be returned (or NULL on failure)
|
|
// The returned block will always be refd, i.e. it is necessary to always call rz_analysis_block_unref() on the return value!
|
|
RZ_API RzAnalysisBlock *rz_analysis_block_split(RzAnalysisBlock *bb, ut64 addr);
|
|
|
|
static inline bool rz_analysis_block_is_contiguous(RzAnalysisBlock *a, RzAnalysisBlock *b) {
|
|
return (a->addr + a->size) == b->addr;
|
|
}
|
|
|
|
// Merge block b into a.
|
|
// b will be FREED (not just unrefd) and is NOT VALID anymore if this function is successful!
|
|
// This only works if b follows directly after a and their function lists are identical.
|
|
// returns true iff the blocks could be merged
|
|
RZ_API bool rz_analysis_block_merge(RzAnalysisBlock *a, RzAnalysisBlock *b);
|
|
|
|
// Manually delete a block and remove it from all its functions
|
|
// If there are more references to it than from its functions only, it will not be removed immediately!
|
|
RZ_API void rz_analysis_delete_block(RzAnalysisBlock *bb);
|
|
|
|
RZ_API void rz_analysis_block_set_size(RzAnalysisBlock *block, ut64 size);
|
|
|
|
// Set the address and size of the block.
|
|
// This can fail (and return false) if there is already another block at the new address
|
|
RZ_API bool rz_analysis_block_relocate(RzAnalysisBlock *block, ut64 addr, ut64 size);
|
|
|
|
RZ_API RzAnalysisBlock *rz_analysis_get_block_at(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API bool rz_analysis_blocks_foreach_in(RzAnalysis *analysis, ut64 addr, RzAnalysisBlockCb cb, void *user);
|
|
RZ_API RzList *rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr); // values from rz_analysis_blocks_foreach_in as a list
|
|
RZ_API void rz_analysis_blocks_foreach_intersect(RzAnalysis *analysis, ut64 addr, ut64 size, RzAnalysisBlockCb cb, void *user);
|
|
RZ_API RzList *rz_analysis_get_blocks_intersect(RzAnalysis *analysis, ut64 addr, ut64 size); // values from rz_analysis_blocks_foreach_intersect as a list
|
|
|
|
// Call cb on every direct successor address of block
|
|
// returns false if the loop was breaked by cb
|
|
RZ_API bool rz_analysis_block_successor_addrs_foreach(RzAnalysisBlock *block, RzAnalysisAddrCb cb, void *user);
|
|
|
|
// Call cb on block and every (recursive) successor of it
|
|
// returns false if the loop was breaked by cb
|
|
RZ_API bool rz_analysis_block_recurse(RzAnalysisBlock *block, RzAnalysisBlockCb cb, void *user);
|
|
|
|
// Call cb on block and every (recursive) successor of it
|
|
// If cb returns false, recursion stops only for that block
|
|
// returns false if the loop was breaked by cb
|
|
RZ_API bool rz_analysis_block_recurse_followthrough(RzAnalysisBlock *block, RzAnalysisBlockCb cb, void *user);
|
|
|
|
// Call cb on block and every (recursive) successor of it
|
|
// Call on_exit on block that doesn't have non-visited successors
|
|
// returns false if the loop was breaked by cb
|
|
RZ_API bool rz_analysis_block_recurse_depth_first(RzAnalysisBlock *block, RzAnalysisBlockCb cb, RZ_NULLABLE RzAnalysisBlockCb on_exit, void *user);
|
|
|
|
// same as rz_analysis_block_recurse, but returns the blocks as a list
|
|
RZ_API RzList *rz_analysis_block_recurse_list(RzAnalysisBlock *block);
|
|
|
|
// return one shortest path from block to dst or NULL if none exists.
|
|
RZ_API RZ_NULLABLE RzList /*<RzAnalysisBlock *>*/ *rz_analysis_block_shortest_path(RzAnalysisBlock *block, ut64 dst);
|
|
|
|
// Add a case to the block's switch_op.
|
|
// If block->switch_op is NULL, it will be created with the given switch_addr.
|
|
RZ_API void rz_analysis_block_add_switch_case(RzAnalysisBlock *block, ut64 switch_addr, ut64 case_value, ut64 case_addr);
|
|
|
|
// Chop off the block at the specified address and remove all destinations.
|
|
// Blocks that have become unreachable after this operation will be automatically removed from all functions of block.
|
|
// addr must be the address directly AFTER the noreturn call!
|
|
// After the chopping, an rz_analysis_block_automerge() is performed on the touched blocks.
|
|
// IMPORTANT: The automerge might also FREE block! This function returns block iff it is still valid afterwards.
|
|
// If this function returns NULL, the pointer to block MUST not be touched anymore!
|
|
RZ_API RzAnalysisBlock *rz_analysis_block_chop_noreturn(RzAnalysisBlock *block, ut64 addr);
|
|
|
|
// Merge every block in blocks with their contiguous predecessor, if possible.
|
|
// IMPORTANT: Merged blocks will be FREED! The blocks list will be updated to contain only the survived blocks.
|
|
RZ_API void rz_analysis_block_automerge(RzList *blocks);
|
|
|
|
// return true iff an instruction in the given basic block starts at the given address
|
|
RZ_API bool rz_analysis_block_op_starts_at(RzAnalysisBlock *block, ut64 addr);
|
|
|
|
// Updates bbhash based on current bytes inside the block
|
|
RZ_API void rz_analysis_block_update_hash(RzAnalysisBlock *block);
|
|
|
|
// returns true if a byte in the given basic block was modified
|
|
RZ_API bool rz_analysis_block_was_modified(RzAnalysisBlock *block);
|
|
|
|
RZ_API RzAnalysisBlock *rz_analysis_find_most_relevant_block_in(RzAnalysis *analysis, ut64 off);
|
|
|
|
RZ_API ut16 rz_analysis_block_get_op_offset(RzAnalysisBlock *block, size_t i);
|
|
RZ_API ut64 rz_analysis_block_get_op_addr(RzAnalysisBlock *block, size_t i);
|
|
RZ_API ut64 rz_analysis_block_get_op_addr_in(RzAnalysisBlock *bb, ut64 off);
|
|
RZ_API bool rz_analysis_block_set_op_offset(RzAnalysisBlock *block, size_t i, ut16 v);
|
|
RZ_API ut64 rz_analysis_block_get_op_size(RzAnalysisBlock *bb, size_t i);
|
|
RZ_API void rz_analysis_block_analyze_ops(RzAnalysisBlock *block);
|
|
|
|
// ---------------------------------------
|
|
|
|
/* function.c */
|
|
|
|
RZ_API RzAnalysisFunction *rz_analysis_function_new(RzAnalysis *analysis);
|
|
RZ_API void rz_analysis_function_free(void *fcn);
|
|
|
|
// Add a function created with rz_analysis_function_new() to anal
|
|
RZ_API bool rz_analysis_add_function(RzAnalysis *analysis, RzAnalysisFunction *fcn);
|
|
|
|
// Create a new function and add it to analysis (rz_analysis_function_new() + set members + rz_analysis_add_function())
|
|
RZ_API RzAnalysisFunction *rz_analysis_create_function(RzAnalysis *analysis, const char *name, ut64 addr, int type, RzAnalysisDiff *diff);
|
|
|
|
// returns all functions that have a basic block containing the given address
|
|
RZ_API RzList *rz_analysis_get_functions_in(RzAnalysis *analysis, ut64 addr);
|
|
|
|
// returns the function that has its entrypoint at addr or NULL
|
|
RZ_API RzAnalysisFunction *rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr);
|
|
|
|
RZ_API bool rz_analysis_function_delete(RzAnalysisFunction *fcn);
|
|
|
|
// returns the list of functions in the RzAnalysis instance
|
|
RZ_API RZ_BORROW RzList *rz_analysis_function_list(RzAnalysis *analysis);
|
|
|
|
// rhange the entrypoint of fcn
|
|
// This can fail (and return false) if there is already another function at the new address
|
|
RZ_API bool rz_analysis_function_relocate(RzAnalysisFunction *fcn, ut64 addr);
|
|
|
|
// rename the given function
|
|
// This can fail (and return false) if there is another function with the name given
|
|
RZ_API bool rz_analysis_function_rename(RzAnalysisFunction *fcn, const char *name);
|
|
|
|
RZ_API void rz_analysis_function_add_block(RzAnalysisFunction *fcn, RzAnalysisBlock *bb);
|
|
RZ_API void rz_analysis_function_remove_block(RzAnalysisFunction *fcn, RzAnalysisBlock *bb);
|
|
|
|
// size of the entire range that the function spans, including holes.
|
|
// this is exactly rz_analysis_function_max_addr() - rz_analysis_function_min_addr()
|
|
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn);
|
|
|
|
// lowest address covered by the function
|
|
RZ_API ut64 rz_analysis_function_min_addr(RzAnalysisFunction *fcn);
|
|
|
|
// first address directly after the function
|
|
RZ_API ut64 rz_analysis_function_max_addr(RzAnalysisFunction *fcn);
|
|
|
|
// size from the function entrypoint (fcn->addr) to the end of the function (rz_analysis_function_max_addr)
|
|
RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn);
|
|
|
|
// the "real" size of the function, that is the sum of the size of the
|
|
// basicblocks this function is composed of
|
|
RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn);
|
|
|
|
// returns whether the function contains a basic block that contains addr
|
|
// This is completely independent of fcn->addr, which is only the entrypoint!
|
|
RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr);
|
|
|
|
// returns true if function bytes were modified
|
|
RZ_API bool rz_analysis_function_was_modified(RzAnalysisFunction *fcn);
|
|
|
|
RZ_API bool rz_analysis_function_is_autonamed(RZ_NONNULL char *name);
|
|
RZ_API RZ_OWN char *rz_analysis_function_name_guess(RzTypeDB *typedb, RZ_NONNULL char *name);
|
|
|
|
/* analysis.c */
|
|
RZ_API RzAnalysis *rz_analysis_new(void);
|
|
RZ_API void rz_analysis_purge(RzAnalysis *analysis);
|
|
RZ_API RzAnalysis *rz_analysis_free(RzAnalysis *r);
|
|
RZ_API int rz_analysis_add(RzAnalysis *analysis, RzAnalysisPlugin *foo);
|
|
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query);
|
|
RZ_API bool rz_analysis_use(RzAnalysis *analysis, const char *name);
|
|
RZ_API bool rz_analysis_set_reg_profile(RzAnalysis *analysis);
|
|
RZ_API char *rz_analysis_get_reg_profile(RzAnalysis *analysis);
|
|
RZ_API bool rz_analysis_set_bits(RzAnalysis *analysis, int bits);
|
|
RZ_API bool rz_analysis_set_os(RzAnalysis *analysis, const char *os);
|
|
RZ_API void rz_analysis_set_cpu(RzAnalysis *analysis, const char *cpu);
|
|
RZ_API int rz_analysis_set_big_endian(RzAnalysis *analysis, int boolean);
|
|
RZ_API ut8 *rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, ut64 at);
|
|
RZ_API void rz_analysis_trace_bb(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API const char *rz_analysis_fcntype_tostring(int type);
|
|
RZ_API void rz_analysis_bind(RzAnalysis *b, RzAnalysisBind *bnd);
|
|
RZ_API bool rz_analysis_set_triplet(RzAnalysis *analysis, const char *os, const char *arch, int bits);
|
|
RZ_API void rz_analysis_add_import(RzAnalysis *analysis, const char *imp);
|
|
RZ_API void rz_analysis_remove_import(RzAnalysis *analysis, const char *imp);
|
|
RZ_API void rz_analysis_purge_imports(RzAnalysis *analysis);
|
|
RZ_API int rz_analysis_get_address_bits(RzAnalysis *analysis);
|
|
|
|
/* op.c */
|
|
RZ_API const char *rz_analysis_stackop_tostring(int s);
|
|
RZ_API RzAnalysisOp *rz_analysis_op_new(void);
|
|
RZ_API void rz_analysis_op_free(void *op);
|
|
RZ_API void rz_analysis_op_init(RzAnalysisOp *op);
|
|
RZ_API bool rz_analysis_op_fini(RzAnalysisOp *op);
|
|
RZ_API int rz_analysis_op_reg_delta(RzAnalysis *analysis, ut64 addr, const char *name);
|
|
RZ_API bool rz_analysis_op_is_eob(RzAnalysisOp *op);
|
|
RZ_API RzList *rz_analysis_op_list_new(void);
|
|
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask);
|
|
RZ_API RzAnalysisOp *rz_analysis_op_hexstr(RzAnalysis *analysis, ut64 addr, const char *hexstr);
|
|
RZ_API char *rz_analysis_op_to_string(RzAnalysis *analysis, RzAnalysisOp *op);
|
|
|
|
RZ_API RzAnalysisEsil *rz_analysis_esil_new(int stacksize, int iotrap, unsigned int addrsize);
|
|
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr);
|
|
RZ_API bool rz_analysis_esil_setup(RzAnalysisEsil *esil, RzAnalysis *analysis, int romem, int stats, int nonull);
|
|
RZ_API void rz_analysis_esil_free(RzAnalysisEsil *esil);
|
|
RZ_API bool rz_analysis_esil_runword(RzAnalysisEsil *esil, const char *word);
|
|
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str);
|
|
RZ_API bool rz_analysis_esil_dumpstack(RzAnalysisEsil *esil);
|
|
RZ_API int rz_analysis_esil_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len);
|
|
RZ_API int rz_analysis_esil_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len);
|
|
RZ_API int rz_analysis_esil_reg_read(RzAnalysisEsil *esil, const char *regname, ut64 *num, int *size);
|
|
RZ_API int rz_analysis_esil_reg_write(RzAnalysisEsil *esil, const char *dst, ut64 num);
|
|
RZ_API bool rz_analysis_esil_pushnum(RzAnalysisEsil *esil, ut64 num);
|
|
RZ_API bool rz_analysis_esil_push(RzAnalysisEsil *esil, const char *str);
|
|
RZ_API char *rz_analysis_esil_pop(RzAnalysisEsil *esil);
|
|
RZ_API bool rz_analysis_esil_set_op(RzAnalysisEsil *esil, const char *op, RzAnalysisEsilOpCb code, ut32 push, ut32 pop, ut32 type);
|
|
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil);
|
|
RZ_API int rz_analysis_esil_get_parm_type(RzAnalysisEsil *esil, const char *str);
|
|
RZ_API int rz_analysis_esil_get_parm(RzAnalysisEsil *esil, const char *str, ut64 *num);
|
|
RZ_API int rz_analysis_esil_condition(RzAnalysisEsil *esil, const char *str);
|
|
|
|
// esil_interrupt.c
|
|
RZ_API void rz_analysis_esil_interrupts_init(RzAnalysisEsil *esil);
|
|
RZ_API RzAnalysisEsilInterrupt *rz_analysis_esil_interrupt_new(RzAnalysisEsil *esil, ut32 src_id, RzAnalysisEsilInterruptHandler *ih);
|
|
RZ_API void rz_analysis_esil_interrupt_free(RzAnalysisEsil *esil, RzAnalysisEsilInterrupt *intr);
|
|
RZ_API bool rz_analysis_esil_set_interrupt(RzAnalysisEsil *esil, RzAnalysisEsilInterrupt *intr);
|
|
RZ_API int rz_analysis_esil_fire_interrupt(RzAnalysisEsil *esil, ut32 intr_num);
|
|
RZ_API bool rz_analysis_esil_load_interrupts(RzAnalysisEsil *esil, RzAnalysisEsilInterruptHandler **handlers, ut32 src_id);
|
|
RZ_API bool rz_analysis_esil_load_interrupts_from_lib(RzAnalysisEsil *esil, const char *path);
|
|
RZ_API void rz_analysis_esil_interrupts_fini(RzAnalysisEsil *esil);
|
|
|
|
RZ_API void rz_analysis_esil_mem_ro(RzAnalysisEsil *esil, int mem_readonly);
|
|
RZ_API void rz_analysis_esil_stats(RzAnalysisEsil *esil, int enable);
|
|
|
|
/* new trace implementation */
|
|
typedef enum {
|
|
RZ_IL_TRACE_OP_READ, ///< read
|
|
RZ_IL_TRACE_OP_WRITE ///< write
|
|
} RzILTraceOpType;
|
|
|
|
typedef struct {
|
|
ut64 addr; ///< memory address
|
|
RzILTraceOpType behavior; ///< read or write, see RzILTraceOpType enums
|
|
ut8 data_buf[32]; ///< data either written to or read from
|
|
int data_len; ///< data length
|
|
} RzILTraceMemOp;
|
|
|
|
typedef struct {
|
|
const char *reg_name; ///< name of register
|
|
RzILTraceOpType behavior; ///< READ or WRITE, see RzILTraceOpType enums
|
|
ut64 value; ///< data either written to or read from
|
|
} RzILTraceRegOp;
|
|
|
|
typedef enum {
|
|
RZ_IL_TRACE_INS_HAS_MEM_R = 0x1U, ///< instruction include memory read
|
|
RZ_IL_TRACE_INS_HAS_MEM_W = 0x2U, ///< instruction include memory write
|
|
RZ_IL_TRACE_INS_HAS_REG_R = 0x4U, ///< instruction include register read
|
|
RZ_IL_TRACE_INS_HAS_REG_W = 0x8U ///< instruction include register write
|
|
} RzILTraceInsOp;
|
|
|
|
typedef struct {
|
|
ut64 addr; ///< Address of instruction
|
|
ut32 stats; ///< Has write/read to reg/mem ? see RZ_IL_TRACE_INS_HAS_* enums
|
|
|
|
RzPVector *write_mem_ops; ///< Vector<RzILTraceMemOp>
|
|
RzPVector *read_mem_ops; ///< Vector<RzILTraceMemOp>
|
|
|
|
RzPVector *write_reg_ops; ///< Vector<RzILTraceRegOp>
|
|
RzPVector *read_reg_ops; ///< Vector<RzILTraceRegOp>
|
|
} RzILTraceInstruction;
|
|
|
|
/* Independent Trace Functions */
|
|
RZ_API RzILTraceInstruction *rz_analysis_il_trace_instruction_new(ut64 addr);
|
|
RZ_API void rz_analysis_il_trace_instruction_free(RzILTraceInstruction *instruction);
|
|
RZ_API bool rz_analysis_il_trace_add_mem(RzILTraceInstruction *trace, RzILTraceMemOp *mem);
|
|
RZ_API bool rz_analysis_il_trace_add_reg(RzILTraceInstruction *trace, RzILTraceRegOp *reg);
|
|
RZ_API RzILTraceMemOp *rz_analysis_il_get_mem_op_trace(RzILTraceInstruction *trace, ut64 addr, RzILTraceOpType op_type);
|
|
RZ_API RzILTraceRegOp *rz_analysis_il_get_reg_op_trace(RzILTraceInstruction *trace, const char *regname, RzILTraceOpType op_type);
|
|
RZ_API bool rz_analysis_il_mem_trace_contains(RzILTraceInstruction *trace, ut64 addr, RzILTraceOpType op_type);
|
|
RZ_API bool rz_analysis_il_reg_trace_contains(RzILTraceInstruction *trace, const char *regname, RzILTraceOpType op_type);
|
|
|
|
/* ESIL trace */
|
|
RZ_API RZ_BORROW RzILTraceInstruction *rz_analysis_esil_get_instruction_trace(RZ_NONNULL RzAnalysisEsilTrace *etrace, int idx);
|
|
RZ_API RzAnalysisEsilTrace *rz_analysis_esil_trace_new(RzAnalysisEsil *esil);
|
|
RZ_API void rz_analysis_esil_trace_free(RzAnalysisEsilTrace *trace);
|
|
RZ_API void rz_analysis_esil_trace_op(RzAnalysisEsil *esil, RZ_NONNULL RzAnalysisOp *op);
|
|
RZ_API void rz_analysis_esil_trace_list(RzAnalysisEsil *esil);
|
|
RZ_API void rz_analysis_esil_trace_show(RzAnalysisEsil *esil, int idx);
|
|
RZ_API void rz_analysis_esil_trace_restore(RzAnalysisEsil *esil, int idx);
|
|
|
|
/* RzIL */
|
|
RZ_API RzAnalysisILInitState *rz_analysis_il_init_state_new();
|
|
RZ_API void rz_analysis_il_init_state_free(RzAnalysisILInitState *state);
|
|
RZ_API void rz_analysis_il_init_state_set_var(RZ_NONNULL RzAnalysisILInitState *state,
|
|
RZ_NONNULL const char *name, RZ_NONNULL RZ_OWN RzILVal *val);
|
|
RZ_API RZ_OWN RzAnalysisILConfig *rz_analysis_il_config_new(ut32 pc_size, bool big_endian, ut32 mem_key_size);
|
|
RZ_API void rz_analysis_il_config_free(RzAnalysisILConfig *cfg);
|
|
RZ_API void rz_analysis_il_config_add_label(RZ_NONNULL RzAnalysisILConfig *cfg, RZ_NONNULL RZ_OWN RzILEffectLabel *label);
|
|
|
|
RZ_API RZ_OWN RzAnalysisILVM *rz_analysis_il_vm_new(RzAnalysis *a, RZ_NULLABLE RzReg *init_state_reg);
|
|
RZ_API void rz_analysis_il_vm_free(RZ_NULLABLE RzAnalysisILVM *vm);
|
|
RZ_API void rz_analysis_il_vm_sync_from_reg(RzAnalysisILVM *vm, RZ_NONNULL RzReg *reg);
|
|
RZ_API bool rz_analysis_il_vm_sync_to_reg(RzAnalysisILVM *vm, RZ_NONNULL RzReg *reg);
|
|
RZ_API RzAnalysisILStepResult rz_analysis_il_vm_step(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisILVM *vm, RZ_NULLABLE RzReg *reg);
|
|
RZ_API bool rz_analysis_il_vm_setup(RzAnalysis *analysis);
|
|
RZ_API void rz_analysis_il_vm_cleanup(RzAnalysis *analysis);
|
|
|
|
/* trace */
|
|
RZ_API RzAnalysisRzilTrace *rz_analysis_rzil_trace_new(RzAnalysis *analysis, RzAnalysisILVM *rzil);
|
|
RZ_API void rz_analysis_rzil_trace_free(RzAnalysisRzilTrace *trace);
|
|
RZ_API void rz_analysis_rzil_trace_op(RzAnalysis *analysis, RzAnalysisILVM *rzil, RzAnalysisLiftedILOp op);
|
|
|
|
RZ_API bool rz_analysis_add_device_peripheral_map(RzBinObject *o, RzAnalysis *analysis);
|
|
|
|
/* fcn.c */
|
|
RZ_API ut32 rz_analysis_function_cost(RzAnalysisFunction *fcn);
|
|
RZ_API int rz_analysis_function_count_edges(const RzAnalysisFunction *fcn, RZ_NULLABLE int *ebbs);
|
|
|
|
// Use rz_analysis_get_functions_in¿() instead
|
|
RZ_DEPRECATE RZ_API RzAnalysisFunction *rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type);
|
|
RZ_DEPRECATE RZ_API RzAnalysisFunction *rz_analysis_get_fcn_in_bounds(RzAnalysis *analysis, ut64 addr, int type);
|
|
|
|
RZ_API RzAnalysisFunction *rz_analysis_get_function_byname(RzAnalysis *analysis, const char *name);
|
|
|
|
RZ_API int rz_analysis_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr, ut64 len, int reftype);
|
|
RZ_API int rz_analysis_fcn_del(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API int rz_analysis_fcn_del_locs(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API bool rz_analysis_fcn_add_bb(RzAnalysis *analysis, RzAnalysisFunction *fcn,
|
|
ut64 addr, ut64 size,
|
|
ut64 jump, ut64 fail, RZ_BORROW RzAnalysisDiff *diff);
|
|
RZ_API bool rz_analysis_check_fcn(RzAnalysis *analysis, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high);
|
|
RZ_API void rz_analysis_fcn_invalidate_read_ahead_cache(void);
|
|
|
|
RZ_API void rz_analysis_function_check_bp_use(RzAnalysisFunction *fcn);
|
|
RZ_API void rz_analysis_update_analysis_range(RzAnalysis *analysis, ut64 addr, int size);
|
|
RZ_API void rz_analysis_function_update_analysis(RzAnalysisFunction *fcn);
|
|
|
|
RZ_API bool rz_analysis_task_item_new(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzVector *tasks, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NULLABLE RzAnalysisBlock *block, ut64 address);
|
|
RZ_API int rz_analysis_run_tasks(RZ_NONNULL RzVector *tasks);
|
|
|
|
#define RZ_ANALYSIS_FCN_VARKIND_LOCAL 'v'
|
|
|
|
RZ_API int rz_analysis_fcn_var_del_byindex(RzAnalysis *a, ut64 fna, char kind, int scope, ut32 idx);
|
|
/* args */
|
|
RZ_API int rz_analysis_var_count(RzAnalysis *a, RzAnalysisFunction *fcn, int kind, int type);
|
|
|
|
/* vars // globals. not here */
|
|
RZ_API bool rz_analysis_var_display(RzAnalysis *analysis, RzAnalysisVar *var);
|
|
|
|
RZ_API int rz_analysis_function_complexity(RzAnalysisFunction *fcn);
|
|
RZ_API int rz_analysis_function_loops(RzAnalysisFunction *fcn);
|
|
RZ_API void rz_analysis_trim_jmprefs(RzAnalysis *analysis, RzAnalysisFunction *fcn);
|
|
RZ_API void rz_analysis_del_jmprefs(RzAnalysis *analysis, RzAnalysisFunction *fcn);
|
|
RZ_API char *rz_analysis_function_get_json(RzAnalysisFunction *function);
|
|
RZ_API RzAnalysisFunction *rz_analysis_fcn_next(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RZ_OWN char *rz_analysis_function_get_signature(RzAnalysisFunction *function);
|
|
RZ_API bool rz_analysis_function_set_type(RzAnalysis *a, RZ_NONNULL RzAnalysisFunction *f, RZ_NONNULL RzCallable *callable);
|
|
RZ_API bool rz_analysis_function_set_type_str(RzAnalysis *a, RZ_NONNULL RzAnalysisFunction *f, RZ_NONNULL const char *sig);
|
|
RZ_API int rz_analysis_fcn_count(RzAnalysis *a, ut64 from, ut64 to);
|
|
RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_in(const RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr);
|
|
RZ_API RzAnalysisBlock *rz_analysis_fcn_bbget_at(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr);
|
|
RZ_API bool rz_analysis_fcn_bbadd(RzAnalysisFunction *fcn, RzAnalysisBlock *bb);
|
|
RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize);
|
|
RZ_API bool rz_analysis_function_purity(RzAnalysisFunction *fcn);
|
|
|
|
typedef bool (*RzAnalysisRefCmp)(RzAnalysisXRef *ref, void *data);
|
|
RZ_API RzList *rz_analysis_xref_list_new(void);
|
|
RZ_API ut64 rz_analysis_xrefs_count(RzAnalysis *analysis);
|
|
RZ_API const char *rz_analysis_xrefs_type_tostring(RzAnalysisXRefType type);
|
|
RZ_API RzAnalysisXRefType rz_analysis_xrefs_type(char ch);
|
|
RZ_API RzList *rz_analysis_xrefs_get_to(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RzList *rz_analysis_xrefs_get_from(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RzList *rz_analysis_xrefs_list(RzAnalysis *analysis);
|
|
RZ_API RzList *rz_analysis_function_get_xrefs_from(RzAnalysisFunction *fcn);
|
|
RZ_API RzList *rz_analysis_function_get_xrefs_to(RzAnalysisFunction *fcn);
|
|
RZ_API bool rz_analysis_xrefs_set(RzAnalysis *analysis, ut64 from, ut64 to, RzAnalysisXRefType type);
|
|
RZ_API bool rz_analysis_xrefs_deln(RzAnalysis *analysis, ut64 from, ut64 to, RzAnalysisXRefType type);
|
|
RZ_API bool rz_analysis_xref_del(RzAnalysis *analysis, ut64 from, ut64 to);
|
|
|
|
RZ_API RzList *rz_analysis_get_fcns(RzAnalysis *analysis);
|
|
|
|
/* var.c */
|
|
RZ_API RZ_OWN char *rz_analysis_function_autoname_var(RzAnalysisFunction *fcn, char kind, const char *pfx, int ptr);
|
|
RZ_API RZ_BORROW RzAnalysisVar *rz_analysis_function_set_var(RzAnalysisFunction *fcn, int delta, char kind, RZ_BORROW RZ_NULLABLE const RzType *type, int size, bool isarg, RZ_NONNULL const char *name);
|
|
RZ_API RZ_BORROW RzAnalysisVar *rz_analysis_function_get_var(RzAnalysisFunction *fcn, char kind, int delta);
|
|
RZ_API RZ_BORROW RzAnalysisVar *rz_analysis_function_get_var_byname(RzAnalysisFunction *fcn, const char *name);
|
|
RZ_API void rz_analysis_function_delete_vars_by_kind(RzAnalysisFunction *fcn, RzAnalysisVarKind kind);
|
|
RZ_API void rz_analysis_function_delete_all_vars(RzAnalysisFunction *fcn);
|
|
RZ_API void rz_analysis_function_delete_unused_vars(RzAnalysisFunction *fcn);
|
|
RZ_API void rz_analysis_function_delete_var(RzAnalysisFunction *fcn, RzAnalysisVar *var);
|
|
RZ_API bool rz_analysis_function_rebase_vars(RzAnalysis *a, RzAnalysisFunction *fcn);
|
|
RZ_API st64 rz_analysis_function_get_var_stackptr_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr);
|
|
RZ_API const char *rz_analysis_function_get_var_reg_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr);
|
|
RZ_API RZ_BORROW RzPVector *rz_analysis_function_get_vars_used_at(RzAnalysisFunction *fcn, ut64 op_addr);
|
|
|
|
// There could be multiple vars used in multiple functions. Use rz_analysis_get_functions_in()+rz_analysis_function_get_vars_used_at() instead.
|
|
RZ_API RZ_DEPRECATE RzAnalysisVar *rz_analysis_get_used_function_var(RzAnalysis *analysis, ut64 addr);
|
|
|
|
RZ_API bool rz_analysis_var_rename(RzAnalysisVar *var, const char *new_name, bool verbose);
|
|
RZ_API void rz_analysis_var_set_type(RzAnalysisVar *var, RZ_OWN RzType *type);
|
|
RZ_API void rz_analysis_var_delete(RzAnalysisVar *var);
|
|
RZ_API ut64 rz_analysis_var_addr(RzAnalysisVar *var);
|
|
RZ_API void rz_analysis_var_set_access(RzAnalysisVar *var, const char *reg, ut64 access_addr, int access_type, st64 stackptr);
|
|
RZ_API void rz_analysis_var_remove_access_at(RzAnalysisVar *var, ut64 address);
|
|
RZ_API void rz_analysis_var_clear_accesses(RzAnalysisVar *var);
|
|
RZ_API void rz_analysis_var_add_constraint(RzAnalysisVar *var, RZ_BORROW RzTypeConstraint *constraint);
|
|
RZ_API char *rz_analysis_var_get_constraints_readable(RzAnalysisVar *var);
|
|
|
|
// Get the access to var at exactly addr if there is one
|
|
RZ_API RzAnalysisVarAccess *rz_analysis_var_get_access_at(RzAnalysisVar *var, ut64 addr);
|
|
|
|
RZ_API int rz_analysis_var_get_argnum(RzAnalysisVar *var);
|
|
|
|
RZ_API void rz_analysis_extract_vars(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisOp *op);
|
|
RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzAnalysisFunction *fcn, int *reg_set, int *count);
|
|
|
|
// Get the variable that var is written to at one of its accesses
|
|
// Useful for cases where a register-based argument is written away into a stack variable,
|
|
// so if var is the reg arg then this will return the stack var.
|
|
RZ_API RzAnalysisVar *rz_analysis_var_get_dst_var(RzAnalysisVar *var);
|
|
|
|
typedef struct rz_analysis_fcn_vars_cache {
|
|
RzList *bvars;
|
|
RzList *rvars;
|
|
RzList *svars;
|
|
} RzAnalysisFcnVarsCache;
|
|
RZ_API void rz_analysis_fcn_vars_cache_init(RzAnalysis *analysis, RzAnalysisFcnVarsCache *cache, RzAnalysisFunction *fcn);
|
|
RZ_API void rz_analysis_fcn_vars_cache_fini(RzAnalysisFcnVarsCache *cache);
|
|
|
|
RZ_API char *rz_analysis_fcn_format_sig(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NULLABLE char *fcn_name,
|
|
RZ_NULLABLE RzAnalysisFcnVarsCache *reuse_cache, RZ_NULLABLE const char *fcn_name_pre, RZ_NULLABLE const char *fcn_name_post);
|
|
|
|
RZ_API void rz_analysis_fcn_vars_add_types(RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn);
|
|
|
|
// Global vars
|
|
RZ_API RZ_OWN RzAnalysisVarGlobal *rz_analysis_var_global_new(RZ_NONNULL const char *name, ut64 addr);
|
|
RZ_API RZ_OWN bool rz_analysis_var_global_add(RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *global_var);
|
|
RZ_API void rz_analysis_var_global_free(RzAnalysisVarGlobal *glob);
|
|
RZ_API RZ_NULLABLE RzFlagItem *rz_analysis_var_global_get_flag_item(RzAnalysisVarGlobal *glob);
|
|
RZ_API bool rz_analysis_var_global_delete(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisVarGlobal *glob);
|
|
RZ_API bool rz_analysis_var_global_delete_byname(RzAnalysis *analysis, RZ_NONNULL const char *name);
|
|
RZ_API bool rz_analysis_var_global_delete_byaddr_at(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API bool rz_analysis_var_global_delete_byaddr_in(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RZ_BORROW RzAnalysisVarGlobal *rz_analysis_var_global_get_byname(RzAnalysis *analysis, RZ_NONNULL const char *name);
|
|
RZ_API RZ_BORROW RzAnalysisVarGlobal *rz_analysis_var_global_get_byaddr_at(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RZ_BORROW RzAnalysisVarGlobal *rz_analysis_var_global_get_byaddr_in(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RZ_OWN RzList *rz_analysis_var_global_get_all(RzAnalysis *analysis);
|
|
RZ_API bool rz_analysis_var_global_rename(RzAnalysis *analysis, RZ_NONNULL const char *old_name, RZ_NONNULL const char *newname);
|
|
RZ_API void rz_analysis_var_global_set_type(RzAnalysisVarGlobal *glob, RZ_NONNULL RZ_BORROW RzType *type);
|
|
RZ_API void rz_analysis_var_global_add_constraint(RzAnalysisVarGlobal *glob, RzTypeConstraint *constraint);
|
|
RZ_API RZ_OWN char *rz_analysis_var_global_get_constraints_readable(RzAnalysisVarGlobal *glob);
|
|
|
|
// Maintaining type links
|
|
RZ_API bool rz_analysis_type_link_exists(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RZ_BORROW RzType *rz_analysis_type_link_at(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API bool rz_analysis_type_set_link(RzAnalysis *analysis, RZ_BORROW RzType *type, ut64 addr);
|
|
RZ_API bool rz_analysis_type_unlink(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API bool rz_analysis_type_unlink_all(RzAnalysis *analysis);
|
|
RZ_API bool rz_analysis_type_link_offset(RzAnalysis *analysis, RZ_BORROW RzType *type, ut64 addr);
|
|
RZ_API RZ_OWN RzList /* RzType */ *rz_analysis_type_links(RzAnalysis *analysis);
|
|
RZ_API RZ_OWN RzList /* RzTypePath */ *rz_analysis_type_links_by_offset(RzAnalysis *analysis, ut64 offset);
|
|
RZ_API RZ_OWN RzList /* RzTypePath */ *rz_analysis_type_paths_by_address(RzAnalysis *analysis, ut64 addr);
|
|
|
|
/* project */
|
|
RZ_API bool rz_analysis_xrefs_init(RzAnalysis *analysis);
|
|
|
|
#define RZ_ANALYSIS_THRESHOLDFCN 0.7F
|
|
#define RZ_ANALYSIS_THRESHOLDBB 0.7F
|
|
|
|
/* diff.c */
|
|
RZ_API RzAnalysisDiff *rz_analysis_diff_new(void);
|
|
RZ_API void rz_analysis_diff_setup(RzAnalysis *analysis, int doops, double thbb, double thfcn);
|
|
RZ_API void rz_analysis_diff_setup_i(RzAnalysis *analysis, int doops, int thbb, int thfcn);
|
|
RZ_API void *rz_analysis_diff_free(RzAnalysisDiff *diff);
|
|
RZ_API int rz_analysis_diff_fingerprint_bb(RzAnalysis *analysis, RzAnalysisBlock *bb);
|
|
RZ_API size_t rz_analysis_diff_fingerprint_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn);
|
|
RZ_API bool rz_analysis_diff_bb(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisFunction *fcn2);
|
|
RZ_API int rz_analysis_diff_fcn(RzAnalysis *analysis, RzList *fcns, RzList *fcns2);
|
|
RZ_API int rz_analysis_diff_eval(RzAnalysis *analysis);
|
|
|
|
/* value.c */
|
|
RZ_API RzAnalysisValue *rz_analysis_value_new(void);
|
|
RZ_API RzAnalysisValue *rz_analysis_value_copy(RzAnalysisValue *ov);
|
|
RZ_API RzAnalysisValue *rz_analysis_value_new_from_string(const char *str);
|
|
RZ_API st64 rz_analysis_value_eval(RzAnalysisValue *value);
|
|
RZ_API char *rz_analysis_value_to_string(RzAnalysisValue *value);
|
|
RZ_API ut64 rz_analysis_value_to_ut64(RzAnalysis *analysis, RzAnalysisValue *val);
|
|
RZ_API int rz_analysis_value_set_ut64(RzAnalysis *analysis, RzAnalysisValue *val, ut64 num);
|
|
RZ_API void rz_analysis_value_free(RzAnalysisValue *value);
|
|
|
|
RZ_API RzAnalysisCond *rz_analysis_cond_new(void);
|
|
RZ_API RzAnalysisCond *rz_analysis_cond_new_from_op(RzAnalysisOp *op);
|
|
RZ_API void rz_analysis_cond_fini(RzAnalysisCond *c);
|
|
RZ_API void rz_analysis_cond_free(RzAnalysisCond *c);
|
|
RZ_API char *rz_analysis_cond_to_string(RzAnalysisCond *cond);
|
|
RZ_API int rz_analysis_cond_eval(RzAnalysis *analysis, RzAnalysisCond *cond);
|
|
RZ_API RzAnalysisCond *rz_analysis_cond_new_from_string(const char *str);
|
|
|
|
/* jmptbl */
|
|
RZ_API bool rz_analysis_jmptbl(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisBlock *block, ut64 jmpaddr, ut64 table, ut64 tablesize, ut64 default_addr);
|
|
|
|
typedef struct rz_jmptable_params_t {
|
|
ut64 jmp_address; /// Address of the jump instruction
|
|
st64 case_shift; /// Shift that is added to get the real number of the case.
|
|
ut64 jmptbl_loc; /// Address of the jump table
|
|
ut64 casetbl_loc; /// Address of the indirect case table
|
|
ut64 jmptbl_off; /// Base of the jump table
|
|
ut64 entry_size; /// Size in bytes of each case entry inside the jump table
|
|
ut64 table_count; /// Count of cases inside the jump table
|
|
ut64 default_case; /// Code address of the default case of the switch
|
|
RzVector *tasks; /// RzVector of RzAnalysisTaskItem to add new tasks to
|
|
} RzAnalysisJmpTableParams;
|
|
|
|
RZ_API bool rz_analysis_get_delta_jmptbl_info(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, ut64 jmp_address, ut64 lea_address, RZ_NONNULL RzAnalysisJmpTableParams *params);
|
|
RZ_API bool rz_analysis_get_jmptbl_info(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NONNULL RzAnalysisBlock *block, ut64 jmp_address, RZ_NONNULL RzAnalysisJmpTableParams *params);
|
|
RZ_API bool rz_analysis_walkthrough_jmptbl(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NONNULL RzAnalysisBlock *block, RZ_NONNULL RzAnalysisJmpTableParams *params);
|
|
RZ_API bool rz_analysis_walkthrough_casetbl(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NONNULL RzAnalysisBlock *block, RZ_NONNULL RzAnalysisJmpTableParams *params);
|
|
RZ_API bool rz_analysis_walkthrough_arm_jmptbl_style(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NONNULL RzAnalysisBlock *block, RZ_NONNULL RzAnalysisJmpTableParams *params);
|
|
|
|
/* reflines.c */
|
|
RZ_API RzList * /*<RzAnalysisRefline>*/ rz_analysis_reflines_get(RzAnalysis *analysis,
|
|
ut64 addr, const ut8 *buf, ut64 len, int nlines, int linesout, int linescall);
|
|
RZ_API int rz_analysis_reflines_middle(RzAnalysis *analysis, RzList *list, ut64 addr, int len);
|
|
RZ_API RzAnalysisRefStr *rz_analysis_reflines_str(void *core, ut64 addr, int opts);
|
|
RZ_API void rz_analysis_reflines_str_free(RzAnalysisRefStr *refstr);
|
|
/* TODO move to rz_core */
|
|
RZ_API void rz_analysis_var_list_show(RzAnalysis *analysis, RzAnalysisFunction *fcn, int kind, int mode, PJ *pj);
|
|
RZ_API RzList *rz_analysis_var_list(RzAnalysis *analysis, RzAnalysisFunction *fcn, int kind);
|
|
RZ_API RZ_DEPRECATE RzList /*<RzAnalysisVar *>*/ *rz_analysis_var_all_list(RzAnalysis *analysis, RzAnalysisFunction *fcn);
|
|
RZ_API RZ_DEPRECATE RzList /*<RzAnalysisVarField *>*/ *rz_analysis_function_get_var_fields(RzAnalysisFunction *fcn, int kind);
|
|
|
|
// calling conventions API
|
|
RZ_API bool rz_analysis_cc_exist(RzAnalysis *analysis, const char *convention);
|
|
RZ_API void rz_analysis_cc_del(RzAnalysis *analysis, const char *name);
|
|
RZ_API bool rz_analysis_cc_set(RzAnalysis *analysis, const char *expr);
|
|
RZ_API char *rz_analysis_cc_get(RzAnalysis *analysis, const char *name);
|
|
RZ_API const char *rz_analysis_cc_arg(RzAnalysis *analysis, const char *convention, int n);
|
|
RZ_API const char *rz_analysis_cc_self(RzAnalysis *analysis, const char *convention);
|
|
RZ_API void rz_analysis_cc_set_self(RzAnalysis *analysis, const char *convention, const char *self);
|
|
RZ_API const char *rz_analysis_cc_error(RzAnalysis *analysis, const char *convention);
|
|
RZ_API void rz_analysis_cc_set_error(RzAnalysis *analysis, const char *convention, const char *error);
|
|
RZ_API int rz_analysis_cc_max_arg(RzAnalysis *analysis, const char *cc);
|
|
RZ_API const char *rz_analysis_cc_ret(RzAnalysis *analysis, const char *convention);
|
|
RZ_API const char *rz_analysis_cc_default(RzAnalysis *analysis);
|
|
RZ_API void rz_analysis_set_cc_default(RzAnalysis *analysis, const char *convention);
|
|
RZ_API const char *rz_analysis_syscc_default(RzAnalysis *analysis);
|
|
RZ_API void rz_analysis_set_syscc_default(RzAnalysis *analysis, const char *convention);
|
|
RZ_API const char *rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name);
|
|
RZ_API RzList *rz_analysis_calling_conventions(RzAnalysis *analysis);
|
|
|
|
typedef struct rz_analysis_data_t {
|
|
ut64 addr;
|
|
int type;
|
|
ut64 ptr;
|
|
char *str;
|
|
int len;
|
|
ut8 *buf;
|
|
ut8 sbuf[8];
|
|
} RzAnalysisData;
|
|
|
|
RZ_API RzAnalysisData *rz_analysis_data(RzAnalysis *analysis, ut64 addr, const ut8 *buf, int size, int wordsize);
|
|
RZ_API const char *rz_analysis_data_kind(RzAnalysis *analysis, ut64 addr, const ut8 *buf, int len);
|
|
RZ_API RzAnalysisData *rz_analysis_data_new_string(ut64 addr, const char *p, int size, int wide);
|
|
RZ_API RzAnalysisData *rz_analysis_data_new(ut64 addr, int type, ut64 n, const ut8 *buf, int len);
|
|
RZ_API void rz_analysis_data_free(RzAnalysisData *d);
|
|
#include <rz_cons.h>
|
|
RZ_API char *rz_analysis_data_to_string(RzAnalysisData *d, RzConsPrintablePalette *pal);
|
|
|
|
/* meta
|
|
*
|
|
* Meta uses Condret's Klemmbaustein Priciple, i.e. intervals are defined inclusive/inclusive.
|
|
* A meta item from 0x42 to 0x42 has a size of 1. Items with size 0 do not exist.
|
|
* Meta items are allowed to overlap and the internal data structure allows for multiple meta items
|
|
* starting at the same address.
|
|
* Meta items are saved in an RzIntervalTree. To access the interval of an item, use the members of RzIntervalNode.
|
|
*/
|
|
|
|
static inline ut64 rz_meta_item_size(ut64 start, ut64 end) {
|
|
// meta items use inclusive/inclusive intervals
|
|
return end - start + 1;
|
|
}
|
|
|
|
static inline ut64 rz_meta_node_size(RzIntervalNode *node) {
|
|
return rz_meta_item_size(node->start, node->end);
|
|
}
|
|
|
|
// Set a meta item at addr with the given contents in the current space.
|
|
// If there already exists an item with this type and space at addr (regardless of its size) it will be overwritten.
|
|
RZ_API bool rz_meta_set(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr, ut64 size, const char *str);
|
|
|
|
// Same as rz_meta_set() but also sets the subtype.
|
|
RZ_API bool rz_meta_set_with_subtype(RzAnalysis *m, RzAnalysisMetaType type, int subtype, ut64 addr, ut64 size, const char *str);
|
|
|
|
// Delete all meta items in the current space that intersect with the given interval.
|
|
// If size == UT64_MAX, everything in the current space will be deleted.
|
|
RZ_API void rz_meta_del(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr, ut64 size);
|
|
|
|
// Same as rz_meta_set() with a size of 1.
|
|
RZ_API bool rz_meta_set_string(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr, const char *s);
|
|
|
|
// Convenience function to get the str content of the item at addr with given type in the current space.
|
|
RZ_API const char *rz_meta_get_string(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr);
|
|
|
|
// Convenience function to add an RZ_META_TYPE_DATA item at the given addr in the current space.
|
|
RZ_API void rz_meta_set_data_at(RzAnalysis *a, ut64 addr, ut64 wordsz);
|
|
|
|
// Returns the item with given type that starts at addr in the current space or NULL. The size of this item optionally returned through size.
|
|
RZ_API RzAnalysisMetaItem *rz_meta_get_at(RzAnalysis *a, ut64 addr, RzAnalysisMetaType type, RZ_OUT RZ_NULLABLE ut64 *size);
|
|
|
|
// Returns the node for one meta item with the given type that contains addr in the current space or NULL.
|
|
// To get all the nodes, use rz_meta_get_all_in().
|
|
RZ_API RzIntervalNode *rz_meta_get_in(RzAnalysis *a, ut64 addr, RzAnalysisMetaType type);
|
|
|
|
// Returns all nodes for items starting at the given address in the current space.
|
|
RZ_API RzPVector /*<RzIntervalNode<RMetaItem> *>*/ *rz_meta_get_all_at(RzAnalysis *a, ut64 at);
|
|
|
|
// Returns all nodes for items with the given type containing the given address in the current space.
|
|
RZ_API RzPVector /*<RzIntervalNode<RMetaItem> *>*/ *rz_meta_get_all_in(RzAnalysis *a, ut64 at, RzAnalysisMetaType type);
|
|
|
|
// Returns all nodes for items with the given type intersecting the given interval in the current space.
|
|
RZ_API RzPVector /*<RzIntervalNode<RMetaItem> *>*/ *rz_meta_get_all_intersect(RzAnalysis *a, ut64 start, ut64 size, RzAnalysisMetaType type);
|
|
|
|
// Delete all meta items in the given space
|
|
RZ_API void rz_meta_space_unset_for(RzAnalysis *a, const RzSpace *space);
|
|
|
|
// Returns the number of meta items in the given space
|
|
RZ_API int rz_meta_space_count_for(RzAnalysis *a, const RzSpace *space);
|
|
|
|
// Shift all meta items by the given delta, for rebasing between different memory layouts.
|
|
RZ_API void rz_meta_rebase(RzAnalysis *analysis, ut64 diff);
|
|
|
|
// Calculate the total size covered by meta items of the given type.
|
|
RZ_API ut64 rz_meta_get_size(RzAnalysis *a, RzAnalysisMetaType type);
|
|
|
|
RZ_API const char *rz_meta_type_to_string(int type);
|
|
|
|
/* hints */
|
|
|
|
RZ_API void rz_analysis_hint_del(RzAnalysis *analysis, ut64 addr, ut64 size); // delete all hints that are contained within the given range, if size > 1, this operation is quite heavy!
|
|
RZ_API void rz_analysis_hint_clear(RzAnalysis *a);
|
|
RZ_API void rz_analysis_hint_free(RzAnalysisHint *h);
|
|
RZ_API void rz_analysis_hint_set_syntax(RzAnalysis *a, ut64 addr, const char *syn);
|
|
RZ_API void rz_analysis_hint_set_type(RzAnalysis *a, ut64 addr, int type);
|
|
RZ_API void rz_analysis_hint_set_jump(RzAnalysis *a, ut64 addr, ut64 jump);
|
|
RZ_API void rz_analysis_hint_set_fail(RzAnalysis *a, ut64 addr, ut64 fail);
|
|
RZ_API void rz_analysis_hint_set_newbits(RzAnalysis *a, ut64 addr, int bits);
|
|
RZ_API void rz_analysis_hint_set_nword(RzAnalysis *a, ut64 addr, int nword);
|
|
RZ_API void rz_analysis_hint_set_offset(RzAnalysis *a, ut64 addr, const char *typeoff);
|
|
RZ_API void rz_analysis_hint_set_immbase(RzAnalysis *a, ut64 addr, int base);
|
|
RZ_API void rz_analysis_hint_set_size(RzAnalysis *a, ut64 addr, ut64 size);
|
|
RZ_API void rz_analysis_hint_set_opcode(RzAnalysis *a, ut64 addr, const char *str);
|
|
RZ_API void rz_analysis_hint_set_esil(RzAnalysis *a, ut64 addr, const char *str);
|
|
RZ_API void rz_analysis_hint_set_pointer(RzAnalysis *a, ut64 addr, ut64 ptr);
|
|
RZ_API void rz_analysis_hint_set_ret(RzAnalysis *a, ut64 addr, ut64 val);
|
|
RZ_API void rz_analysis_hint_set_high(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_set_stackframe(RzAnalysis *a, ut64 addr, ut64 size);
|
|
RZ_API void rz_analysis_hint_set_val(RzAnalysis *a, ut64 addr, ut64 v);
|
|
RZ_API void rz_analysis_hint_set_arch(RzAnalysis *a, ut64 addr, RZ_NULLABLE const char *arch); // arch == NULL => use global default
|
|
RZ_API void rz_analysis_hint_set_bits(RzAnalysis *a, ut64 addr, int bits); // bits == NULL => use global default
|
|
RZ_API void rz_analysis_hint_unset_val(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_high(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_immbase(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_nword(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_size(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_type(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_esil(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_opcode(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_syntax(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_pointer(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_ret(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_offset(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_jump(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_fail(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_newbits(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_stackframe(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_arch(RzAnalysis *a, ut64 addr);
|
|
RZ_API void rz_analysis_hint_unset_bits(RzAnalysis *a, ut64 addr);
|
|
RZ_API RZ_NULLABLE const RzVector /*<const RzAnalysisAddrHintRecord>*/ *rz_analysis_addr_hints_at(RzAnalysis *analysis, ut64 addr);
|
|
typedef bool (*RzAnalysisAddrHintRecordsCb)(ut64 addr, const RzVector /*<const RzAnalysisAddrHintRecord>*/ *records, void *user);
|
|
RZ_API void rz_analysis_addr_hints_foreach(RzAnalysis *analysis, RzAnalysisAddrHintRecordsCb cb, void *user);
|
|
typedef bool (*RzAnalysisArchHintCb)(ut64 addr, RZ_NULLABLE const char *arch, void *user);
|
|
RZ_API void rz_analysis_arch_hints_foreach(RzAnalysis *analysis, RzAnalysisArchHintCb cb, void *user);
|
|
typedef bool (*RzAnalysisBitsHintCb)(ut64 addr, int bits, void *user);
|
|
RZ_API void rz_analysis_bits_hints_foreach(RzAnalysis *analysis, RzAnalysisBitsHintCb cb, void *user);
|
|
|
|
// get the hint-specified arch value to be considered at addr
|
|
// hint_addr will optionally be set to the address where the hint that specifies this arch is placed or UT64_MAX
|
|
// if there is no hint affecting addr.
|
|
RZ_API RZ_NULLABLE RZ_BORROW const char *rz_analysis_hint_arch_at(RzAnalysis *analysis, ut64 addr, RZ_NULLABLE ut64 *hint_addr);
|
|
|
|
// get the hint-specified bits value to be considered at addr
|
|
// hint_addr will optionally be set to the address where the hint that specifies this arch is placed or UT64_MAX
|
|
// if there is no hint affecting addr.
|
|
RZ_API int rz_analysis_hint_bits_at(RzAnalysis *analysis, ut64 addr, RZ_NULLABLE ut64 *hint_addr);
|
|
|
|
RZ_API RzAnalysisHint *rz_analysis_hint_get(RzAnalysis *analysis, ut64 addr); // accumulate all available hints affecting the given address
|
|
|
|
/* switch.c APIs */
|
|
RZ_API RzAnalysisSwitchOp *rz_analysis_switch_op_new(ut64 addr, ut64 min_val, ut64 max_val, ut64 def_val);
|
|
RZ_API void rz_analysis_switch_op_free(RzAnalysisSwitchOp *swop);
|
|
RZ_API RzAnalysisCaseOp *rz_analysis_switch_op_add_case(RzAnalysisSwitchOp *swop, ut64 addr, ut64 value, ut64 jump);
|
|
|
|
/* cycles.c */
|
|
RZ_API RzAnalysisCycleFrame *rz_analysis_cycle_frame_new(void);
|
|
RZ_API void rz_analysis_cycle_frame_free(RzAnalysisCycleFrame *cf);
|
|
|
|
/* labels */
|
|
RZ_API ut64 rz_analysis_function_get_label(RzAnalysisFunction *fcn, const char *name);
|
|
RZ_API const char *rz_analysis_function_get_label_at(RzAnalysisFunction *fcn, ut64 addr);
|
|
RZ_API bool rz_analysis_function_set_label(RzAnalysisFunction *fcn, const char *name, ut64 addr);
|
|
RZ_API bool rz_analysis_function_delete_label(RzAnalysisFunction *fcn, const char *name);
|
|
RZ_API bool rz_analysis_function_delete_label_at(RzAnalysisFunction *fcn, ut64 addr);
|
|
|
|
/* limits */
|
|
RZ_API void rz_analysis_set_limits(RzAnalysis *analysis, ut64 from, ut64 to);
|
|
RZ_API void rz_analysis_unset_limits(RzAnalysis *analysis);
|
|
|
|
/* no-return stuff */
|
|
RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr);
|
|
RZ_API bool rz_analysis_noreturn_drop(RzAnalysis *analysis, const char *expr);
|
|
RZ_API bool rz_analysis_noreturn_at_addr(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API bool rz_analysis_noreturn_at(RzAnalysis *analysis, ut64 addr);
|
|
RZ_API RzList *rz_analysis_noreturn_functions(RzAnalysis *analysis);
|
|
|
|
/* zign spaces */
|
|
RZ_API int rz_sign_space_count_for(RzAnalysis *a, const RzSpace *space);
|
|
RZ_API void rz_sign_space_unset_for(RzAnalysis *a, const RzSpace *space);
|
|
RZ_API void rz_sign_space_rename_for(RzAnalysis *a, const RzSpace *space, const char *oname, const char *nname);
|
|
|
|
/* vtables */
|
|
typedef struct {
|
|
RzAnalysis *analysis;
|
|
RzAnalysisCPPABI abi;
|
|
ut8 word_size;
|
|
bool (*read_addr)(RzAnalysis *analysis, ut64 addr, ut64 *buf);
|
|
} RVTableContext;
|
|
|
|
typedef struct vtable_info_t {
|
|
ut64 saddr; // starting address
|
|
RzVector methods;
|
|
} RVTableInfo;
|
|
|
|
typedef struct vtable_method_info_t {
|
|
ut64 addr; // addr of the function
|
|
ut64 vtable_offset; // offset inside the vtable
|
|
} RVTableMethodInfo;
|
|
|
|
RZ_API void rz_analysis_vtable_info_free(RVTableInfo *vtable);
|
|
RZ_API ut64 rz_analysis_vtable_info_get_size(RVTableContext *context, RVTableInfo *vtable);
|
|
RZ_API bool rz_analysis_vtable_begin(RzAnalysis *analysis, RVTableContext *context);
|
|
RZ_API RVTableInfo *rz_analysis_vtable_parse_at(RVTableContext *context, ut64 addr);
|
|
RZ_API RzList *rz_analysis_vtable_search(RVTableContext *context);
|
|
RZ_API void rz_analysis_list_vtables(RzAnalysis *analysis, RzOutputMode mode);
|
|
|
|
/* rtti */
|
|
RZ_API char *rz_analysis_rtti_msvc_demangle_class_name(RVTableContext *context, const char *name);
|
|
RZ_API void rz_analysis_rtti_msvc_print_complete_object_locator(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API void rz_analysis_rtti_msvc_print_type_descriptor(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API void rz_analysis_rtti_msvc_print_class_hierarchy_descriptor(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API void rz_analysis_rtti_msvc_print_base_class_descriptor(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API bool rz_analysis_rtti_msvc_print_at_vtable(RVTableContext *context, ut64 addr, RzOutputMode mode, bool strict);
|
|
RZ_API void rz_analysis_rtti_msvc_recover_all(RVTableContext *vt_context, RzList *vtables);
|
|
|
|
RZ_API char *rz_analysis_rtti_itanium_demangle_class_name(RVTableContext *context, const char *name);
|
|
RZ_API void rz_analysis_rtti_itanium_print_class_type_info(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API void rz_analysis_rtti_itanium_print_si_class_type_info(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API void rz_analysis_rtti_itanium_print_vmi_class_type_info(RVTableContext *context, ut64 addr, int mode);
|
|
RZ_API bool rz_analysis_rtti_itanium_print_at_vtable(RVTableContext *context, ut64 addr, RzOutputMode mode);
|
|
RZ_API void rz_analysis_rtti_itanium_recover_all(RVTableContext *vt_context, RzList *vtables);
|
|
|
|
RZ_API char *rz_analysis_rtti_demangle_class_name(RzAnalysis *analysis, const char *name);
|
|
RZ_API void rz_analysis_rtti_print_at_vtable(RzAnalysis *analysis, ut64 addr, RzOutputMode mode);
|
|
RZ_API void rz_analysis_rtti_print_all(RzAnalysis *analysis, RzOutputMode mode);
|
|
RZ_API void rz_analysis_rtti_recover_all(RzAnalysis *analysis);
|
|
|
|
RZ_API RzList *rz_analysis_preludes(RzAnalysis *analysis);
|
|
RZ_API bool rz_analysis_is_prelude(RzAnalysis *analysis, const ut8 *data, int len);
|
|
|
|
/* classes */
|
|
typedef enum {
|
|
RZ_ANALYSIS_CLASS_METHOD_DEFAULT = 0,
|
|
RZ_ANALYSIS_CLASS_METHOD_VIRTUAL,
|
|
RZ_ANALYSIS_CLASS_METHOD_VIRTUAL_DESTRUCTOR,
|
|
RZ_ANALYSIS_CLASS_METHOD_DESTRUCTOR,
|
|
RZ_ANALYSIS_CLASS_METHOD_CONSTRUCTOR
|
|
} RzAnalysisMethodType;
|
|
|
|
typedef struct rz_analysis_method_t {
|
|
char *name;
|
|
char *real_name;
|
|
ut64 addr;
|
|
st64 vtable_offset; // >= 0 if method is virtual, else -1
|
|
RzAnalysisMethodType method_type;
|
|
} RzAnalysisMethod;
|
|
|
|
typedef struct rz_analysis_base_class_t {
|
|
char *id; // id to identify the class attr
|
|
ut64 offset; // offset of the base class inside the derived class
|
|
char *class_name;
|
|
} RzAnalysisBaseClass;
|
|
|
|
typedef struct rz_analysis_vtable_t {
|
|
char *id; // id to identify the class attr
|
|
ut64 offset; // offset inside the class
|
|
ut64 addr; // where the content of the vtable is
|
|
ut64 size; // size (in bytes) of the vtable
|
|
} RzAnalysisVTable;
|
|
|
|
typedef enum {
|
|
RZ_ANALYSIS_CLASS_ERR_SUCCESS = 0,
|
|
RZ_ANALYSIS_CLASS_ERR_CLASH,
|
|
RZ_ANALYSIS_CLASS_ERR_NONEXISTENT_ATTR,
|
|
RZ_ANALYSIS_CLASS_ERR_NONEXISTENT_CLASS,
|
|
RZ_ANALYSIS_CLASS_ERR_OTHER
|
|
} RzAnalysisClassErr;
|
|
|
|
RZ_API void rz_analysis_class_recover_from_rzbin(RzAnalysis *analysis);
|
|
RZ_API void rz_analysis_class_recover_all(RzAnalysis *analysis);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_create(RzAnalysis *analysis, const char *name);
|
|
RZ_API void rz_analysis_class_delete(RzAnalysis *analysis, const char *name);
|
|
RZ_API bool rz_analysis_class_exists(RzAnalysis *analysis, const char *name);
|
|
RZ_API SdbList *rz_analysis_class_get_all(RzAnalysis *analysis, bool sorted);
|
|
RZ_API void rz_analysis_class_foreach(RzAnalysis *analysis, SdbForeachCallback cb, void *user);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_rename(RzAnalysis *analysis, const char *old_name, const char *new_name);
|
|
|
|
RZ_API void rz_analysis_class_method_fini(RzAnalysisMethod *meth);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_method_get(RzAnalysis *analysis, const char *class_name, const char *meth_name, RzAnalysisMethod *meth);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_method_get_by_addr(RzAnalysis *analysis, const char *class_name, ut64 addr, RzAnalysisMethod *method);
|
|
RZ_API RzVector /*<RzAnalysisMethod>*/ *rz_analysis_class_method_get_all(RzAnalysis *analysis, const char *class_name);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_method_set(RzAnalysis *analysis, const char *class_name, RzAnalysisMethod *meth);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_method_rename(RzAnalysis *analysis, const char *class_name, const char *old_meth_name, const char *new_meth_name);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_method_delete(RzAnalysis *analysis, const char *class_name, const char *meth_name);
|
|
RZ_API bool rz_analysis_class_method_exists(RzAnalysis *analysis, const char *class_name, const char *meth_name);
|
|
RZ_API bool rz_analysis_class_method_exists_by_addr(RzAnalysis *analysis, const char *class_name, ut64 addr);
|
|
RZ_API void rz_analysis_class_method_recover(RzAnalysis *analysis, RzBinClass *cls, RzList *methods);
|
|
|
|
RZ_API void rz_analysis_class_base_fini(RzAnalysisBaseClass *base);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_base_get(RzAnalysis *analysis, const char *class_name, const char *base_id, RzAnalysisBaseClass *base);
|
|
RZ_API RzVector /*<RzAnalysisBaseClass>*/ *rz_analysis_class_base_get_all(RzAnalysis *analysis, const char *class_name);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_base_set(RzAnalysis *analysis, const char *class_name, RzAnalysisBaseClass *base);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_base_delete(RzAnalysis *analysis, const char *class_name, const char *base_id);
|
|
|
|
RZ_API void rz_analysis_class_vtable_fini(RzAnalysisVTable *vtable);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_get(RzAnalysis *analysis, const char *class_name, const char *vtable_id, RzAnalysisVTable *vtable);
|
|
RZ_API RzVector /*<RzAnalysisVTable>*/ *rz_analysis_class_vtable_get_all(RzAnalysis *analysis, const char *class_name);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_set(RzAnalysis *analysis, const char *class_name, RzAnalysisVTable *vtable);
|
|
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_delete(RzAnalysis *analysis, const char *class_name, const char *vtable_id);
|
|
|
|
RZ_API RzGraph /*<RzGraphNodeInfo>*/ *rz_analysis_class_get_inheritance_graph(RzAnalysis *analysis);
|
|
|
|
RZ_API size_t rz_analysis_function_arg_count(RzAnalysis *a, RzAnalysisFunction *fcn);
|
|
RZ_API RZ_OWN RzPVector *rz_analysis_function_args(RzAnalysis *a, RzAnalysisFunction *fcn);
|
|
RZ_API RZ_OWN RzList *rz_analysis_types_from_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn);
|
|
RZ_API RZ_OWN RzCallable *rz_analysis_function_derive_type(RzAnalysis *analysis, RzAnalysisFunction *f);
|
|
|
|
/* PDB */
|
|
RZ_API void rz_parse_pdb_types(const RzTypeDB *typedb, const RzPdb *pdb);
|
|
|
|
/* DWARF */
|
|
RZ_API void rz_analysis_dwarf_process_info(const RzAnalysis *analysis, RzAnalysisDwarfContext *ctx);
|
|
RZ_API void rz_analysis_dwarf_integrate_functions(RzAnalysis *analysis, RzFlag *flags, Sdb *dwarf_sdb);
|
|
|
|
/* serialize */
|
|
RZ_API void rz_serialize_analysis_case_op_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisCaseOp *op);
|
|
RZ_API void rz_serialize_analysis_switch_op_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisSwitchOp *op);
|
|
RZ_API RzAnalysisSwitchOp *rz_serialize_analysis_switch_op_load(RZ_NONNULL const RzJson *json);
|
|
|
|
typedef void *RzSerializeAnalDiffParser;
|
|
RZ_API RzSerializeAnalDiffParser rz_serialize_analysis_diff_parser_new(void);
|
|
RZ_API void rz_serialize_analysis_diff_parser_free(RzSerializeAnalDiffParser parser);
|
|
RZ_API RZ_NULLABLE RzAnalysisDiff *rz_serialize_analysis_diff_load(RZ_NONNULL RzSerializeAnalDiffParser parser, RZ_NONNULL const RzJson *json);
|
|
RZ_API void rz_serialize_analysis_diff_save(RZ_NONNULL PJ *j, RZ_NONNULL RzAnalysisDiff *diff);
|
|
RZ_API void rz_serialize_analysis_blocks_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
|
|
RZ_API void rz_serialize_typelinks_save(RZ_NONNULL Sdb *db, RZ_NONNULL const RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_typelinks_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
|
|
typedef void *RzSerializeAnalGlobalVarParser;
|
|
RZ_API void rz_serialize_analysis_global_var_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *anal);
|
|
RZ_API RzSerializeAnalGlobalVarParser rz_serialize_analysis_global_var_parser_new(void);
|
|
RZ_API void rz_serialize_analysis_global_var_parser_free(RzSerializeAnalGlobalVarParser parser);
|
|
RZ_API bool rz_serialize_analysis_global_var_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
|
|
/**
|
|
* RzAnalysis must not contain any blocks when calling this function!
|
|
* All loaded blocks will have a ref of 1 after this function and should be unrefd once after loading functions.
|
|
*/
|
|
RZ_API bool rz_serialize_analysis_blocks_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
|
|
typedef void *RzSerializeAnalVarParser;
|
|
RZ_API RzSerializeAnalVarParser rz_serialize_analysis_var_parser_new(void);
|
|
RZ_API void rz_serialize_analysis_var_parser_free(RzSerializeAnalVarParser parser);
|
|
RZ_API RZ_NULLABLE RzAnalysisVar *rz_serialize_analysis_var_load(RZ_NONNULL RzAnalysisFunction *fcn, RZ_NONNULL RzSerializeAnalVarParser parser, RZ_NONNULL const RzJson *json);
|
|
|
|
RZ_API void rz_serialize_analysis_functions_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_functions_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RzSerializeAnalDiffParser diff_parser, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_function_noreturn_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_function_noreturn_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_xrefs_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_xrefs_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_meta_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_meta_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_hints_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_hints_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_classes_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_classes_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_types_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_types_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_sign_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_sign_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_imports_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_imports_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_pin_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_pin_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
RZ_API void rz_serialize_analysis_cc_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_cc_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
|
|
RZ_API void rz_serialize_analysis_save(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis);
|
|
RZ_API bool rz_serialize_analysis_load(RZ_NONNULL Sdb *db, RZ_NONNULL RzAnalysis *analysis, RZ_NULLABLE RzSerializeResultInfo *res);
|
|
|
|
typedef struct rz_analysis_signature_t {
|
|
char *bin_name; ///< RzBinPlugin name (elf64 and pe64 are named as elf and pe)
|
|
char *arch_name; ///< RzAsmPlugin name
|
|
ut32 arch_bits; ///< Architecture bits
|
|
const char *base_name; ///< basename of file
|
|
const char *short_path; ///< Short path without sigdb path
|
|
char *file_path; ///< full path to the signature file
|
|
} RzAnalysisSignature;
|
|
|
|
RZ_API RzList /*<RzAnalysisSignature>*/ *rz_analysis_sigdb_load_database(RZ_NONNULL const char *sigdb_path);
|
|
|
|
/* plugin pointers */
|
|
extern RzAnalysisPlugin rz_analysis_plugin_null;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_6502;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_8051;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_amd29k;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_arc;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_arm_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_avr;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_bf;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_chip8;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_cr16;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_cris;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_dalvik;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_ebc;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_gb;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_h8300;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_hexagon;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_i4004;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_i8080;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_java;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_m68k_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_m680x_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_malbolge;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_mcore;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_mips_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_mips_gnu;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_msp430;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_nios2;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_or1k;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_pic;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_ppc_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_propeller;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_riscv;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_riscv_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_rsp;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_sh;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_snes;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_sparc_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_sparc_gnu;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_spc700;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_sysz;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_tms320;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_tms320c64x;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_tricore;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_v810;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_v850;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_vax;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_wasm;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_x86;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_x86_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_x86_im;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_x86_simple;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_x86_udis;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_xap;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_xcore_cs;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_xtensa;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_z80;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_pyc;
|
|
extern RzAnalysisPlugin rz_analysis_plugin_luac;
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
|
|
#endif
|
|
#endif
|