23 "esil.nonull",
"dbg.follow",
NULL);
31 eprintf(
"Stack isn't initialized.\n");
32 eprintf(
"Try running aei and aeim commands before aft for default stack initialization\n");
52 ut64 write_addr = 0LL;
53 if (instr_trace && (instr_trace->stats & RZ_IL_TRACE_INS_HAS_MEM_W)) {
57 write_addr =
mem->addr;
62 return (write_addr ==
sp +
size);
72 if (!*
name || !strcmp(
name,
"...")) {
81 if (!is_default && (strlen(
v->name) > strlen(
name))) {
129 eprintf(
"Cannot clone the type for the variable \"%s.%s\"\n", var->
fcn->
name, var->
name);
137 eprintf(
"Cannot convert the type for the variable \"%s.%s\" into pointer\n", var->
fcn->
name, var->
name);
160 char *error_msg =
NULL;
162 if (!realtype && error_msg) {
163 eprintf(
"Fail to parse type \"%s\":\n%s\n",
type, error_msg);
180 char *
tmp = strchr(op_esil,
',');
187 if ((analysis->
bits == 64) && (ri->
size == 32)) {
213 return reg_op->value;
226 char arr[10] = { 0 };
227 char *ptr = strchr(fmt,
'%');
228 fmt[strlen(fmt) - 1] =
'\0';
241 const char *query =
sdb_fmt(
"spec.%s.%s", spec,
arr);
246 ptr = strchr(ptr,
'%');
285 if (!ht_up_insert(cache,
addr,
op)) {
330 #define DEFAULT_MAX 3
331 #define REGNAME_SIZE 10
346 int prev_idx,
bool userfnc,
ut64 caddr, HtUP *op_cache) {
355 bool stack_rev =
false, in_stack =
false, format =
false;
357 if (!fcn_name || !cc) {
364 if (place && !strcmp(place,
"stack_rev")) {
371 if (
verbose && !strncmp(fcn_name,
"sym.imp.", 8)) {
372 eprintf(
"%s missing function definition\n", fcn_name + 8);
388 for (
i = 0;
i <
max;
i++) {
389 int arg_num = stack_rev ? (
max - 1 -
i) :
i;
393 if (rz_list_empty(
types)) {
405 if (!
type && !userfnc) {
419 bool cmt_set =
false;
422 for (j =
idx; j >= prev_idx; j--) {
424 ut64 instr_addr = instr_trace->addr;
425 if (instr_addr <
baddr) {
453 char formatstr[0x200];
456 formatstr[
read] =
'\0';
506 }
else if (var && res && xaddr && (xaddr !=
UT64_MAX)) {
532 return a->addr >
b->addr ? 1 : (
a->addr <
b->addr ? -1 : 0);
546 mov_addr = prev_trace->addr;
569 return !
ctx->resolved &&
ctx->ret_type &&
ctx->ret_reg;
596 RzILTraceRegOp *single_write_reg =
NULL;
597 if (trace && (trace->stats & RZ_IL_TRACE_INS_HAS_REG_W)) {
603 if (
ctx->ret_reg && *
src && strstr(
ctx->ret_reg,
src)) {
610 ctx->resolved =
true;
613 if (single_write_reg && single_write_reg->reg_name) {
614 ctx->ret_reg =
strdup(single_write_reg->reg_name);
617 }
else if (single_write_reg) {
619 (single_write_reg->reg_name && strstr(
ctx->ret_reg, single_write_reg->reg_name))) {
620 ctx->resolved =
true;
643 bool prev_var =
false;
644 char *fcn_name =
NULL;
645 bool userfnc =
false;
654 char *full_name =
NULL;
659 full_name = fcn_call->
name;
660 callee_addr = fcn_call->
addr;
666 callee_addr = aop->
ptr;
673 fcn_name =
strdup(full_name);
678 fcn_name =
strdup(full_name);
684 type_match(core, fcn_name, aop->
addr, bb->
addr, cc, prev_idx, userfnc, callee_addr, op_cache);
685 prev_idx =
ctx->cur_idx;
692 ctx->retctx->resolved =
false;
695 if (!strcmp(fcn_name,
"__stack_chk_fail")) {
719 if (sign || aop->
sign) {
732 if (prop &&
match && prev_var && prev_type) {
755 jmp_addr += jmp_op->
size;
768 ctx->str_flag =
false;
783 ctx->str_flag =
true;
787 ctx->str_flag =
true;
792 RzILTraceRegOp *w_reg =
NULL;
793 if (cur_instr_trace) {
794 if (cur_instr_trace->stats & RZ_IL_TRACE_INS_HAS_REG_W) {
809 prev_type = var->
type;
829 const int minopcode =
RZ_MAX(1, mininstrsz);
845 opt = dtrace->
ht->opt;
846 ht_pp_free(dtrace->
ht);
847 dtrace->
ht = ht_pp_new_size(fcn->
ninstr, opt.dupvalue, opt.freefn, opt.calcsizeV);
848 dtrace->
ht->opt = opt;
863 HtUP *op_cache =
NULL;
876 rz_list_foreach (fcn->
bbs, it, bb) {
879 ht_up_free(op_cache);
910 ht_uu_update(loop_table,
addr, loop_count);
927 rz_list_foreach (fcns, it, fcn) {
958 ht_up_free(op_cache);
RZ_API RZ_OWN char * rz_analysis_function_name_guess(RzTypeDB *typedb, RZ_NONNULL char *name)
Checks if varions function name variations present in the database.
RZ_API RzList * rz_analysis_get_functions_in(RzAnalysis *analysis, ut64 addr)
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
static void retype_callee_arg(RzAnalysis *analysis, const char *callee_name, bool in_stack, const char *place, int size, RZ_BORROW RzType *type)
static bool var_type_simple_to_complex(const RzTypeDB *typedb, RzType *a, RzType *b)
void propagate_types_among_used_variables(RzCore *core, HtUP *op_cache, RzAnalysisFunction *fcn, RzAnalysisBlock *bb, RzAnalysisOp *aop, struct TypeAnalysisCtx *ctx)
RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, HtUU *loop_table)
static void var_type_set_sign(RzAnalysis *analysis, RzAnalysisVar *var, bool sign)
static void get_src_regname(RzCore *core, ut64 addr, char *regname, int size)
static bool return_type_analysis_context_unresolved(struct ReturnTypeAnalysisCtx *ctx)
static void type_match(RzCore *core, char *fcn_name, ut64 addr, ut64 baddr, const char *cc, int prev_idx, bool userfnc, ut64 caddr, HtUP *op_cache)
static ut64 get_addr(RzAnalysis *analysis, const char *regname, int idx)
void free_op_cache_kv(HtUPKv *kv)
static void var_type_set_resolve_overlaps(RzAnalysis *analysis, RzAnalysisVar *var, RZ_BORROW RzType *type, bool ref)
void handle_stack_canary(RzCore *core, RzAnalysisOp *aop, int cur_idx)
static void var_type_set(RzAnalysis *analysis, RzAnalysisVar *var, RZ_BORROW RzType *type, bool ref, bool resolve_overlaps)
static RzList * parse_format(RzCore *core, char *fmt)
static bool analysis_emul_init(RzCore *core, RzConfigHold *hc, RzDebugTrace **dt, RzAnalysisEsilTrace **et, RzAnalysisRzilTrace **rt)
static bool type_pos_hit(RzAnalysis *analysis, RzILTraceInstruction *instr_trace, bool in_stack, int size, const char *place)
RzCallable * function_type_derive(RzAnalysis *analysis, RZ_NONNULL const char *fcn_name, bool *owned)
static void vars_resolve_overlaps(RzPVector *vars)
static void analysis_emul_restore(RzCore *core, RzConfigHold *hc, RzDebugTrace *dt, RzAnalysisEsilTrace *et, RzAnalysisRzilTrace *rt)
RzAnalysisOp * op_cache_get(HtUP *cache, RzCore *core, ut64 addr)
static void var_type_set_str(RzAnalysis *analysis, RzAnalysisVar *var, const char *type, bool ref)
static void propagate_return_type_pointer(RzCore *core, RzAnalysisOp *aop, RzPVector *used_vars, ut64 addr, struct ReturnTypeAnalysisCtx *ctx)
static void propagate_return_type(RzCore *core, RzAnalysisOp *aop, RzAnalysisOp *next_op, RzILTraceInstruction *trace, struct ReturnTypeAnalysisCtx *ctx, RzPVector *used_vars)
static void var_rename(RzAnalysis *analysis, RzAnalysisVar *v, const char *name, ut64 addr)
static int bb_cmpaddr(const void *_a, const void *_b)
bool function_argument_type_derive(RZ_NULLABLE const RzCallable *callable, int arg_num, RzType **type, char **name)
static ut64 baddr(RzBinFile *bf)
RZ_API RZ_OWN RzType * rz_type_parse_string_single(RzTypeParser *parser, const char *code, char **error_msg)
Parses the single C type definition.
RZ_API RzAnalysisOp * rz_core_analysis_op(RzCore *core, ut64 addr, int mask)
RZ_API const char * rz_analysis_cc_func(RzAnalysis *analysis, const char *func_name)
RZ_API const char * rz_analysis_cc_arg(RzAnalysis *analysis, const char *convention, int n)
RZ_API bool rz_analysis_cc_exist(RzAnalysis *analysis, const char *convention)
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 int rz_core_esil_step(RzCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver)
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
RZ_API void rz_cons_break_pop(void)
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
RZ_API bool rz_cons_is_breaked(void)
RZ_API RzAnalysisEsilTrace * rz_analysis_esil_trace_new(RzAnalysisEsil *esil)
RZ_API void rz_analysis_esil_trace_free(RzAnalysisEsilTrace *trace)
RZ_API RZ_BORROW RzILTraceInstruction * rz_analysis_esil_get_instruction_trace(RZ_NONNULL RzAnalysisEsilTrace *etrace, int idx)
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
RZ_API RzAnalysisFunction * rz_analysis_get_function_byname(RzAnalysis *a, const char *name)
RZ_API RZ_OWN RzCallable * rz_analysis_function_derive_type(RzAnalysis *analysis, RzAnalysisFunction *f)
Derives the RzCallable type for the given function.
RZ_API RzAnalysisBlock * rz_analysis_fcn_bbget_in(const RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr)
RZ_API bool rz_flag_exist_at(RzFlag *f, const char *flag_prefix, ut16 fp_size, ut64 off)
RZ_API RzFlagItem * rz_flag_get_by_spaces(RzFlag *f, ut64 off,...)
RZ_API char * sdb_fmt(const char *fmt,...)
RZ_API bool rz_type_is_char_ptr_nested(RZ_NONNULL const RzType *type)
Checks if the pointer RzType is a nested pointer of string ("char **", "char ***",...
RZ_API RzTypeCond rz_type_cond_invert(RzTypeCond cond)
return the inverted condition
RZ_API bool rz_type_is_void_ptr(RZ_NONNULL const RzType *type)
Checks if the pointer RzType is abstract pointer ("void *")
RZ_API bool rz_type_is_default(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is default.
RZ_API RZ_OWN RzType * rz_type_pointer_of_type(const RzTypeDB *typedb, RZ_NONNULL RzType *type, bool is_const)
Creates a new pointer RzType from the given RzType.
RZ_API bool rz_type_atomic_is_void(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is "void".
RZ_API bool rz_type_integral_set_sign(const RzTypeDB *typedb, RZ_NONNULL RzType **type, bool sign)
If the type is unsigned it sets the sign.
RZ_API void rz_config_hold_restore(RzConfigHold *h)
Restore whatever config options were previously saved in h.
RZ_API RzConfigHold * rz_config_hold_new(RzConfig *cfg)
Create an opaque object to save/restore some configuration options.
RZ_API bool rz_config_hold_i(RzConfigHold *h,...)
Save the current values of a list of config options that have integer values.
RZ_API void rz_config_hold_free(RzConfigHold *h)
Free a RzConfigHold object h.
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API bool rz_analysis_il_reg_trace_contains(RzILTraceInstruction *trace, const char *regname, RzILTraceOpType op_type)
RZ_API RzILTraceRegOp * rz_analysis_il_get_reg_op_trace(RzILTraceInstruction *trace, const char *regname, RzILTraceOpType op_type)
return memset(p, 0, total)
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
RZ_API void rz_analysis_op_free(void *op)
RZ_API bool rz_analysis_op_nonlinear(int t)
insn_type_descr_t types[]
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
RZ_API RzRegItem * rz_reg_index_get(RzReg *reg, int idx)
RZ_API const char * rz_reg_32_to_64(RzReg *reg, const char *rreg32)
RZ_API bool rz_reg_set_value(RzReg *reg, RzRegItem *item, ut64 value)
@ RZ_ANALYSIS_OP_DIR_READ
@ RZ_ANALYSIS_OP_DIR_WRITE
@ RZ_ANALYSIS_OP_MASK_BASIC
@ RZ_ANALYSIS_OP_MASK_VAL
@ RZ_ANALYSIS_OP_MASK_ESIL
#define RZ_ANALYSIS_OP_TYPE_MASK
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
@ RZ_ANALYSIS_VAR_KIND_REG
@ RZ_ANALYSIS_VAR_KIND_BPV
@ RZ_ANALYSIS_OP_TYPE_CMP
@ RZ_ANALYSIS_OP_TYPE_LOAD
@ RZ_ANALYSIS_OP_TYPE_JMP
@ RZ_ANALYSIS_OP_TYPE_CALL
@ RZ_ANALYSIS_OP_TYPE_STORE
@ RZ_ANALYSIS_OP_TYPE_PUSH
@ RZ_ANALYSIS_OP_TYPE_CJMP
@ RZ_ANALYSIS_OP_TYPE_MOV
@ RZ_ANALYSIS_OP_TYPE_ILL
@ RZ_ANALYSIS_OP_TYPE_UCALL
@ RZ_ANALYSIS_OP_TYPE_RET
@ RZ_ANALYSIS_OP_TYPE_LEA
#define rz_warn_if_reached()
#define rz_return_if_fail(expr)
#define rz_return_val_if_fail(expr, val)
#define RZ_FLAGS_FS_IMPORTS
#define RZ_FLAGS_FS_STRINGS
static ut64 rz_read_ble(const void *src, bool big_endian, int size)
RZ_API bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
RZ_API int rz_io_nread_at(RzIO *io, ut64 addr, ut8 *buf, int len)
RZ_API char * rz_str_new(const char *str)
RZ_API size_t rz_str_ncpy(char *dst, const char *src, size_t n)
Secure string copy with null terminator.
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
RZ_API bool rz_strbuf_is_empty(RzStrBuf *sb)
@ RZ_TYPE_KIND_IDENTIFIER
static void ** rz_pvector_index_ptr(RzPVector *vec, size_t index)
static size_t rz_pvector_len(const RzPVector *vec)
static bool rz_pvector_empty(RzPVector *vec)
static void * rz_pvector_at(const RzPVector *vec, size_t index)
#define rz_pvector_foreach(vec, it)
RZ_API const char * sdb_const_get(Sdb *s, const char *key, ut32 *cas)
struct ReturnTypeAnalysisCtx * retctx
RzAnalysisEsilTrace * trace
RzAnalysisOpDirection direction
struct rz_analysis_esil_t * esil
int size
in bits> 8,16,32,64 ... 128/256
int index
Index in register profile.
type constrained by the type conditions
RZ_API void rz_debug_trace_free(RzDebugTrace *trace)
RZ_API RzDebugTrace * rz_debug_trace_new(void)
RZ_API RZ_BORROW RzCallable * rz_type_func_get(RzTypeDB *typedb, RZ_NONNULL const char *name)
Returns the RzCallable from the database by name.
RZ_API int rz_type_func_args_count(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns arguments' count.
RZ_API RZ_BORROW RzType * rz_type_func_ret(RzTypeDB *typedb, RZ_NONNULL const char *name)
Searches for the RzCallable type in types database and returns return type.
RZ_API bool rz_type_func_exist(RzTypeDB *typedb, RZ_NONNULL const char *name)
Checks if the RzCallable type exists in the database given the name.
RZ_API void rz_type_callable_free(RZ_NONNULL RzCallable *callable)
Frees the RzCallable.
RZ_API void rz_type_free(RZ_NULLABLE RzType *type)
Frees the RzType.
RZ_API RZ_OWN RzType * rz_type_clone(RZ_BORROW RZ_NONNULL const RzType *type)
Creates an exact clone of the RzType.
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
RZ_API bool rz_type_is_integral(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is Integral typeclass.
RZ_API void rz_analysis_var_resolve_overlaps(RzAnalysisVar *var)
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_get_var(RzAnalysisFunction *fcn, char kind, int delta)
RZ_API RZ_BORROW RzPVector * rz_analysis_function_get_vars_used_at(RzAnalysisFunction *fcn, ut64 op_addr)
RZ_API void rz_analysis_var_add_constraint(RzAnalysisVar *var, RZ_BORROW RzTypeConstraint *constraint)
RZ_API bool rz_analysis_var_rename(RzAnalysisVar *var, const char *new_name, bool verbose)
RZ_API RzAnalysisVar * rz_analysis_var_get_dst_var(RzAnalysisVar *var)
RZ_API void rz_analysis_var_set_type(RzAnalysisVar *var, RZ_OWN RzType *type, bool resolve_overlaps)
RZ_DEPRECATE RZ_API RzAnalysisVar * rz_analysis_get_used_function_var(RzAnalysis *analysis, ut64 addr)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
static char * regname(int reg)
int read(izstream &zs, T *x, Items items)