Rizin
unix-like reverse engineering framework and cli tools
canalysis.c File Reference
#include <string.h>
#include <rz_types.h>
#include <rz_list.h>
#include <rz_flag.h>
#include <rz_core.h>
#include <rz_bin.h>
#include <ht_uu.h>
#include <rz_util/rz_graph_drawable.h>
#include <rz_util/rz_path.h>
#include "core_private.h"

Go to the source code of this file.

Classes

struct  HintNode
 
struct  BlockRecurseCtx
 
struct  block_flags_stat_t
 
struct  EsilBreakCtx
 
struct  IterCtx
 
struct  RzCoreAnalPaths
 
struct  core_noretl
 

Macros

#define MAX_SCAN_SIZE   0x7ffffff
 
#define MINLEN   1
 
#define HINTCMD_ADDR(hint, fmt, x)   rz_cons_printf(fmt " @ 0x%" PFMT64x "\n", x, (hint)->addr)
 
#define END_ADDR
 
#define USE_ID   1
 
#define REG_SET_SIZE   (RZ_ANALYSIS_CC_MAXARG + 2)
 
#define OPSZ   8
 
#define CHECKREF(x)   ((refptr && (x) == refptr) || !refptr)
 
#define CALL_BUF_SIZE   32
 

Enumerations

enum  { RZ_ARCH_THUMB , RZ_ARCH_ARM32 , RZ_ARCH_ARM64 , RZ_ARCH_MIPS }
 

Functions

 HEAPTYPE (ut64)
 
static void loganalysis (ut64 from, ut64 to, int depth)
 
RZ_IPI int bb_cmpaddr (const void *_a, const void *_b)
 
RZ_IPI int fcn_cmpaddr (const void *_a, const void *_b)
 
static char * getFunctionName (RzCore *core, ut64 addr)
 
static char * getFunctionNamePrefix (RzCore *core, ut64 off, const char *name)
 
static int is_string (const ut8 *buf, int size, int *len)
 
static char * is_string_at (RzCore *core, ut64 addr, int *olen)
 
RZ_API ut64 rz_core_analysis_address (RzCore *core, ut64 addr)
 
RZ_IPI void rz_core_analysis_bbs_asciiart (RzCore *core, RzAnalysisFunction *fcn)
 
RZ_IPI void rz_core_analysis_fcn_returns (RzCore *core, RzAnalysisFunction *fcn)
 
static int casecmp (const void *_a, const void *_b)
 
static ut64 __opaddr (RzAnalysisBlock *b, ut64 addr)
 
static void bb_info_print (RzCore *core, RzAnalysisFunction *fcn, RzAnalysisBlock *bb, ut64 addr, RzOutputMode mode, PJ *pj, RzTable *t)
 
static int bb_cmp (const void *a, const void *b)
 
RZ_IPI void rz_core_analysis_bbs_info_print (RzCore *core, RzAnalysisFunction *fcn, RzCmdStateOutput *state)
 
RZ_IPI void rz_core_analysis_bb_info_print (RzCore *core, RzAnalysisBlock *bb, ut64 addr, RzCmdStateOutput *state)
 
RZ_API void rz_core_analysis_autoname_all_fcns (RzCore *core)
 
static bool blacklisted_word (const char *name)
 
RZ_API RZ_OWN char * rz_core_analysis_function_autoname (RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn)
 Suggest a name for the function. More...
 
RZ_API void rz_core_analysis_function_strings_print (RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn, RZ_NULLABLE PJ *pj)
 Print all string flags referenced by the function. More...
 
static ut64next_append (ut64 *next, int *nexti, ut64 v)
 
static void rz_analysis_set_stringrefs (RzCore *core, RzAnalysisFunction *fcn)
 
static bool rz_analysis_try_get_fcn (RzCore *core, RzAnalysisXRef *xref, int fcndepth, int refdepth)
 
static int rz_analysis_analyze_fcn_refs (RzCore *core, RzAnalysisFunction *fcn, int depth)
 
static void function_rename (RzFlag *flags, RzAnalysisFunction *fcn)
 
static void autoname_imp_trampoline (RzCore *core, RzAnalysisFunction *fcn)
 
static void set_fcn_name_from_flag (RzAnalysisFunction *fcn, RzFlagItem *f, const char *fcnpfx)
 
static bool is_entry_flag (RzFlagItem *f)
 
static int __core_analysis_fcn (RzCore *core, ut64 at, ut64 from, int reftype, int depth)
 
static char * get_title (ut64 addr)
 
RZ_API RzAnalysisOprz_core_analysis_op (RzCore *core, ut64 addr, int mask)
 
static void print_hint_h_format (HintNode *node)
 
static void hint_node_print (HintNode *node, RzOutputMode mode, PJ *pj)
 
void hint_node_free (RBNode *node, void *user)
 
int hint_node_cmp (const void *incoming, const RBNode *in_tree, void *user)
 
bool print_addr_hint_cb (ut64 addr, const RzVector *records, void *user)
 
bool print_arch_hint_cb (ut64 addr, RZ_NULLABLE const char *arch, void *user)
 
bool print_bits_hint_cb (ut64 addr, int bits, void *user)
 
static void print_hint_tree (RBTree tree, RzCmdStateOutput *state)
 
RZ_API void rz_core_analysis_hint_list_print (RzAnalysis *a, RzCmdStateOutput *state)
 
RZ_API void rz_core_analysis_hint_print (RzAnalysis *a, ut64 addr, RzCmdStateOutput *state)
 
static char * core_analysis_graph_label (RzCore *core, RzAnalysisBlock *bb, int opts)
 
static char * palColorFor (const char *k)
 
static void core_analysis_color_curr_node (RzCore *core, RzAnalysisBlock *bbi)
 
static int core_analysis_graph_construct_edges (RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj, Sdb *DB)
 
static int core_analysis_graph_construct_nodes (RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj, Sdb *DB)
 
static int core_analysis_graph_nodes (RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj)
 
RZ_API bool rz_core_analysis_bb_seek (RzCore *core, ut64 addr)
 
RZ_API int rz_core_analysis_esil_fcn (RzCore *core, ut64 at, ut64 from, int reftype, int depth)
 
static int find_sym_flag (const void *a1, const void *a2)
 
static bool is_skippable_addr (RzCore *core, ut64 addr)
 
RZ_API int rz_core_analysis_fcn (RzCore *core, ut64 at, ut64 from, int reftype, int depth)
 
RZ_API int rz_core_analysis_fcn_clean (RzCore *core, ut64 addr)
 
RZ_API int rz_core_print_bb_custom (RzCore *core, RzAnalysisFunction *fcn)
 
RZ_API int rz_core_print_bb_gml (RzCore *core, RzAnalysisFunction *fcn)
 
RZ_API void rz_core_analysis_datarefs (RzCore *core, ut64 addr)
 
RZ_API void rz_core_analysis_coderefs (RzCore *core, ut64 addr)
 
static void add_single_addr_xrefs (RzCore *core, ut64 addr, RzGraph *graph)
 
RZ_API RzGraphrz_core_analysis_importxrefs (RzCore *core)
 
RZ_API RzGraphrz_core_analysis_codexrefs (RzCore *core, ut64 addr)
 
static int RzAnalysisRef_cmp (const RzAnalysisXRef *xref1, const RzAnalysisXRef *xref2)
 
RZ_API void rz_core_analysis_callgraph (RzCore *core, ut64 addr, int fmt)
 
RZ_API char * rz_core_analysis_fcn_name (RzCore *core, RzAnalysisFunction *fcn)
 
RZ_API RzListrz_core_analysis_fcn_get_calls (RzCore *core, RzAnalysisFunction *fcn)
 
static RzListrecurse_bb (RzCore *core, ut64 addr, RzAnalysisBlock *dest)
 
static RzListrecurse (RzCore *core, RzAnalysisBlock *from, RzAnalysisBlock *dest)
 
static bool analysis_block_on_exit (RzAnalysisBlock *bb, BlockRecurseCtx *ctx)
 
static bool analysis_block_cb (RzAnalysisBlock *bb, BlockRecurseCtx *ctx)
 
RZ_API void rz_core_recover_vars (RzCore *core, RzAnalysisFunction *fcn, bool argonly)
 
static bool analysis_path_exists (RzCore *core, ut64 from, ut64 to, RzList *bbs, int depth, HtUP *state, HtUP *avoid)
 
static RzListanalysis_graph_to (RzCore *core, ut64 addr, int depth, HtUP *avoid)
 
RZ_API RzListrz_core_analysis_graph_to (RzCore *core, ut64 addr, int n)
 
RZ_API bool rz_core_analysis_graph (RzCore *core, ut64 addr, int opts)
 
static int core_analysis_followptr (RzCore *core, int type, ut64 at, ut64 ptr, ut64 ref, int code, int depth)
 
static bool opiscall (RzCore *core, RzAnalysisOp *aop, ut64 addr, const ut8 *buf, int len, int arch)
 
RZ_API int rz_core_analysis_search (RzCore *core, ut64 from, ut64 to, ut64 ref, int mode)
 
static bool core_search_for_xrefs_in_boundaries (RzCore *core, ut64 from, ut64 to)
 
RZ_API void rz_core_analysis_resolve_jumps (RZ_NONNULL RzCore *core)
 Resolves any unresolved jump. More...
 
RZ_API bool rz_core_analysis_refs (RZ_NONNULL RzCore *core, size_t nbytes)
 Analyze xrefs and prints the result. More...
 
static bool is_valid_xref (RzCore *core, ut64 xref_to, RzAnalysisXRefType type, int cfg_debug)
 Validates a xref. Mainly checks if it points out of the memory map. More...
 
static void set_new_xref (RzCore *core, ut64 xref_from, ut64 xref_to, RzAnalysisXRefType type, bool decode_str)
 Sets a new xref according to the given to and from addresses. More...
 
RZ_API int rz_core_analysis_search_xrefs (RZ_NONNULL RzCore *core, ut64 from, ut64 to)
 Searches for xrefs in the range of the paramters 'from' and 'to'. More...
 
static bool isValidSymbol (RzBinSymbol *symbol)
 
static bool isSkippable (RzBinSymbol *s)
 
RZ_API int rz_core_analysis_all (RzCore *core)
 
RZ_API int rz_core_analysis_data (RzCore *core, ut64 addr, int count, int depth, int wordsize)
 
static bool block_flags_stat (RzFlagItem *fi, void *user)
 
RZ_API RZ_OWN RzCoreAnalysisStats * rz_core_analysis_get_stats (RZ_NONNULL RzCore *core, ut64 from, ut64 to, ut64 step)
 
RZ_API void rz_core_analysis_stats_free (RzCoreAnalysisStats *s)
 
RZ_API ut64 rz_core_analysis_stats_get_block_from (RZ_NONNULL const RzCoreAnalysisStats *s, size_t i)
 
RZ_API ut64 rz_core_analysis_stats_get_block_to (RZ_NONNULL const RzCoreAnalysisStats *s, size_t i)
 
RZ_API RzListrz_core_analysis_cycles (RzCore *core, int ccl)
 
RZ_API void rz_core_analysis_undefine (RzCore *core, ut64 off)
 
RZ_API void rz_core_analysis_fcn_merge (RzCore *core, ut64 addr, ut64 addr2)
 
static void cccb (void *u)
 
static void add_string_ref (RzCore *core, ut64 xref_from, ut64 xref_to)
 
static bool myvalid (RzIO *io, ut64 addr)
 
static const char * reg_name_for_access (RzAnalysisOp *op, RzAnalysisVarAccessType type)
 
static ut64 delta_for_access (RzAnalysisOp *op, RzAnalysisVarAccessType type)
 
static void handle_var_stack_access (RzAnalysisEsil *esil, ut64 addr, RzAnalysisVarAccessType type, int len)
 
static int esilbreak_mem_write (RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
 
static int esilbreak_mem_read (RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
 
static int esilbreak_reg_write (RzAnalysisEsil *esil, const char *name, ut64 *val)
 
static void getpcfromstack (RzCore *core, RzAnalysisEsil *esil)
 
static int find_bb (ut64 *addr, RzAnalysisBlock *bb)
 
static bool get_next_i (IterCtx *ctx, size_t *next_i)
 
RZ_API void rz_core_analysis_esil (RzCore *core, ut64 addr, ut64 size, RZ_NULLABLE RzAnalysisFunction *fcn)
 
static bool isValidAddress (RzCore *core, ut64 addr)
 
static bool stringAt (RzCore *core, ut64 addr)
 
RZ_API int rz_core_search_value_in_range (RzCore *core, RzInterval search_itv, ut64 vmin, ut64 vmax, int vsize, inRangeCb cb, void *cb_user)
 
static bool printAnalPaths (RzCoreAnalPaths *p, PJ *pj)
 
static void analPaths (RzCoreAnalPaths *p, PJ *pj)
 
static void analPathFollow (RzCoreAnalPaths *p, ut64 addr, PJ *pj)
 
RZ_API void rz_core_analysis_paths (RzCore *core, ut64 from, ut64 to, bool followCalls, int followDepth, bool is_json)
 
static bool analyze_noreturn_function (RzCore *core, RzAnalysisFunction *f)
 
RZ_API void rz_core_analysis_flag_every_function (RzCore *core)
 
static bool add_mmio_flag_cb (void *user, const ut64 addr, const void *v)
 
static bool add_mmio_extended_flag_cb (void *user, const ut64 addr, const void *v)
 
RZ_API void rz_platform_profile_add_flag_every_io (RzPlatformProfile *profile, RzFlag *flags)
 Adds the IO and extended IO registers from the CPU profiles as flags. More...
 
static bool add_arch_platform_flag_comment_cb (void *user, const ut64 addr, const void *v)
 
RZ_API bool rz_platform_index_add_flags_comments (RzCore *core)
 Adds the information from the Platform Profiles as flags and comments. More...
 
RZ_API bool rz_core_analysis_function_rename (RzCore *core, ut64 addr, const char *_name)
 
RZ_API bool rz_core_analysis_function_add (RzCore *core, const char *name, ut64 addr, bool analyze_recursively)
 
RZ_IPI char * rz_core_analysis_function_signature (RzCore *core, RzOutputMode mode, char *fcn_name)
 
static RzAnalysisBlockfind_block_at_xref_addr (RzCore *core, ut64 addr)
 
static void relocation_function_process_noreturn (RzCore *core, RzAnalysisBlock *b, SetU *todo, ut64 opsize, ut64 reladdr, ut64 addr)
 
static void relocation_noreturn_process (RzCore *core, RzList *noretl, SetU *todo, RzAnalysisBlock *b, RzBinReloc *rel, ut64 opsize, ut64 addr)
 
static bool process_reference_noreturn_cb (void *u, const ut64 k, const void *v)
 
static bool process_refs_cb (void *u, const ut64 k, const void *v)
 
static bool reanalyze_fcns_cb (void *u, const ut64 k, const void *v)
 
RZ_API void rz_core_analysis_propagate_noreturn_relocs (RzCore *core, ut64 addr)
 
RZ_API void rz_core_analysis_propagate_noreturn (RzCore *core, ut64 addr)
 
RZ_IPI bool rz_core_analysis_var_rename (RzCore *core, const char *name, const char *newname)
 
static bool is_unknown_file (RzCore *core)
 
static bool is_apple_target (RzCore *core)
 
RZ_API bool rz_core_analysis_everything (RzCore *core, bool experimental, char *dh_orig)
 
static void analysis_sigdb_add (RzSigDb *sigs, const char *path, bool with_details)
 
RZ_API RZ_OWN RzListrz_core_analysis_sigdb_list (RZ_NONNULL RzCore *core, bool with_details)
 Returns all the signatures found in the default path. More...
 
RZ_API void rz_core_analysis_sigdb_print (RZ_NONNULL RzCore *core, RZ_NONNULL RzTable *table)
 Adds all the signatures to a RzTable structure. More...
 
RZ_API bool rz_core_analysis_sigdb_apply (RZ_NONNULL RzCore *core, RZ_NULLABLE int *n_applied, RZ_NULLABLE const char *filter)
 tries to apply the signatures in the flirt.sigdb.path More...
 
RZ_IPI bool rz_core_analysis_function_delete_var (RzCore *core, RzAnalysisFunction *fcn, RzAnalysisVarKind kind, const char *id)
 
RZ_IPI char * rz_core_analysis_var_display (RzCore *core, RzAnalysisVar *var, bool add_name)
 
RZ_IPI char * rz_core_analysis_all_vars_display (RzCore *core, RzAnalysisFunction *fcn, bool add_name)
 
RZ_IPI bool rz_analysis_var_global_list_show (RzAnalysis *analysis, RzCmdStateOutput *state, RZ_NULLABLE const char *name)
 
static int check_rom_exists (const void *value, const void *data)
 
RZ_API bool rz_analysis_add_device_peripheral_map (RzBinObject *o, RzAnalysis *analysis)
 Maps the device peripherals as sections. More...
 
RZ_IPI bool rz_core_analysis_types_propagation (RzCore *core)
 
RZ_IPI bool rz_core_analysis_function_set_signature (RzCore *core, RzAnalysisFunction *fcn, const char *newsig)
 
RZ_IPI void rz_core_analysis_function_signature_editor (RzCore *core, ut64 addr)
 
RZ_IPI void rz_core_analysis_function_until (RzCore *core, ut64 addr_end)
 
static bool archIsThumbable (RzCore *core)
 
static void _CbInRangeAav (RzCore *core, ut64 from, ut64 to, int vsize, void *user)
 
RZ_IPI void rz_core_analysis_value_pointers (RzCore *core, RzOutputMode mode)
 
RZ_API int rz_core_get_stacksz (RzCore *core, ut64 from, ut64 to)
 
RZ_API void rz_core_analysis_type_init (RzCore *core)
 
static void sdb_concat_by_path (Sdb *s, const char *path)
 
RZ_API void rz_core_analysis_cc_init (RzCore *core)
 
RZ_IPI void rz_core_analysis_cc_print (RzCore *core, RZ_NONNULL const char *cc, RZ_NULLABLE PJ *pj)
 Print Calling Convention info. More...
 
RZ_API bool rz_core_analysis_esil_trace_start (RzCore *core)
 Start ESIL trace session. More...
 
RZ_API bool rz_core_analysis_esil_trace_stop (RzCore *core)
 Stop ESIL trace session. More...
 
RZ_API void rz_analysis_bytes_free (RZ_NULLABLE void *ptr)
 
RZ_API RZ_OWN RzPVectorrz_core_analysis_bytes (RZ_NONNULL RzCore *core, RZ_NONNULL const ut8 *buf, int len, int nops)
 
RZ_API bool rz_core_analysis_hint_set_offset (RZ_NONNULL RzCore *core, RZ_NONNULL const char *struct_member)
 Set analysis hint for the first immediate of the instruction at current offset to struct_member. More...
 
RZ_API bool rz_core_analysis_continue_until_syscall (RZ_NONNULL RzCore *core)
 Continue until syscall. More...
 
RZ_API bool rz_core_analysis_continue_until_call (RZ_NONNULL RzCore *core)
 Continue until call. More...
 
RZ_API st64 rz_core_analysis_coverage_count (RZ_NONNULL RzCore *core)
 Compute analysis coverage count. More...
 
RZ_API st64 rz_core_analysis_code_count (RZ_NONNULL RzCore *core)
 Compute analysis code count. More...
 
RZ_API st64 rz_core_analysis_calls_count (RZ_NONNULL RzCore *core)
 Compute analysis function xrefs count. More...
 
RZ_API RZ_BORROW const char * rz_core_analysis_name_type_to_str (RzCoreAnalysisNameType typ)
 Convert typ to string (const char*) More...
 
RZ_API void rz_core_analysis_name_free (RZ_NULLABLE RzCoreAnalysisName *p)
 
RZ_API bool rz_core_analysis_rename (RZ_NONNULL RzCore *core, RZ_NONNULL const char *name, ut64 addr)
 Rename whatever var/flag/function is used at addr to name. More...
 
RZ_API RZ_OWN RzCoreAnalysisName * rz_core_analysis_name (RZ_NONNULL RzCore *core, ut64 addr)
 Get information on whatever var/flag/function is used at addr. More...
 

Variables

static bool esil_analysis_stop = false
 
static ut64 esilbreak_last_read = UT64_MAX
 
static ut64 esilbreak_last_data = UT64_MAX
 
static ut64 ntarget = UT64_MAX
 
static const char * RzCoreAnalysisNameTypeStrs []
 

Macro Definition Documentation

◆ CALL_BUF_SIZE

#define CALL_BUF_SIZE   32

Definition at line 5554 of file canalysis.c.

◆ CHECKREF

#define CHECKREF (   x)    ((refptr && (x) == refptr) || !refptr)

◆ END_ADDR

#define END_ADDR
Value:
if (pj) { \
pj_end(pj); \
} else if (state->mode == RZ_OUTPUT_MODE_STANDARD) { \
rz_cons_newline(); \
}
@ RZ_OUTPUT_MODE_STANDARD
Definition: rz_types.h:39
Definition: dis.h:43

◆ HINTCMD_ADDR

#define HINTCMD_ADDR (   hint,
  fmt,
  x 
)    rz_cons_printf(fmt " @ 0x%" PFMT64x "\n", x, (hint)->addr)

◆ MAX_SCAN_SIZE

#define MAX_SCAN_SIZE   0x7ffffff

Definition at line 28 of file canalysis.c.

◆ MINLEN

#define MINLEN   1

Definition at line 65 of file canalysis.c.

◆ OPSZ

#define OPSZ   8

Definition at line 3070 of file canalysis.c.

◆ REG_SET_SIZE

#define REG_SET_SIZE   (RZ_ANALYSIS_CC_MAXARG + 2)

Definition at line 2701 of file canalysis.c.

◆ USE_ID

#define USE_ID   1

Definition at line 2192 of file canalysis.c.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum
Enumerator
RZ_ARCH_THUMB 
RZ_ARCH_ARM32 
RZ_ARCH_ARM64 
RZ_ARCH_MIPS 

Definition at line 21 of file canalysis.c.

21  {
26 };
@ RZ_ARCH_MIPS
Definition: canalysis.c:25
@ RZ_ARCH_THUMB
Definition: canalysis.c:22
@ RZ_ARCH_ARM32
Definition: canalysis.c:23
@ RZ_ARCH_ARM64
Definition: canalysis.c:24

Function Documentation

◆ __core_analysis_fcn()

static int __core_analysis_fcn ( RzCore core,
ut64  at,
ut64  from,
int  reftype,
int  depth 
)
static

Definition at line 813 of file canalysis.c.

813  {
814  if (depth < 0) {
815  // printf ("Too deep for 0x%08"PFMT64x"\n", at);
816  // rz_sys_backtrace ();
817  return false;
818  }
819  int has_next = rz_config_get_i(core->config, "analysis.hasnext");
820  RzAnalysisHint *hint = NULL;
821  int i, nexti = 0;
822  ut64 *next = NULL;
823  int fcnlen;
825  const char *fcnpfx = rz_config_get(core->config, "analysis.fcnprefix");
826  if (!fcnpfx) {
827  fcnpfx = "fcn";
828  }
829  if (!fcn) {
830  eprintf("Error: new (fcn)\n");
831  return false;
832  }
834  rz_warn_if_fail(!core->analysis->sdb_cc->path || fcn->cc);
835  hint = rz_analysis_hint_get(core->analysis, at);
836  if (hint && hint->bits == 16) {
837  // expand 16bit for function
838  fcn->bits = 16;
839  } else {
840  fcn->bits = core->analysis->bits;
841  }
842  fcn->addr = at;
843  fcn->name = getFunctionName(core, at);
844 
845  if (!fcn->name) {
846  fcn->name = rz_str_newf("%s.%08" PFMT64x, fcnpfx, at);
847  }
849  do {
850  RzFlagItem *f;
852  if (!rz_io_is_valid_offset(core->io, at + delta, !core->analysis->opt.noncode)) {
853  goto error;
854  }
855  if (rz_cons_is_breaked()) {
856  break;
857  }
858  fcnlen = rz_analysis_fcn(core->analysis, fcn, at + delta, core->analysis->opt.bb_max_size, reftype);
859  if (core->analysis->opt.searchstringrefs) {
860  rz_analysis_set_stringrefs(core, fcn);
861  }
862  if (fcnlen == 0) {
863  RZ_LOG_DEBUG("Analyzed function has size of 0 at 0x%08" PFMT64x "\n", at + delta);
864  goto error;
865  }
866  if (fcnlen < 0) {
867  switch (fcnlen) {
869  case RZ_ANALYSIS_RET_END:
870  break;
873  continue;
874  default:
875  RZ_LOG_ERROR("Found negative function size at 0x%08" PFMT64x " (%d)\n", at, fcnlen);
876  continue;
877  }
878  }
879  f = rz_core_flag_get_by_spaces(core->flags, fcn->addr);
880  set_fcn_name_from_flag(fcn, f, fcnpfx);
881 
882  if (fcnlen == RZ_ANALYSIS_RET_ERROR ||
883  (fcnlen == RZ_ANALYSIS_RET_END && !rz_analysis_function_realsize(fcn))) { /* Error analyzing function */
884  if (core->analysis->opt.followbrokenfcnsrefs) {
885  rz_analysis_analyze_fcn_refs(core, fcn, depth);
886  }
887  goto error;
888  } else if (fcnlen == RZ_ANALYSIS_RET_END) { /* Function analysis complete */
889  f = rz_core_flag_get_by_spaces(core->flags, fcn->addr);
890  if (f && f->name && strncmp(f->name, "sect", 4)) { /* Check if it's already flagged */
891  char *new_name = strdup(f->name);
892  if (is_entry_flag(f)) {
893  RzListIter *iter;
894  RzBinSymbol *sym;
895  const RzList *syms = rz_bin_get_symbols(core->bin);
896  ut64 baddr = rz_config_get_i(core->config, "bin.baddr");
897  rz_list_foreach (syms, iter, sym) {
898  if ((sym->paddr + baddr) == fcn->addr && !strcmp(sym->type, RZ_BIN_TYPE_FUNC_STR)) {
899  free(new_name);
900  new_name = rz_str_newf("sym.%s", sym->name);
901  break;
902  }
903  }
904  }
905  free(fcn->name);
906  fcn->name = new_name;
907  } else {
908  RZ_FREE(fcn->name);
909  const char *fcnpfx = rz_analysis_fcntype_tostring(fcn->type);
910  if (!fcnpfx || !*fcnpfx || !strcmp(fcnpfx, "fcn")) {
911  fcnpfx = rz_config_get(core->config, "analysis.fcnprefix");
912  }
913  fcn->name = rz_str_newf("%s.%08" PFMT64x, fcnpfx, fcn->addr);
914  autoname_imp_trampoline(core, fcn);
915  /* Add flag */
916  rz_flag_space_push(core->flags, RZ_FLAGS_FS_FUNCTIONS);
918  rz_flag_space_pop(core->flags);
919  }
920 
921  /* New function: Add initial xref */
922  if (from != UT64_MAX) {
924  }
925  // XXX: this is wrong. See CID 1134565
927  if (has_next) {
929  RzIOMap *map = rz_io_map_get(core->io, addr);
930  // only get next if found on an executable section
931  if (!map || (map && map->perm & RZ_PERM_X)) {
932  for (i = 0; i < nexti; i++) {
933  if (next[i] == addr) {
934  break;
935  }
936  }
937  if (i == nexti) {
939  while (true) {
940  ut64 size;
942  if (!mi) {
943  break;
944  }
945  at += size;
946  }
947  // TODO: ensure next address is function after padding (nop or trap or wat)
948  // XXX noisy for test cases because we want to clear the stderr
950  loganalysis(fcn->addr, at, 10000 - depth);
951  next = next_append(next, &nexti, at);
952  }
953  }
954  }
955  if (!rz_analysis_analyze_fcn_refs(core, fcn, depth)) {
956  goto error;
957  }
958  }
959  } while (fcnlen != RZ_ANALYSIS_RET_END);
960  rz_list_free(core->analysis->leaddrs);
961  core->analysis->leaddrs = NULL;
962  if (has_next) {
963  for (i = 0; i < nexti; i++) {
964  if (!next[i] || rz_analysis_get_fcn_in(core->analysis, next[i], 0)) {
965  continue;
966  }
967  rz_core_analysis_fcn(core, next[i], from, 0, depth - 1);
968  }
969  free(next);
970  }
971  if (core->analysis->cur && core->analysis->cur->arch && !strcmp(core->analysis->cur->arch, "x86")) {
973  if (fcn && !fcn->bp_frame) {
975  }
976  }
977  rz_analysis_hint_free(hint);
978  return true;
979 
980 error:
981  rz_list_free(core->analysis->leaddrs);
982  core->analysis->leaddrs = NULL;
983  // ugly hack to free fcn
984  if (fcn) {
985  if (!rz_analysis_function_realsize(fcn) || fcn->addr == UT64_MAX) {
987  fcn = NULL;
988  } else {
989  // TODO: mark this function as not properly analyzed
990  if (!fcn->name) {
991  // XXX dupped code.
992  fcn->name = rz_str_newf(
993  "%s.%08" PFMT64x,
995  at);
996  /* Add flag */
997  rz_flag_space_push(core->flags, RZ_FLAGS_FS_FUNCTIONS);
999  rz_flag_space_pop(core->flags);
1000  }
1001  rz_analysis_add_function(core->analysis, fcn);
1002  }
1003  if (fcn && has_next) {
1004  ut64 newaddr = rz_analysis_function_max_addr(fcn);
1005  RzIOMap *map = rz_io_map_get(core->io, newaddr);
1006  if (!map || (map && (map->perm & RZ_PERM_X))) {
1007  next = next_append(next, &nexti, newaddr);
1008  for (i = 0; i < nexti; i++) {
1009  if (!next[i]) {
1010  continue;
1011  }
1012  rz_core_analysis_fcn(core, next[i], next[i], 0, depth - 1);
1013  }
1014  free(next);
1015  }
1016  }
1017  }
1018  if (fcn && core->analysis->cur && core->analysis->cur->arch && !strcmp(core->analysis->cur->arch, "x86")) {
1020  if (!fcn->bp_frame) {
1022  }
1023  }
1024  rz_analysis_hint_free(hint);
1025  return false;
1026 }
RZ_API ut64 rz_analysis_function_max_addr(RzAnalysisFunction *fcn)
Definition: function.c:328
RZ_API ut64 rz_analysis_function_linear_size(RzAnalysisFunction *fcn)
Definition: function.c:318
RZ_API ut64 rz_analysis_function_realsize(const RzAnalysisFunction *fcn)
Definition: function.c:338
RZ_API bool rz_analysis_add_function(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: function.c:129
RZ_API RzAnalysisFunction * rz_analysis_function_new(RzAnalysis *analysis)
Definition: function.c:70
RZ_API void rz_analysis_function_free(void *_fcn)
Definition: function.c:92
lzma_index ** i
Definition: index.h:629
RZ_DEPRECATE RZ_API RZ_BORROW RzList * rz_bin_get_symbols(RZ_NONNULL RzBin *bin)
Definition: bin.c:696
static ut64 baddr(RzBinFile *bf)
Definition: bin_any.c:58
static char * getFunctionName(RzCore *core, ut64 addr)
Definition: canalysis.c:45
static int rz_analysis_analyze_fcn_refs(RzCore *core, RzAnalysisFunction *fcn, int depth)
Definition: canalysis.c:726
static void set_fcn_name_from_flag(RzAnalysisFunction *fcn, RzFlagItem *f, const char *fcnpfx)
Definition: canalysis.c:793
static void autoname_imp_trampoline(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:776
RZ_API int rz_core_analysis_fcn(RzCore *core, ut64 at, ut64 from, int reftype, int depth)
Definition: canalysis.c:2026
static void rz_analysis_set_stringrefs(RzCore *core, RzAnalysisFunction *fcn)
Definition: canalysis.c:647
static bool is_entry_flag(RzFlagItem *f)
Definition: canalysis.c:809
static void loganalysis(ut64 from, ut64 to, int depth)
Definition: canalysis.c:30
static ut64 * next_append(ut64 *next, int *nexti, ut64 v)
Definition: canalysis.c:636
RZ_API const char * rz_analysis_cc_default(RzAnalysis *analysis)
Definition: cc.c:200
RZ_API ut64 rz_config_get_i(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:119
RZ_API RZ_BORROW const char * rz_config_get(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:75
RZ_API void rz_cons_clear_line(int std_err)
Definition: cons.c:756
RZ_API bool rz_cons_is_breaked(void)
Definition: cons.c:373
#define NULL
Definition: cris-opc.c:27
size_t map(int syms, int left, int len)
Definition: enough.c:237
RZ_API void rz_analysis_fcn_invalidate_read_ahead_cache(void)
Definition: fcn.c:84
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1687
RZ_API const char * rz_analysis_fcntype_tostring(int type)
Definition: fcn.c:35
RZ_API int rz_analysis_fcn(RzAnalysis *analysis, RzAnalysisFunction *fcn, ut64 addr, ut64 len, int reftype)
Definition: fcn.c:1606
RZ_API void rz_analysis_function_check_bp_use(RzAnalysisFunction *fcn)
Definition: fcn.c:2241
RZ_API RzFlagItem * rz_flag_set(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:521
RZ_API RzAnalysisHint * rz_analysis_hint_get(RzAnalysis *a, ut64 addr)
Definition: hint.c:506
RZ_API void rz_analysis_hint_free(RzAnalysisHint *h)
Definition: hint.c:371
RZ_API void Ht_() free(HtName_(Ht) *ht)
Definition: ht_inc.c:130
voidpf void uLong size
Definition: ioapi.h:138
RZ_API RzFlagItem * rz_core_flag_get_by_spaces(RzFlag *f, ut64 off)
Definition: core.c:2280
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
Definition: list.c:137
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 RzAnalysisMetaItem * rz_meta_get_at(RzAnalysis *a, ut64 addr, RzAnalysisMetaType type, RZ_OUT RZ_NULLABLE ut64 *size)
Definition: meta.c:207
#define eprintf(x, y...)
Definition: rlcc.c:7
@ RZ_ANALYSIS_RET_BRANCH
Definition: rz_analysis.h:476
@ RZ_ANALYSIS_RET_COND
Definition: rz_analysis.h:477
@ RZ_ANALYSIS_RET_ERROR
Definition: rz_analysis.h:474
@ RZ_ANALYSIS_RET_END
Definition: rz_analysis.h:475
@ RZ_META_TYPE_ANY
Definition: rz_analysis.h:288
@ RZ_ANALYSIS_VAR_KIND_BPV
Definition: rz_analysis.h:704
#define rz_warn_if_fail(expr)
Definition: rz_assert.h:35
#define RZ_BIN_TYPE_FUNC_STR
Definition: rz_bin.h:119
#define RZ_FLAGS_FS_FUNCTIONS
Definition: rz_core.h:58
RZ_API RzIOMap * rz_io_map_get(RzIO *io, ut64 addr)
Definition: io_map.c:176
RZ_API bool rz_io_is_valid_offset(RzIO *io, ut64 offset, int hasperm)
Definition: ioutils.c:20
#define RZ_LOG_DEBUG(fmtstr,...)
Definition: rz_log.h:49
#define RZ_LOG_ERROR(fmtstr,...)
Definition: rz_log.h:58
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API const char * rz_str_constpool_get(RzStrConstPool *pool, const char *str)
Definition: str_constpool.c:19
#define RZ_PERM_X
Definition: rz_types.h:95
#define RZ_FREE(x)
Definition: rz_types.h:369
#define PFMT64x
Definition: rz_types.h:393
#define UT64_MAX
Definition: rz_types_base.h:86
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr from
Definition: sfsocketcall.h:123
#define f(i)
Definition: sha256.c:46
RzStrConstPool constpool
Definition: rz_analysis.h:620
RzList * leaddrs
Definition: rz_analysis.h:621
struct rz_analysis_plugin_t * cur
Definition: rz_analysis.h:586
RzAnalysisOptions opt
Definition: rz_analysis.h:608
const char * type
Definition: rz_bin.h:682
char * name
Definition: rz_bin.h:675
RzBin * bin
Definition: rz_core.h:298
RzAnalysis * analysis
Definition: rz_core.h:322
RzIO * io
Definition: rz_core.h:313
RzFlag * flags
Definition: rz_core.h:330
RzConfig * config
Definition: rz_core.h:300
char * path
Definition: sdb.h:65
void error(const char *msg)
Definition: untgz.c:593
RZ_API void rz_analysis_function_delete_vars_by_kind(RzAnalysisFunction *fcn, RzAnalysisVarKind kind)
Definition: var.c:206
static st64 delta
Definition: vmenus.c:2425
ut64(WINAPI *w32_GetEnabledXStateFeatures)()
RZ_API bool rz_analysis_xrefs_set(RzAnalysis *analysis, ut64 from, ut64 to, RzAnalysisXRefType type)
Definition: xrefs.c:117
static int addr
Definition: z80asm.c:58
reftype
Definition: z80asm.h:66

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, rz_analysis_plugin_t::arch, autoname_imp_trampoline(), baddr(), rz_analysis_options_t::bb_max_size, rz_core_t::bin, rz_analysis_function_t::bits, rz_analysis_t::bits, rz_analysis_hint_t::bits, rz_analysis_function_t::bp_frame, rz_analysis_function_t::cc, rz_core_t::config, rz_analysis_t::constpool, rz_analysis_t::cur, delta, eprintf, error(), f, rz_core_t::flags, rz_analysis_options_t::followbrokenfcnsrefs, free(), from, getFunctionName(), i, rz_core_t::io, is_entry_flag(), rz_analysis_t::leaddrs, loganalysis(), map(), mi, rz_analysis_function_t::name, rz_bin_symbol_t::name, next_append(), rz_analysis_options_t::noncode, NULL, rz_analysis_t::opt, rz_bin_symbol_t::paddr, sdb_t::path, PFMT64x, rz_analysis_add_function(), rz_analysis_analyze_fcn_refs(), rz_analysis_cc_default(), rz_analysis_fcn(), rz_analysis_fcn_invalidate_read_ahead_cache(), rz_analysis_fcntype_tostring(), rz_analysis_function_check_bp_use(), rz_analysis_function_delete_vars_by_kind(), rz_analysis_function_free(), rz_analysis_function_linear_size(), rz_analysis_function_max_addr(), rz_analysis_function_new(), rz_analysis_function_realsize(), rz_analysis_get_fcn_in(), rz_analysis_hint_free(), rz_analysis_hint_get(), RZ_ANALYSIS_RET_BRANCH, RZ_ANALYSIS_RET_COND, RZ_ANALYSIS_RET_END, RZ_ANALYSIS_RET_ERROR, rz_analysis_set_stringrefs(), RZ_ANALYSIS_VAR_KIND_BPV, rz_analysis_xrefs_set(), rz_bin_get_symbols(), RZ_BIN_TYPE_FUNC_STR, rz_config_get(), rz_config_get_i(), rz_cons_clear_line(), rz_cons_is_breaked(), rz_core_analysis_fcn(), rz_core_flag_get_by_spaces(), rz_flag_set(), RZ_FLAGS_FS_FUNCTIONS, RZ_FREE, rz_io_is_valid_offset(), rz_io_map_get(), rz_list_free(), RZ_LOG_DEBUG, RZ_LOG_ERROR, rz_meta_get_at(), RZ_META_TYPE_ANY, RZ_PERM_X, rz_str_constpool_get(), rz_str_newf(), rz_warn_if_fail, rz_analysis_t::sdb_cc, rz_analysis_options_t::searchstringrefs, set_fcn_name_from_flag(), strdup(), rz_analysis_function_t::type, rz_bin_symbol_t::type, ut64(), and UT64_MAX.

Referenced by rz_core_analysis_fcn().

◆ __opaddr()

static ut64 __opaddr ( RzAnalysisBlock b,
ut64  addr 
)
static

Definition at line 349 of file canalysis.c.

349  {
350  int i;
351  if (addr >= b->addr && addr < (b->addr + b->size)) {
352  for (i = 0; i < b->ninstr; i++) {
355  if (addr >= aa && addr < ab) {
356  return aa;
357  }
358  }
359  }
360  return UT64_MAX;
361 }
RZ_API ut64 rz_analysis_block_get_op_addr(RzAnalysisBlock *block, size_t i)
Definition: block.c:1016
#define b(i)
Definition: sha256.c:42

References addr, b, i, rz_analysis_block_get_op_addr(), ut64(), and UT64_MAX.

Referenced by bb_info_print().

◆ _CbInRangeAav()

static void _CbInRangeAav ( RzCore core,
ut64  from,
ut64  to,
int  vsize,
void *  user 
)
static

Definition at line 6461 of file canalysis.c.

6461  {
6462  bool pretend = (user && *(RzOutputMode *)user == RZ_OUTPUT_MODE_RIZIN);
6463  int arch_align = rz_analysis_archinfo(core->analysis, RZ_ANALYSIS_ARCHINFO_ALIGN);
6464  bool vinfun = rz_config_get_b(core->config, "analysis.vinfun");
6465  int searchAlign = rz_config_get_i(core->config, "search.align");
6466  int align = (searchAlign > 0) ? searchAlign : arch_align;
6467  if (align > 1) {
6468  if ((from % align) || (to % align)) {
6469  bool itsFine = false;
6470  if (archIsThumbable(core)) {
6471  if ((from & 1) || (to & 1)) {
6472  itsFine = true;
6473  }
6474  }
6475  if (!itsFine) {
6476  return;
6477  }
6478  RZ_LOG_DEBUG("Warning: aav: false positive in 0x%08" PFMT64x "\n", from);
6479  }
6480  }
6481  if (!vinfun) {
6483  if (fcn) {
6484  return;
6485  }
6486  }
6487  if (pretend) {
6488  rz_cons_printf("ax 0x%" PFMT64x " @ 0x%" PFMT64x "\n", to, from);
6489  rz_cons_printf("Cd %d @ 0x%" PFMT64x "\n", vsize, from);
6490  rz_cons_printf("f+ aav.0x%08" PFMT64x "= 0x%08" PFMT64x, to, to);
6491  } else {
6493  rz_meta_set(core->analysis, RZ_META_TYPE_DATA, from, vsize, NULL);
6494  if (!rz_flag_get_at(core->flags, to, false)) {
6495  char *name = rz_str_newf("aav.0x%08" PFMT64x, to);
6496  rz_flag_set(core->flags, name, to, vsize);
6497  free(name);
6498  }
6499  }
6500 }
RZ_API int rz_analysis_archinfo(RzAnalysis *analysis, int query)
Definition: analysis.c:449
static bool archIsThumbable(RzCore *core)
Definition: canalysis.c:6453
RZ_API bool rz_config_get_b(RzConfig *cfg, RZ_NONNULL const char *name)
Definition: config.c:142
RZ_API int rz_cons_printf(const char *format,...)
Definition: cons.c:1202
RZ_API RzFlagItem * rz_flag_get_at(RzFlag *f, ut64 off, bool closest)
Definition: flag.c:404
RZ_API bool rz_meta_set(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr, ut64 size, const char *str)
Definition: meta.c:191
#define RZ_ANALYSIS_ARCHINFO_ALIGN
Definition: rz_analysis.h:100
@ RZ_ANALYSIS_XREF_TYPE_NULL
Definition: rz_analysis.h:899
@ RZ_META_TYPE_DATA
Definition: rz_analysis.h:289
RzOutputMode
Enum to describe the way data are printed.
Definition: rz_types.h:38
@ RZ_OUTPUT_MODE_RIZIN
Definition: rz_types.h:41
static struct sockaddr static addrlen static backlog const void static flags void struct sockaddr socklen_t static fromlen const void const struct sockaddr to
Definition: sfsocketcall.h:125
Definition: z80asm.h:102

References rz_core_t::analysis, archIsThumbable(), rz_core_t::config, core_noretl::core, rz_core_t::flags, free(), from, NULL, PFMT64x, rz_analysis_archinfo(), RZ_ANALYSIS_ARCHINFO_ALIGN, rz_analysis_get_fcn_in(), RZ_ANALYSIS_XREF_TYPE_NULL, rz_analysis_xrefs_set(), rz_config_get_b(), rz_config_get_i(), rz_cons_printf(), rz_flag_get_at(), rz_flag_set(), RZ_LOG_DEBUG, rz_meta_set(), RZ_META_TYPE_DATA, RZ_OUTPUT_MODE_RIZIN, rz_str_newf(), and to.

Referenced by rz_core_analysis_value_pointers().

◆ add_arch_platform_flag_comment_cb()

static bool add_arch_platform_flag_comment_cb ( void *  user,
const ut64  addr,
const void *  v 
)
static

Definition at line 5243 of file canalysis.c.

5243  {
5244  if (!v) {
5245  return false;
5246  }
5247  RzPlatformItem *item = (RzPlatformItem *)v;
5248  RzCore *core = (RzCore *)user;
5249  rz_flag_space_push(core->flags, RZ_FLAGS_FS_PLATFORM_PORTS);
5250  rz_flag_set(core->flags, item->name, addr, 1);
5251  rz_flag_space_pop(core->flags);
5252  if (item->comment) {
5253  rz_core_meta_comment_add(core, item->comment, addr);
5254  }
5255  return true;
5256 }
RZ_IPI void rz_core_meta_comment_add(RzCore *core, const char *comment, ut64 addr)
Definition: cmd_meta.c:17
const char * v
Definition: dsignal.c:12
#define RZ_FLAGS_FS_PLATFORM_PORTS
Definition: rz_core.h:72

References addr, rz_platform_item_t::comment, rz_core_t::flags, rz_platform_item_t::name, rz_core_meta_comment_add(), rz_flag_set(), RZ_FLAGS_FS_PLATFORM_PORTS, and v.

Referenced by rz_platform_index_add_flags_comments().

◆ add_mmio_extended_flag_cb()

static bool add_mmio_extended_flag_cb ( void *  user,
const ut64  addr,
const void *  v 
)
static

Definition at line 5222 of file canalysis.c.

5222  {
5223  const char *name = v;
5224  RzFlag *flags = (RzFlag *)user;
5225  rz_flag_space_push(flags, RZ_FLAGS_FS_MMIO_REGISTERS_EXTENDED);
5226  rz_flag_set(flags, name, addr, 1);
5227  rz_flag_space_pop(flags);
5228  return true;
5229 }
#define RZ_FLAGS_FS_MMIO_REGISTERS_EXTENDED
Definition: rz_core.h:71
static struct sockaddr static addrlen static backlog const void static flags void flags
Definition: sfsocketcall.h:123

References addr, flags, rz_flag_set(), RZ_FLAGS_FS_MMIO_REGISTERS_EXTENDED, and v.

Referenced by rz_platform_profile_add_flag_every_io().

◆ add_mmio_flag_cb()

static bool add_mmio_flag_cb ( void *  user,
const ut64  addr,
const void *  v 
)
static

Definition at line 5213 of file canalysis.c.

5213  {
5214  const char *name = v;
5215  RzFlag *flags = (RzFlag *)user;
5216  rz_flag_space_push(flags, RZ_FLAGS_FS_MMIO_REGISTERS);
5217  rz_flag_set(flags, name, addr, 1);
5218  rz_flag_space_pop(flags);
5219  return true;
5220 }
#define RZ_FLAGS_FS_MMIO_REGISTERS
Definition: rz_core.h:70

References addr, flags, rz_flag_set(), RZ_FLAGS_FS_MMIO_REGISTERS, and v.

Referenced by rz_platform_profile_add_flag_every_io().

◆ add_single_addr_xrefs()

static void add_single_addr_xrefs ( RzCore core,
ut64  addr,
RzGraph graph 
)
static

Definition at line 2362 of file canalysis.c.

2362  {
2363  rz_return_if_fail(graph);
2364  RzFlagItem *f = rz_flag_get_at(core->flags, addr, false);
2365  char *me = (f && f->offset == addr)
2366  ? rz_str_new(f->name)
2367  : rz_str_newf("0x%" PFMT64x, addr);
2368 
2369  RzGraphNode *curr_node = rz_graph_add_node_info(graph, me, NULL, addr);
2370  RZ_FREE(me);
2371  if (!curr_node) {
2372  return;
2373  }
2374  RzListIter *iter;
2375  RzAnalysisXRef *xref;
2377  rz_list_foreach (list, iter, xref) {
2378  RzFlagItem *item = rz_flag_get_i(core->flags, xref->from);
2379  char *src = item ? rz_str_new(item->name) : rz_str_newf("0x%08" PFMT64x, xref->from);
2380  RzGraphNode *reference_from = rz_graph_add_node_info(graph, src, NULL, xref->from);
2381  free(src);
2382  rz_graph_add_edge(graph, reference_from, curr_node);
2383  }
2384  rz_list_free(list);
2385 }
lzma_index * src
Definition: index.h:567
RZ_API RzFlagItem * rz_flag_get_i(RzFlag *f, ut64 off)
Definition: flag.c:317
static void list(RzEgg *egg)
Definition: rz-gg.c:52
#define rz_return_if_fail(expr)
Definition: rz_assert.h:100
RZ_API void rz_graph_add_edge(RzGraph *g, RzGraphNode *from, RzGraphNode *to)
Definition: graph.c:199
RZ_API RzGraphNode * rz_graph_add_node_info(RzGraph *graph, const char *title, const char *body, ut64 offset)
RZ_API char * rz_str_new(const char *str)
Definition: str.c:865
char * name
Definition: rz_flag.h:35
RZ_API RzList * rz_analysis_xrefs_get_to(RzAnalysis *analysis, ut64 addr)
Definition: xrefs.c:173

References addr, rz_core_t::analysis, f, rz_core_t::flags, free(), rz_analysis_ref_t::from, list(), rz_flag_item_t::name, NULL, PFMT64x, rz_analysis_xrefs_get_to(), rz_flag_get_at(), rz_flag_get_i(), RZ_FREE, rz_graph_add_edge(), rz_graph_add_node_info(), rz_list_free(), rz_return_if_fail, rz_str_new(), rz_str_newf(), and src.

Referenced by rz_core_analysis_codexrefs(), and rz_core_analysis_importxrefs().

◆ add_string_ref()

static void add_string_ref ( RzCore core,
ut64  xref_from,
ut64  xref_to 
)
static

Definition at line 4102 of file canalysis.c.

4102  {
4103  int len = 0;
4104  if (xref_to == UT64_MAX || !xref_to) {
4105  return;
4106  }
4107  if (!xref_from || xref_from == UT64_MAX) {
4108  xref_from = core->analysis->esil->address;
4109  }
4110  char *str_flagname = is_string_at(core, xref_to, &len);
4111  if (str_flagname) {
4112  rz_analysis_xrefs_set(core->analysis, xref_from, xref_to, RZ_ANALYSIS_XREF_TYPE_DATA);
4113  rz_name_filter(str_flagname, -1, true);
4114  char *flagname = sdb_fmt("str.%s", str_flagname);
4115  rz_flag_space_push(core->flags, RZ_FLAGS_FS_STRINGS);
4116  rz_flag_set(core->flags, flagname, xref_to, len);
4117  rz_flag_space_pop(core->flags);
4118  rz_meta_set(core->analysis, 's', xref_to, len, str_flagname);
4119  free(str_flagname);
4120  }
4121 }
size_t len
Definition: 6502dis.c:15
static char * is_string_at(RzCore *core, ut64 addr, int *olen)
Definition: canalysis.c:99
RZ_API char * sdb_fmt(const char *fmt,...)
Definition: fmt.c:26
@ RZ_ANALYSIS_XREF_TYPE_DATA
Definition: rz_analysis.h:902
#define RZ_FLAGS_FS_STRINGS
Definition: rz_core.h:66
RZ_API bool rz_name_filter(char *name, int len, bool strict)
Definition: name.c:43
struct rz_analysis_esil_t * esil
Definition: rz_analysis.h:584

References rz_analysis_esil_t::address, rz_core_t::analysis, rz_analysis_t::esil, rz_core_t::flags, free(), is_string_at(), len, RZ_ANALYSIS_XREF_TYPE_DATA, rz_analysis_xrefs_set(), rz_flag_set(), RZ_FLAGS_FS_STRINGS, rz_meta_set(), rz_name_filter(), sdb_fmt(), and UT64_MAX.

Referenced by esilbreak_mem_read(), esilbreak_reg_write(), rz_core_analysis_esil(), and rz_core_search_value_in_range().

◆ analPathFollow()

static void analPathFollow ( RzCoreAnalPaths p,
ut64  addr,
PJ pj 
)
static

Definition at line 5063 of file canalysis.c.

5063  {
5064  if (addr == UT64_MAX) {
5065  return;
5066  }
5067  bool found;
5068  ht_uu_find(p->visited, addr, &found);
5069  if (!found) {
5070  p->cur = rz_analysis_find_most_relevant_block_in(p->core->analysis, addr);
5071  analPaths(p, pj);
5072  }
5073 }
RZ_API RzAnalysisBlock * rz_analysis_find_most_relevant_block_in(RzAnalysis *analysis, ut64 off)
Definition: block.c:997
static void analPaths(RzCoreAnalPaths *p, PJ *pj)
Definition: canalysis.c:5075
RZ_API const KEY_TYPE bool * found
Definition: ht_inc.h:130
void * p
Definition: libc.cpp:67

References addr, analPaths(), found, p, rz_analysis_find_most_relevant_block_in(), and UT64_MAX.

Referenced by analPaths().

◆ analPaths()

static void analPaths ( RzCoreAnalPaths p,
PJ pj 
)
static

Definition at line 5075 of file canalysis.c.

5075  {
5076  RzAnalysisBlock *cur = p->cur;
5077  if (!cur) {
5078  // eprintf ("eof\n");
5079  return;
5080  }
5081  /* handle ^C */
5082  if (rz_cons_is_breaked()) {
5083  return;
5084  }
5085  ht_uu_insert(p->visited, cur->addr, 1);
5086  rz_list_append(p->path, cur);
5087  if (p->followDepth && --p->followDepth == 0) {
5088  return;
5089  }
5090  if (p->toBB && cur->addr == p->toBB->addr) {
5091  if (!printAnalPaths(p, pj)) {
5092  return;
5093  }
5094  } else {
5095  RzAnalysisBlock *c = cur;
5096  ut64 j = cur->jump;
5097  ut64 f = cur->fail;
5098  analPathFollow(p, j, pj);
5099  cur = c;
5100  analPathFollow(p, f, pj);
5101  if (p->followCalls) {
5102  int i;
5103  for (i = 0; i < cur->op_pos_size; i++) {
5104  ut64 addr = cur->addr + cur->op_pos[i];
5106  if (op && op->type == RZ_ANALYSIS_OP_TYPE_CALL) {
5107  analPathFollow(p, op->jump, pj);
5108  }
5109  cur = c;
5111  }
5112  }
5113  }
5114  p->cur = rz_list_pop(p->path);
5115  ht_uu_delete(p->visited, cur->addr);
5116  if (p->followDepth) {
5117  p->followDepth++;
5118  }
5119 }
static void analPathFollow(RzCoreAnalPaths *p, ut64 addr, PJ *pj)
Definition: canalysis.c:5063
RZ_API RzAnalysisOp * rz_core_analysis_op(RzCore *core, ut64 addr, int mask)
Definition: canalysis.c:1033
static bool printAnalPaths(RzCoreAnalPaths *p, PJ *pj)
Definition: canalysis.c:5037
RZ_API RZ_OWN void * rz_list_pop(RZ_NONNULL RzList *list)
Removes and returns the last element of the list.
Definition: list.c:376
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
Definition: list.c:288
RZ_API void rz_analysis_op_free(void *op)
Definition: op.c:61
@ RZ_ANALYSIS_OP_MASK_BASIC
Definition: rz_analysis.h:440
@ RZ_ANALYSIS_OP_TYPE_CALL
Definition: rz_analysis.h:378
#define c(i)
Definition: sha256.c:43
Definition: dis.c:32

References addr, rz_analysis_bb_t::addr, analPathFollow(), c, f, rz_analysis_bb_t::fail, i, rz_analysis_bb_t::jump, rz_analysis_bb_t::op_pos, rz_analysis_bb_t::op_pos_size, p, printAnalPaths(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_TYPE_CALL, rz_cons_is_breaked(), rz_core_analysis_op(), rz_list_append(), rz_list_pop(), and ut64().

Referenced by analPathFollow(), and rz_core_analysis_paths().

◆ analysis_block_cb()

static bool analysis_block_cb ( RzAnalysisBlock bb,
BlockRecurseCtx ctx 
)
static

Definition at line 2724 of file canalysis.c.

2724  {
2725  if (rz_cons_is_breaked()) {
2726  return false;
2727  }
2728  if (bb->size < 1) {
2729  return true;
2730  }
2731  if (bb->size > ctx->core->analysis->opt.bb_max_size) {
2732  return true;
2733  }
2734  int *parent_reg_set = rz_pvector_at(&ctx->reg_set, rz_pvector_len(&ctx->reg_set) - 1);
2735  int *reg_set = RZ_NEWS(int, REG_SET_SIZE);
2736  memcpy(reg_set, parent_reg_set, REG_SET_SIZE * sizeof(int));
2737  rz_pvector_push(&ctx->reg_set, reg_set);
2738  RzCore *core = ctx->core;
2739  RzAnalysisFunction *fcn = ctx->fcn;
2740  fcn->stack = bb->parent_stackptr;
2741  ut64 pos = bb->addr;
2742  while (pos < bb->addr + bb->size) {
2743  if (rz_cons_is_breaked()) {
2744  break;
2745  }
2747  if (!op) {
2748  // eprintf ("Cannot get op\n");
2749  break;
2750  }
2751  rz_analysis_extract_rarg(core->analysis, op, fcn, reg_set, &ctx->count);
2752  if (!ctx->argonly) {
2753  if (op->stackop == RZ_ANALYSIS_STACK_INC) {
2754  fcn->stack += op->stackptr;
2755  } else if (op->stackop == RZ_ANALYSIS_STACK_RESET) {
2756  fcn->stack = 0;
2757  }
2758  rz_analysis_extract_vars(core->analysis, fcn, op);
2759  }
2760  int opsize = op->size;
2761  int optype = op->type;
2763  if (opsize < 1) {
2764  break;
2765  }
2767  size_t i;
2768  int max_count = fcn->cc ? rz_analysis_cc_max_arg(core->analysis, fcn->cc) : 0;
2769  for (i = 0; i < max_count; i++) {
2770  reg_set[i] = 2;
2771  }
2772  }
2773  pos += opsize;
2774  }
2775  return true;
2776 }
#define REG_SET_SIZE
Definition: canalysis.c:2701
RZ_API int rz_analysis_cc_max_arg(RzAnalysis *analysis, const char *cc)
Definition: cc.c:171
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
static size_t max_count
Definition: malloc.c:67
@ RZ_ANALYSIS_STACK_RESET
Definition: rz_analysis.h:460
@ RZ_ANALYSIS_STACK_INC
Definition: rz_analysis.h:457
@ RZ_ANALYSIS_OP_MASK_VAL
Definition: rz_analysis.h:442
@ RZ_ANALYSIS_OP_MASK_ESIL
Definition: rz_analysis.h:441
@ RZ_ANALYSIS_OP_MASK_HINT
Definition: rz_analysis.h:443
#define RZ_NEWS(x, y)
Definition: rz_types.h:283
static size_t rz_pvector_len(const RzPVector *vec)
Definition: rz_vector.h:231
static void ** rz_pvector_push(RzPVector *vec, void *x)
Definition: rz_vector.h:300
static void * rz_pvector_at(const RzPVector *vec, size_t index)
Definition: rz_vector.h:236
Definition: op.c:222
int pos
Definition: main.c:11
RZ_API void rz_analysis_extract_rarg(RzAnalysis *analysis, RzAnalysisOp *op, RzAnalysisFunction *fcn, int *reg_set, int *count)
Definition: var.c:909
RZ_API void rz_analysis_extract_vars(RzAnalysis *analysis, RzAnalysisFunction *fcn, RzAnalysisOp *op)
Definition: var.c:1103

References addr, rz_analysis_bb_t::addr, rz_core_t::analysis, rz_analysis_function_t::cc, i, max_count, memcpy(), rz_analysis_bb_t::parent_stackptr, pos, REG_SET_SIZE, rz_analysis_cc_max_arg(), rz_analysis_extract_rarg(), rz_analysis_extract_vars(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_MASK_VAL, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_STACK_INC, RZ_ANALYSIS_STACK_RESET, rz_cons_is_breaked(), rz_core_analysis_op(), RZ_NEWS, rz_pvector_at(), rz_pvector_len(), rz_pvector_push(), rz_analysis_bb_t::size, rz_analysis_function_t::stack, and ut64().

Referenced by rz_core_recover_vars().

◆ analysis_block_on_exit()

static bool analysis_block_on_exit ( RzAnalysisBlock bb,
BlockRecurseCtx ctx 
)
static

Definition at line 2711 of file canalysis.c.

2711  {
2712  int *cur_regset = rz_pvector_pop(&ctx->reg_set);
2713  int *prev_regset = rz_pvector_at(&ctx->reg_set, rz_pvector_len(&ctx->reg_set) - 1);
2714  size_t i;
2715  for (i = 0; i < REG_SET_SIZE; i++) {
2716  if (!prev_regset[i] && cur_regset[i] == 1) {
2717  prev_regset[i] = 1;
2718  }
2719  }
2720  free(cur_regset);
2721  return true;
2722 }
RZ_API void * rz_pvector_pop(RzPVector *vec)
Definition: vector.c:372

References free(), i, REG_SET_SIZE, rz_pvector_at(), rz_pvector_len(), and rz_pvector_pop().

Referenced by rz_core_recover_vars().

◆ analysis_graph_to()

static RzList* analysis_graph_to ( RzCore core,
ut64  addr,
int  depth,
HtUP *  avoid 
)
static

Definition at line 2851 of file canalysis.c.

2851  {
2852  RzAnalysisFunction *cur_fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
2853  RzList *list = rz_list_new();
2854  HtUP *state = ht_up_new0();
2855 
2856  if (!list || !state || !cur_fcn) {
2857  rz_list_free(list);
2858  ht_up_free(state);
2859  return NULL;
2860  }
2861 
2862  // forward search
2863  if (analysis_path_exists(core, core->offset, addr, list, depth - 1, state, avoid)) {
2864  ht_up_free(state);
2865  return list;
2866  }
2867 
2868  // backward search
2869  RzList *xrefs = rz_analysis_xrefs_get_to(core->analysis, cur_fcn->addr);
2870  if (xrefs) {
2871  RzListIter *iter;
2872  RzAnalysisXRef *xref = NULL;
2873  rz_list_foreach (xrefs, iter, xref) {
2874  if (xref->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
2875  ut64 offset = core->offset;
2876  core->offset = xref->from;
2877  rz_list_free(list);
2878  list = analysis_graph_to(core, addr, depth - 1, avoid);
2879  core->offset = offset;
2880  if (list && rz_list_length(list)) {
2881  rz_list_free(xrefs);
2882  ht_up_free(state);
2883  return list;
2884  }
2885  }
2886  }
2887  }
2888 
2889  rz_list_free(xrefs);
2890  ht_up_free(state);
2891  rz_list_free(list);
2892  return NULL;
2893 }
static bool analysis_path_exists(RzCore *core, ut64 from, ut64 to, RzList *bbs, int depth, HtUP *state, HtUP *avoid)
Definition: canalysis.c:2797
static RzList * analysis_graph_to(RzCore *core, ut64 addr, int depth, HtUP *avoid)
Definition: canalysis.c:2851
voidpf uLong offset
Definition: ioapi.h:144
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
Definition: list.c:235
RZ_API ut32 rz_list_length(RZ_NONNULL const RzList *list)
Returns the length of the list.
Definition: list.c:109
@ RZ_ANALYSIS_XREF_TYPE_CALL
Definition: rz_analysis.h:901
RzAnalysisXRefType type
Definition: rz_analysis.h:909
ut64 offset
Definition: rz_core.h:301

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, analysis_path_exists(), rz_analysis_ref_t::from, list(), NULL, rz_core_t::offset, rz_analysis_get_fcn_in(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_analysis_xrefs_get_to(), rz_list_free(), rz_list_length(), rz_list_new(), rz_analysis_ref_t::type, and ut64().

Referenced by rz_core_analysis_graph_to().

◆ analysis_path_exists()

static bool analysis_path_exists ( RzCore core,
ut64  from,
ut64  to,
RzList bbs,
int  depth,
HtUP *  state,
HtUP *  avoid 
)
static

Definition at line 2797 of file canalysis.c.

2797  {
2798  rz_return_val_if_fail(bbs, false);
2800  RzListIter *iter = NULL;
2801  RzAnalysisXRef *xrefi;
2802 
2803  if (depth < 1) {
2804  eprintf("going too deep\n");
2805  return false;
2806  }
2807 
2808  if (!bb) {
2809  return false;
2810  }
2811 
2812  ht_up_update(state, from, bb);
2813 
2814  // try to find the target in the current function
2815  if (rz_analysis_block_contains(bb, to) ||
2816  ((!ht_up_find(avoid, bb->jump, NULL) &&
2817  !ht_up_find(state, bb->jump, NULL) &&
2818  analysis_path_exists(core, bb->jump, to, bbs, depth - 1, state, avoid))) ||
2819  ((!ht_up_find(avoid, bb->fail, NULL) &&
2820  !ht_up_find(state, bb->fail, NULL) &&
2821  analysis_path_exists(core, bb->fail, to, bbs, depth - 1, state, avoid)))) {
2822  rz_list_prepend(bbs, bb);
2823  return true;
2824  }
2825 
2826  // find our current function
2828 
2829  // get call refs from current basic block and find a path from them
2830  if (cur_fcn) {
2831  RzList *xrefs = rz_analysis_function_get_xrefs_from(cur_fcn);
2832  if (xrefs) {
2833  rz_list_foreach (xrefs, iter, xrefi) {
2834  if (xrefi->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
2835  if (rz_analysis_block_contains(bb, xrefi->from)) {
2836  if ((xrefi->from != xrefi->to) && !ht_up_find(state, xrefi->to, NULL) && analysis_path_exists(core, xrefi->to, to, bbs, depth - 1, state, avoid)) {
2837  rz_list_prepend(bbs, bb);
2838  rz_list_free(xrefs);
2839  return true;
2840  }
2841  }
2842  }
2843  }
2844  }
2845  rz_list_free(xrefs);
2846  }
2847 
2848  return false;
2849 }
RZ_API RZ_BORROW RzListIter * rz_list_prepend(RZ_NONNULL RzList *list, void *data)
Appends at the beginning of the list a new element.
Definition: list.c:316
#define rz_return_val_if_fail(expr, val)
Definition: rz_assert.h:108
RZ_API RzList * rz_analysis_function_get_xrefs_from(RzAnalysisFunction *fcn)
Definition: xrefs.c:297

References rz_core_t::analysis, eprintf, rz_analysis_bb_t::fail, rz_analysis_ref_t::from, from, rz_analysis_bb_t::jump, NULL, rz_analysis_find_most_relevant_block_in(), rz_analysis_function_get_xrefs_from(), rz_analysis_get_fcn_in(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_list_free(), rz_list_prepend(), rz_return_val_if_fail, rz_analysis_ref_t::to, to, and rz_analysis_ref_t::type.

Referenced by analysis_graph_to().

◆ analysis_sigdb_add()

static void analysis_sigdb_add ( RzSigDb sigs,
const char *  path,
bool  with_details 
)
static

Definition at line 5971 of file canalysis.c.

5971  {
5973  return;
5974  }
5975  RzSigDb *tmp = rz_sign_sigdb_load_database(path, with_details);
5976  if (tmp) {
5977  rz_sign_sigdb_merge(sigs, tmp);
5979  }
5980 }
static static fork const void static count static fd const char const char static newpath const char static path const char path
Definition: sflib.h:35
RZ_API bool rz_file_is_directory(const char *str)
Definition: file.c:167
RZ_API bool rz_sign_sigdb_merge(RZ_NONNULL RzSigDb *db, RZ_NONNULL RzSigDb *db2)
Merge the signatures from db2 into db.
Definition: sigdb.c:184
RZ_API void rz_sign_sigdb_free(RzSigDb *db)
Definition: sigdb.c:277
RZ_API RZ_OWN RzSigDb * rz_sign_sigdb_load_database(RZ_NONNULL const char *sigdb_path, bool with_details)
Returns a database of signatures loaded from the signature database path.
Definition: sigdb.c:105
#define RZ_STR_ISEMPTY(x)
Definition: rz_str.h:67

References path, rz_file_is_directory(), rz_sign_sigdb_free(), rz_sign_sigdb_load_database(), rz_sign_sigdb_merge(), RZ_STR_ISEMPTY, and autogen_x86imm::tmp.

Referenced by rz_core_analysis_sigdb_list().

◆ analyze_noreturn_function()

static bool analyze_noreturn_function ( RzCore core,
RzAnalysisFunction f 
)
static

Definition at line 5168 of file canalysis.c.

5168  {
5169  RzListIter *iter;
5170  RzAnalysisBlock *bb;
5171  rz_list_foreach (f->bbs, iter, bb) {
5172  ut64 opaddr = rz_analysis_block_get_op_addr(bb, bb->ninstr - 1);
5173  if (opaddr == UT64_MAX) {
5174  return false;
5175  }
5176 
5177  // get last opcode
5179  if (!op) {
5180  eprintf("Cannot analyze opcode at 0x%08" PFMT64x "\n", opaddr);
5181  return false;
5182  }
5183 
5184  switch (op->type & RZ_ANALYSIS_OP_TYPE_MASK) {
5188  return false;
5190  if (!rz_analysis_function_contains(f, op->jump)) {
5192  return false;
5193  }
5194  break;
5195  }
5197  }
5198  return true;
5199 }
RZ_API bool rz_analysis_function_contains(RzAnalysisFunction *fcn, ut64 addr)
Definition: function.c:361
RZ_API RzAnalysisOp * rz_core_op_analysis(RzCore *core, ut64 addr, RzAnalysisOpMask mask)
Definition: core.c:2880
#define RZ_ANALYSIS_OP_TYPE_MASK
Definition: rz_analysis.h:358
@ RZ_ANALYSIS_OP_TYPE_JMP
Definition: rz_analysis.h:368
@ RZ_ANALYSIS_OP_TYPE_ILL
Definition: rz_analysis.h:387
@ RZ_ANALYSIS_OP_TYPE_RET
Definition: rz_analysis.h:385

References eprintf, f, rz_analysis_bb_t::ninstr, PFMT64x, rz_analysis_block_get_op_addr(), rz_analysis_function_contains(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_MASK, RZ_ANALYSIS_OP_TYPE_RET, rz_core_op_analysis(), ut64(), and UT64_MAX.

Referenced by reanalyze_fcns_cb(), and rz_core_analysis_propagate_noreturn().

◆ archIsThumbable()

static bool archIsThumbable ( RzCore core)
static

Definition at line 6453 of file canalysis.c.

6453  {
6454  RzAsm *as = core ? core->rasm : NULL;
6455  if (as && as->cur && as->bits <= 32 && as->cur->name) {
6456  return strstr(as->cur->name, "arm");
6457  }
6458  return false;
6459 }
int bits
Definition: rz_asm.h:100
_RzAsmPlugin * cur
Definition: rz_asm.h:106
RzAsm * rasm
Definition: rz_core.h:323

References rz_asm_t::bits, core_noretl::core, rz_asm_t::cur, NULL, and rz_core_t::rasm.

Referenced by _CbInRangeAav().

◆ autoname_imp_trampoline()

static void autoname_imp_trampoline ( RzCore core,
RzAnalysisFunction fcn 
)
static

Definition at line 776 of file canalysis.c.

776  {
777  if (rz_list_length(fcn->bbs) == 1 && ((RzAnalysisBlock *)rz_list_first(fcn->bbs))->ninstr == 1) {
779  if (xrefs && rz_list_length(xrefs) == 1) {
780  RzAnalysisXRef *xref = rz_list_first(xrefs);
781  if (xref->type != RZ_ANALYSIS_XREF_TYPE_CALL) { /* Some fcns don't return */
782  RzFlagItem *flg = rz_flag_get_i(core->flags, xref->to);
783  if (flg && rz_str_startswith(flg->name, "sym.imp.")) {
784  RZ_FREE(fcn->name);
785  fcn->name = rz_str_newf("sub.%s", flg->name + 8);
786  }
787  }
788  }
789  rz_list_free(xrefs);
790  }
791 }
RZ_API RZ_BORROW void * rz_list_first(RZ_NONNULL const RzList *list)
Returns the first element of the list.
Definition: list.c:77
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)
Definition: str.c:3286

References rz_analysis_function_t::bbs, rz_core_t::flags, rz_analysis_function_t::name, rz_flag_item_t::name, rz_analysis_function_get_xrefs_from(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_flag_get_i(), RZ_FREE, rz_list_first(), rz_list_free(), rz_list_length(), rz_str_newf(), rz_str_startswith(), rz_analysis_ref_t::to, and rz_analysis_ref_t::type.

Referenced by __core_analysis_fcn().

◆ bb_cmp()

static int bb_cmp ( const void *  a,
const void *  b 
)
static

Definition at line 472 of file canalysis.c.

472  {
473  const RzAnalysisBlock *ba = a;
474  const RzAnalysisBlock *bb = b;
475  return ba->addr - bb->addr;
476 }
#define a(i)
Definition: sha256.c:41

References a, rz_analysis_bb_t::addr, and b.

Referenced by rz_core_analysis_bbs_info_print().

◆ bb_cmpaddr()

RZ_IPI int bb_cmpaddr ( const void *  _a,
const void *  _b 
)

Definition at line 35 of file canalysis.c.

35  {
36  const RzAnalysisBlock *a = _a, *b = _b;
37  return (a->addr > b->addr) - (a->addr < b->addr);
38 }

References a, and b.

◆ bb_info_print()

static void bb_info_print ( RzCore core,
RzAnalysisFunction fcn,
RzAnalysisBlock bb,
ut64  addr,
RzOutputMode  mode,
PJ pj,
RzTable t 
)
static

Definition at line 363 of file canalysis.c.

364  {
365  RzDebugTracepoint *tp = NULL;
366  RzListIter *iter;
367  RzAnalysisBlock *bb2;
368  int outputs = (bb->jump != UT64_MAX) + (bb->fail != UT64_MAX);
369  int inputs = 0;
370  rz_list_foreach (fcn->bbs, iter, bb2) {
371  inputs += (bb2->jump == bb->addr) + (bb2->fail == bb->addr);
372  }
373  if (bb->switch_op) {
374  RzList *unique_cases = rz_list_uniq(bb->switch_op->cases, casecmp);
375  outputs += rz_list_length(unique_cases);
376  rz_list_free(unique_cases);
377  }
378  ut64 opaddr = __opaddr(bb, addr);
379 
380  switch (mode) {
382  tp = rz_debug_trace_get(core->dbg, bb->addr);
383  rz_cons_printf("0x%08" PFMT64x " 0x%08" PFMT64x " %02X:%04X %" PFMT64d,
384  bb->addr, bb->addr + bb->size,
385  tp ? tp->times : 0, tp ? tp->count : 0,
386  bb->size);
387  if (bb->jump != UT64_MAX) {
388  rz_cons_printf(" j 0x%08" PFMT64x, bb->jump);
389  }
390  if (bb->fail != UT64_MAX) {
391  rz_cons_printf(" f 0x%08" PFMT64x, bb->fail);
392  }
393  if (bb->switch_op) {
394  RzAnalysisCaseOp *cop;
395  RzListIter *iter;
396  RzList *unique_cases = rz_list_uniq(bb->switch_op->cases, casecmp);
397  rz_list_foreach (unique_cases, iter, cop) {
398  rz_cons_printf(" s 0x%08" PFMT64x, cop->addr);
399  }
400  rz_list_free(unique_cases);
401  }
402  rz_cons_newline();
403  break;
404  case RZ_OUTPUT_MODE_JSON: {
405  pj_o(pj);
406  if (bb->jump != UT64_MAX) {
407  pj_kn(pj, "jump", bb->jump);
408  }
409  if (bb->fail != UT64_MAX) {
410  pj_kn(pj, "fail", bb->fail);
411  }
412  if (bb->switch_op) {
413  pj_k(pj, "switch_op");
414  pj_o(pj);
415  pj_kn(pj, "addr", bb->switch_op->addr);
416  pj_kn(pj, "min_val", bb->switch_op->min_val);
417  pj_kn(pj, "def_val", bb->switch_op->def_val);
418  pj_kn(pj, "max_val", bb->switch_op->max_val);
419  pj_k(pj, "cases");
420  pj_a(pj);
421  {
422  RzListIter *case_op_iter;
423  RzAnalysisCaseOp *case_op;
424  rz_list_foreach (bb->switch_op->cases, case_op_iter, case_op) {
425  pj_o(pj);
426  pj_kn(pj, "addr", case_op->addr);
427  pj_kn(pj, "jump", case_op->jump);
428  pj_kn(pj, "value", case_op->value);
429  pj_end(pj);
430  }
431  }
432  pj_end(pj);
433  pj_end(pj);
434  }
435  pj_kn(pj, "opaddr", opaddr);
436  pj_kn(pj, "addr", bb->addr);
437  pj_ki(pj, "size", bb->size);
438  pj_ki(pj, "inputs", inputs);
439  pj_ki(pj, "outputs", outputs);
440  pj_ki(pj, "ninstr", bb->ninstr);
441  pj_kb(pj, "traced", bb->traced);
442  pj_end(pj);
443  break;
444  }
446  rz_table_add_rowf(t, "xdxx", bb->addr, bb->size, bb->jump, bb->fail);
447  break;
449  rz_cons_printf("f bb.%05" PFMT64x " @ 0x%08" PFMT64x "\n", bb->addr & 0xFFFFF, bb->addr);
450  break;
452  rz_cons_printf("0x%08" PFMT64x "\n", bb->addr);
453  break;
454  case RZ_OUTPUT_MODE_LONG: {
455  if (bb->jump != UT64_MAX) {
456  rz_cons_printf("jump: 0x%08" PFMT64x "\n", bb->jump);
457  }
458  if (bb->fail != UT64_MAX) {
459  rz_cons_printf("fail: 0x%08" PFMT64x "\n", bb->fail);
460  }
461  rz_cons_printf("opaddr: 0x%08" PFMT64x "\n", opaddr);
462  rz_cons_printf("addr: 0x%08" PFMT64x "\nsize: %" PFMT64d "\ninputs: %d\noutputs: %d\nninstr: %d\ntraced: %s\n",
463  bb->addr, bb->size, inputs, outputs, bb->ninstr, rz_str_bool(bb->traced));
464  break;
465  }
466  default:
468  break;
469  }
470 }
static int casecmp(const void *_a, const void *_b)
Definition: canalysis.c:343
static ut64 __opaddr(RzAnalysisBlock *b, ut64 addr)
Definition: canalysis.c:349
RZ_API void rz_cons_newline(void)
Definition: cons.c:1274
const char int mode
Definition: ioapi.h:137
RZ_API RZ_OWN RzList * rz_list_uniq(RZ_NONNULL const RzList *list, RZ_NONNULL RzListComparator cmp)
Returns a new RzList which contains only unique values.
Definition: list.c:756
#define rz_warn_if_reached()
Definition: rz_assert.h:29
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
Definition: pj.c:177
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
Definition: pj.c:149
RZ_API PJ * pj_k(PJ *j, const char *k)
Definition: pj.c:104
RZ_API PJ * pj_end(PJ *j)
Definition: pj.c:87
RZ_API PJ * pj_o(PJ *j)
Definition: pj.c:75
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
Definition: pj.c:121
RZ_API PJ * pj_a(PJ *j)
Definition: pj.c:81
RZ_API const char * rz_str_bool(int b)
Definition: str.c:3896
RZ_API void rz_table_add_rowf(RzTable *t, const char *fmt,...)
Definition: table.c:316
#define PFMT64d
Definition: rz_types.h:394
@ RZ_OUTPUT_MODE_TABLE
Definition: rz_types.h:46
@ RZ_OUTPUT_MODE_LONG
Definition: rz_types.h:44
@ RZ_OUTPUT_MODE_JSON
Definition: rz_types.h:40
@ RZ_OUTPUT_MODE_QUIET
Definition: rz_types.h:42
RzAnalysisSwitchOp * switch_op
Definition: rz_analysis.h:874
RzDebug * dbg
Definition: rz_core.h:329
RZ_API RzDebugTracepoint * rz_debug_trace_get(RzDebug *dbg, ut64 addr)
Definition: trace.c:200

References __opaddr(), addr, rz_analysis_case_obj_t::addr, rz_analysis_switch_obj_t::addr, rz_analysis_bb_t::addr, rz_analysis_function_t::bbs, casecmp(), rz_analysis_switch_obj_t::cases, rz_debug_tracepoint_t::count, rz_core_t::dbg, rz_analysis_switch_obj_t::def_val, rz_analysis_bb_t::fail, rz_analysis_case_obj_t::jump, rz_analysis_bb_t::jump, rz_analysis_switch_obj_t::max_val, rz_analysis_switch_obj_t::min_val, rz_analysis_bb_t::ninstr, NULL, PFMT64d, PFMT64x, pj_a(), pj_end(), pj_k(), pj_kb(), pj_ki(), pj_kn(), pj_o(), rz_cons_newline(), rz_cons_printf(), rz_debug_trace_get(), rz_list_free(), rz_list_length(), rz_list_uniq(), RZ_OUTPUT_MODE_JSON, RZ_OUTPUT_MODE_LONG, RZ_OUTPUT_MODE_QUIET, RZ_OUTPUT_MODE_RIZIN, RZ_OUTPUT_MODE_STANDARD, RZ_OUTPUT_MODE_TABLE, rz_str_bool(), rz_table_add_rowf(), rz_warn_if_reached, rz_analysis_bb_t::size, rz_analysis_bb_t::switch_op, rz_debug_tracepoint_t::times, rz_analysis_bb_t::traced, ut64(), UT64_MAX, and rz_analysis_case_obj_t::value.

Referenced by rz_core_analysis_bb_info_print(), and rz_core_analysis_bbs_info_print().

◆ blacklisted_word()

static bool blacklisted_word ( const char *  name)
static

Definition at line 526 of file canalysis.c.

526  {
527  const char *list[] = {
528  "__stack_chk_guard",
529  "__stderrp",
530  "__stdinp",
531  "__stdoutp",
532  "_DefaultRuneLocale"
533  };
534  for (int i = 0; i < RZ_ARRAY_SIZE(list); i++) {
535  if (strstr(name, list[i])) {
536  return true;
537  }
538  }
539  return false;
540 }
#define RZ_ARRAY_SIZE(x)
Definition: rz_types.h:300

References i, list(), and RZ_ARRAY_SIZE.

Referenced by rz_core_analysis_function_autoname().

◆ block_flags_stat()

static bool block_flags_stat ( RzFlagItem fi,
void *  user 
)
static

Definition at line 3703 of file canalysis.c.

3703  {
3704  struct block_flags_stat_t *u = (struct block_flags_stat_t *)user;
3705  size_t piece = (fi->offset - u->from) / u->step;
3706  u->blocks[piece].flags++;
3707  return true;
3708 }
RzCoreAnalysisStatsItem * blocks
Definition: canalysis.c:3700
ut64 offset
Definition: rz_flag.h:38

References block_flags_stat_t::blocks, block_flags_stat_t::from, rz_flag_item_t::offset, and block_flags_stat_t::step.

Referenced by rz_core_analysis_get_stats().

◆ casecmp()

static int casecmp ( const void *  _a,
const void *  _b 
)
static

Definition at line 343 of file canalysis.c.

343  {
344  const RzAnalysisCaseOp *a = _a;
345  const RzAnalysisCaseOp *b = _b;
346  return a->addr != b->addr;
347 }

References a, and b.

Referenced by bb_info_print().

◆ cccb()

static void cccb ( void *  u)
static

Definition at line 4097 of file canalysis.c.

4097  {
4098  esil_analysis_stop = true;
4099  eprintf("^C\n");
4100 }
static bool esil_analysis_stop
Definition: canalysis.c:4096

References eprintf, and esil_analysis_stop.

Referenced by rz_core_analysis_esil().

◆ check_rom_exists()

static int check_rom_exists ( const void *  value,
const void *  data 
)
static

Definition at line 6279 of file canalysis.c.

6279  {
6280  const char *name = (const char *)value;
6281  const RzBinSection *sections = (const RzBinSection *)data;
6282  return strcmp(name, sections->name);
6283 }
RzList * sections(RzBinFile *bf)
Definition: bin_ne.c:110
static int value
Definition: cmd_api.c:93

References sections(), and value.

Referenced by rz_analysis_add_device_peripheral_map().

◆ core_analysis_color_curr_node()

static void core_analysis_color_curr_node ( RzCore core,
RzAnalysisBlock bbi 
)
static

Definition at line 1513 of file canalysis.c.

1513  {
1514  bool color_current = rz_config_get_i(core->config, "graph.gv.current");
1515  char *pal_curr = palColorFor("graph.current");
1516  bool current = rz_analysis_block_contains(bbi, core->offset);
1517 
1518  if (current && color_current) {
1519  rz_cons_printf("\t\"0x%08" PFMT64x "\" ", bbi->addr);
1520  rz_cons_printf("\t[fillcolor=%s style=filled shape=box];\n", pal_curr);
1521  }
1522  free(pal_curr);
1523 }
static char * palColorFor(const char *k)
Definition: canalysis.c:1505

References rz_analysis_bb_t::addr, rz_core_t::config, free(), rz_core_t::offset, palColorFor(), PFMT64x, rz_config_get_i(), and rz_cons_printf().

Referenced by core_analysis_graph_construct_edges().

◆ core_analysis_followptr()

static int core_analysis_followptr ( RzCore core,
int  type,
ut64  at,
ut64  ptr,
ut64  ref,
int  code,
int  depth 
)
static

Definition at line 3017 of file canalysis.c.

3017  {
3018  // SLOW Operation try to reduce as much as possible
3019  if (!ptr) {
3020  return false;
3021  }
3022  if (ref == UT64_MAX || ptr == ref) {
3024  rz_analysis_xrefs_set(core->analysis, at, ptr, t);
3025  return true;
3026  }
3027  if (depth < 1) {
3028  return false;
3029  }
3030  int wordsize = (int)(core->analysis->bits / 8);
3031  ut64 dataptr;
3032  if (!rz_io_read_i(core->io, ptr, &dataptr, wordsize, false)) {
3033  // eprintf ("core_analysis_followptr: Cannot read word at destination\n");
3034  return false;
3035  }
3036  return core_analysis_followptr(core, type, at, dataptr, ref, code, depth - 1);
3037 }
static int core_analysis_followptr(RzCore *core, int type, ut64 at, ut64 ptr, ut64 ref, int code, int depth)
Definition: canalysis.c:3017
int type
Definition: mipsasm.c:17
RzAnalysisXRefType
Definition: rz_analysis.h:898
@ RZ_ANALYSIS_XREF_TYPE_CODE
Definition: rz_analysis.h:900
RZ_API bool rz_io_read_i(RzIO *io, ut64 addr, ut64 *val, int size, bool endian)
Definition: ioutils.c:41
static int
Definition: sfsocketcall.h:114
Definition: inftree9.h:24

References rz_core_t::analysis, rz_analysis_t::bits, int, rz_core_t::io, RZ_ANALYSIS_XREF_TYPE_CODE, RZ_ANALYSIS_XREF_TYPE_DATA, rz_analysis_xrefs_set(), rz_io_read_i(), type, ut64(), and UT64_MAX.

Referenced by rz_core_analysis_search().

◆ core_analysis_graph_construct_edges()

static int core_analysis_graph_construct_edges ( RzCore core,
RzAnalysisFunction fcn,
int  opts,
PJ pj,
Sdb DB 
)
static

Definition at line 1525 of file canalysis.c.

1525  {
1526  RzAnalysisBlock *bbi;
1527  RzListIter *iter;
1528  int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
1529  int is_star = opts & RZ_CORE_ANALYSIS_STAR;
1530  int is_json = opts & RZ_CORE_ANALYSIS_JSON;
1531  int is_html = rz_cons_singleton()->is_html;
1532  char *pal_jump = palColorFor("graph.true");
1533  char *pal_fail = palColorFor("graph.false");
1534  char *pal_trfa = palColorFor("graph.ujump");
1535  int nodes = 0;
1536  rz_list_foreach (fcn->bbs, iter, bbi) {
1537  if (bbi->jump != UT64_MAX) {
1538  nodes++;
1539  if (is_keva) {
1540  char key[128];
1541  char val[128];
1542  snprintf(key, sizeof(key), "bb.0x%08" PFMT64x ".to", bbi->addr);
1543  if (bbi->fail != UT64_MAX) {
1544  snprintf(val, sizeof(val), "0x%08" PFMT64x, bbi->jump);
1545  } else {
1546  snprintf(val, sizeof(val), "0x%08" PFMT64x ",0x%08" PFMT64x,
1547  bbi->jump, bbi->fail);
1548  }
1549  // bb.<addr>.to=<jump>,<fail>
1550  sdb_set(DB, key, val, 0);
1551  } else if (is_html) {
1552  rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
1553  " <img class=\"connector-end\" src=\"img/arrow.gif\" /></div>\n",
1554  bbi->addr, bbi->jump);
1555  } else if (!is_json && !is_keva) {
1556  if (is_star) {
1557  char *from = get_title(bbi->addr);
1558  char *to = get_title(bbi->jump);
1559  rz_cons_printf("age %s %s\n", from, to);
1560  free(from);
1561  free(to);
1562  } else {
1563  rz_cons_printf(" \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
1564  "[color=\"%s\"];\n",
1565  bbi->addr, bbi->jump,
1566  bbi->fail != -1 ? pal_jump : pal_trfa);
1567  core_analysis_color_curr_node(core, bbi);
1568  }
1569  }
1570  }
1571  if (bbi->fail != -1) {
1572  nodes++;
1573  if (is_html) {
1574  rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
1575  " <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
1576  bbi->addr, bbi->fail);
1577  } else if (!is_keva && !is_json) {
1578  if (is_star) {
1579  char *from = get_title(bbi->addr);
1580  char *to = get_title(bbi->fail);
1581  rz_cons_printf("age %s %s\n", from, to);
1582  free(from);
1583  free(to);
1584  } else {
1585  rz_cons_printf(" \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
1586  "[color=\"%s\"];\n",
1587  bbi->addr, bbi->fail, pal_fail);
1588  core_analysis_color_curr_node(core, bbi);
1589  }
1590  }
1591  }
1592  if (bbi->switch_op) {
1593  RzAnalysisCaseOp *caseop;
1594  RzListIter *iter;
1595 
1596  if (bbi->fail != UT64_MAX) {
1597  if (is_html) {
1598  rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
1599  " <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
1600  bbi->addr, bbi->fail);
1601  } else if (!is_keva && !is_json) {
1602  if (is_star) {
1603  char *from = get_title(bbi->addr);
1604  char *to = get_title(bbi->fail);
1605  rz_cons_printf("age %s %s\n", from, to);
1606  free(from);
1607  free(to);
1608  } else {
1609  rz_cons_printf(" \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
1610  "[color=\"%s\"];\n",
1611  bbi->addr, bbi->fail, pal_fail);
1612  core_analysis_color_curr_node(core, bbi);
1613  }
1614  }
1615  }
1616  rz_list_foreach (bbi->switch_op->cases, iter, caseop) {
1617  nodes++;
1618  if (is_keva) {
1619  char key[128];
1620  snprintf(key, sizeof(key),
1621  "bb.0x%08" PFMT64x ".switch.%" PFMT64d,
1622  bbi->addr, caseop->value);
1623  sdb_num_set(DB, key, caseop->jump, 0);
1624  snprintf(key, sizeof(key),
1625  "bb.0x%08" PFMT64x ".switch", bbi->addr);
1626  sdb_array_add_num(DB, key, caseop->value, 0);
1627  } else if (is_html) {
1628  rz_cons_printf("<div class=\"connector _0x%08" PFMT64x " _0x%08" PFMT64x "\">\n"
1629  " <img class=\"connector-end\" src=\"img/arrow.gif\"/></div>\n",
1630  caseop->addr, caseop->jump);
1631  } else if (!is_json && !is_keva) {
1632  if (is_star) {
1633  char *from = get_title(caseop->addr);
1634  char *to = get_title(caseop->jump);
1635  rz_cons_printf("age %s %s\n", from, to);
1636  free(from);
1637  free(to);
1638  } else {
1639  rz_cons_printf(" \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
1640  "[color2=\"%s\"];\n",
1641  caseop->addr, caseop->jump, pal_fail);
1642  core_analysis_color_curr_node(core, bbi);
1643  }
1644  }
1645  }
1646  }
1647  }
1648  free(pal_jump);
1649  free(pal_fail);
1650  free(pal_trfa);
1651  return nodes;
1652 }
ut16 val
Definition: armass64_const.h:6
RZ_API int sdb_array_add_num(Sdb *s, const char *key, ut64 val, ut32 cas)
Definition: array.c:211
static char * get_title(ut64 addr)
Definition: canalysis.c:1028
static void core_analysis_color_curr_node(RzCore *core, RzAnalysisBlock *bbi)
Definition: canalysis.c:1513
#define DB
Definition: cc.c:8
RZ_API RzCons * rz_cons_singleton(void)
Definition: cons.c:300
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len key
Definition: sflib.h:118
snprintf
Definition: kernel.h:364
RZ_API int sdb_num_set(Sdb *s, const char *key, ut64 v, ut32 cas)
Definition: num.c:25
#define RZ_CORE_ANALYSIS_STAR
Definition: rz_core.h:55
#define RZ_CORE_ANALYSIS_KEYVALUE
Definition: rz_core.h:53
#define RZ_CORE_ANALYSIS_JSON
Definition: rz_core.h:52
RZ_API int sdb_set(Sdb *s, const char *key, const char *val, ut32 cas)
Definition: sdb.c:611
bool is_html
Definition: rz_cons.h:505

References rz_analysis_case_obj_t::addr, rz_analysis_bb_t::addr, rz_analysis_function_t::bbs, rz_analysis_switch_obj_t::cases, core_analysis_color_curr_node(), DB, rz_analysis_bb_t::fail, free(), from, get_title(), rz_cons_t::is_html, rz_analysis_case_obj_t::jump, rz_analysis_bb_t::jump, key, palColorFor(), PFMT64d, PFMT64x, rz_cons_printf(), rz_cons_singleton(), RZ_CORE_ANALYSIS_JSON, RZ_CORE_ANALYSIS_KEYVALUE, RZ_CORE_ANALYSIS_STAR, sdb_array_add_num(), sdb_num_set(), sdb_set(), snprintf, rz_analysis_bb_t::switch_op, to, UT64_MAX, val, and rz_analysis_case_obj_t::value.

Referenced by core_analysis_graph_nodes().

◆ core_analysis_graph_construct_nodes()

static int core_analysis_graph_construct_nodes ( RzCore core,
RzAnalysisFunction fcn,
int  opts,
PJ pj,
Sdb DB 
)
static

Definition at line 1654 of file canalysis.c.

1654  {
1655  RzAnalysisBlock *bbi;
1656  RzListIter *iter;
1657  int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
1658  int is_star = opts & RZ_CORE_ANALYSIS_STAR;
1659  int is_json = opts & RZ_CORE_ANALYSIS_JSON;
1660  int is_html = rz_cons_singleton()->is_html;
1661  int left = 300;
1662  int top = 0;
1663 
1664  int is_json_format_disasm = opts & RZ_CORE_ANALYSIS_JSON_FORMAT_DISASM;
1665  char *pal_curr = palColorFor("graph.current");
1666  char *pal_traced = palColorFor("graph.traced");
1667  char *pal_box4 = palColorFor("graph.box4");
1668  const char *font = rz_config_get(core->config, "graph.font");
1669  bool color_current = rz_config_get_i(core->config, "graph.gv.current");
1670  char *str;
1671  int nodes = 0;
1672  rz_list_foreach (fcn->bbs, iter, bbi) {
1673  if (is_keva) {
1674  char key[128];
1675  sdb_array_push_num(DB, "bbs", bbi->addr, 0);
1676  snprintf(key, sizeof(key), "bb.0x%08" PFMT64x ".size", bbi->addr);
1677  sdb_num_set(DB, key, bbi->size, 0); // bb.<addr>.size=<num>
1678  } else if (is_json) {
1679  RzDebugTracepoint *t = rz_debug_trace_get(core->dbg, bbi->addr);
1680  ut8 *buf = malloc(bbi->size);
1681  pj_o(pj);
1682  pj_kn(pj, "offset", bbi->addr);
1683  pj_kn(pj, "size", bbi->size);
1684  if (bbi->jump != UT64_MAX) {
1685  pj_kn(pj, "jump", bbi->jump);
1686  }
1687  if (bbi->fail != -1) {
1688  pj_kn(pj, "fail", bbi->fail);
1689  }
1690  if (bbi->switch_op) {
1692  pj_k(pj, "switchop");
1693  pj_o(pj);
1694  pj_kn(pj, "offset", op->addr);
1695  pj_kn(pj, "defval", op->def_val);
1696  pj_kn(pj, "maxval", op->max_val);
1697  pj_kn(pj, "minval", op->min_val);
1698  pj_k(pj, "cases");
1699  pj_a(pj);
1700  RzAnalysisCaseOp *case_op;
1701  RzListIter *case_iter;
1702  rz_list_foreach (op->cases, case_iter, case_op) {
1703  pj_o(pj);
1704  pj_kn(pj, "offset", case_op->addr);
1705  pj_kn(pj, "value", case_op->value);
1706  pj_kn(pj, "jump", case_op->jump);
1707  pj_end(pj);
1708  }
1709  pj_end(pj);
1710  pj_end(pj);
1711  }
1712  if (t) {
1713  pj_k(pj, "trace");
1714  pj_o(pj);
1715  pj_ki(pj, "count", t->count);
1716  pj_ki(pj, "times", t->times);
1717  pj_end(pj);
1718  }
1719  pj_kn(pj, "colorize", bbi->colorize);
1720  pj_k(pj, "ops");
1721  pj_a(pj);
1722  if (buf) {
1723  rz_io_read_at(core->io, bbi->addr, buf, bbi->size);
1724  if (is_json_format_disasm) {
1726  .mode = RZ_OUTPUT_MODE_JSON,
1727  .d = { .pj = pj }
1728  };
1729  RzCoreDisasmOptions disasm_options = {
1730  .cbytes = 1,
1731  };
1732  rz_core_print_disasm(core, bbi->addr, buf, bbi->size, bbi->size, &state, &disasm_options);
1733  } else {
1734  rz_core_print_disasm_json(core, bbi->addr, buf, bbi->size, 0, pj);
1735  }
1736  free(buf);
1737  } else {
1738  eprintf("cannot allocate %" PFMT64u " byte(s)\n", bbi->size);
1739  }
1740  pj_end(pj);
1741  pj_end(pj);
1742  continue;
1743  }
1744  if ((str = core_analysis_graph_label(core, bbi, opts))) {
1745  if (opts & RZ_CORE_ANALYSIS_GRAPHDIFF) {
1746  const char *difftype = bbi->diff ? (
1747  bbi->diff->type == RZ_ANALYSIS_DIFF_TYPE_MATCH ? "lightgray" : bbi->diff->type == RZ_ANALYSIS_DIFF_TYPE_UNMATCH ? "yellow"
1748  : "red")
1749  : "orange";
1750  const char *diffname = bbi->diff ? (
1751  bbi->diff->type == RZ_ANALYSIS_DIFF_TYPE_MATCH ? "match" : bbi->diff->type == RZ_ANALYSIS_DIFF_TYPE_UNMATCH ? "unmatch"
1752  : "new")
1753  : "unk";
1754  if (is_keva) {
1755  sdb_set(DB, "diff", diffname, 0);
1756  sdb_set(DB, "label", str, 0);
1757  } else if (!is_json) {
1758  nodes++;
1759  RzConfigHold *hc = rz_config_hold_new(core->config);
1760  rz_config_hold_i(hc, "scr.color", "scr.utf8", "asm.offset", "asm.lines",
1761  "asm.cmt.right", "asm.lines.fcn", "asm.bytes", NULL);
1762  rz_config_set_i(core->config, "scr.utf8", 0);
1763  rz_config_set_i(core->config, "asm.offset", 0);
1764  rz_config_set_i(core->config, "asm.lines", 0);
1765  rz_config_set_i(core->config, "asm.cmt.right", 0);
1766  rz_config_set_i(core->config, "asm.lines.fcn", 0);
1767  rz_config_set_i(core->config, "asm.bytes", 0);
1768  if (!is_star) {
1769  rz_config_set_i(core->config, "scr.color", 0); // disable color for dot
1770  }
1771 
1772  if (bbi->diff && bbi->diff->type != RZ_ANALYSIS_DIFF_TYPE_MATCH && core->c2) {
1773  char dff_from[32], dff_to[32];
1774 
1775  RzCore *c = core->c2;
1776  RzConfig *oc = c->config;
1777  char *str = rz_core_cmd_strf(core, "pdb @ 0x%08" PFMT64x, bbi->addr);
1778  c->config = core->config;
1779  // XXX. the bbi->addr doesnt needs to be in the same address in core2
1780  char *str2 = rz_core_cmd_strf(c, "pdb @ 0x%08" PFMT64x, bbi->diff->addr);
1781  snprintf(dff_from, sizeof(dff_from), "0x%08" PFMT64x, bbi->addr);
1782  snprintf(dff_to, sizeof(dff_to), "0x%08" PFMT64x, bbi->diff->addr);
1783 
1784  RzDiff *dff = rz_diff_lines_new(str, str2, NULL);
1785  char *diffstr = rz_diff_unified_text(dff, dff_from, dff_to, false, false);
1786  rz_diff_free(dff);
1787 
1788  if (diffstr) {
1789  char *nl = strchr(diffstr, '\n');
1790  if (nl) {
1791  nl = strchr(nl + 1, '\n');
1792  if (nl) {
1793  nl = strchr(nl + 1, '\n');
1794  if (nl) {
1795  rz_str_cpy(diffstr, nl + 1);
1796  }
1797  }
1798  }
1799  }
1800 
1801  if (is_star) {
1802  char *title = get_title(bbi->addr);
1803  if (!title) {
1804  rz_config_hold_free(hc);
1805  return false;
1806  }
1807  char *body_b64 = rz_base64_encode_dyn((const ut8 *)diffstr, strlen(diffstr));
1808  if (!body_b64) {
1809  free(title);
1810  rz_config_hold_free(hc);
1811  return false;
1812  }
1813  body_b64 = rz_str_prepend(body_b64, "base64:");
1814  rz_cons_printf("agn %s %s %d\n", title, body_b64, bbi->diff->type);
1815  free(body_b64);
1816  free(title);
1817  } else {
1818  diffstr = rz_str_replace(diffstr, "\n", "\\l", 1);
1819  diffstr = rz_str_replace(diffstr, "\"", "'", 1);
1820  rz_cons_printf(" \"0x%08" PFMT64x "\" [fillcolor=\"%s\","
1821  "color=\"black\", fontname=\"%s\","
1822  " label=\"%s\", URL=\"%s/0x%08" PFMT64x "\"]\n",
1823  bbi->addr, difftype, diffstr, font, fcn->name,
1824  bbi->addr);
1825  }
1826  free(diffstr);
1827  c->config = oc;
1828  } else {
1829  if (is_star) {
1830  char *title = get_title(bbi->addr);
1831  if (!title) {
1832  rz_config_hold_free(hc);
1833  return false;
1834  }
1835  char *body_b64 = rz_base64_encode_dyn((const ut8 *)str, strlen(title));
1836  int color = (bbi && bbi->diff) ? bbi->diff->type : 0;
1837  if (!title || !body_b64) {
1838  free(body_b64);
1839  free(title);
1840  rz_config_hold_free(hc);
1841  return false;
1842  }
1843  body_b64 = rz_str_prepend(body_b64, "base64:");
1844  rz_cons_printf("agn %s %s %d\n", title, body_b64, color);
1845  free(body_b64);
1846  free(title);
1847  } else {
1848  rz_cons_printf(" \"0x%08" PFMT64x "\" [fillcolor=\"%s\","
1849  "color=\"black\", fontname=\"%s\","
1850  " label=\"%s\", URL=\"%s/0x%08" PFMT64x "\"]\n",
1851  bbi->addr, difftype, str, font, fcn->name, bbi->addr);
1852  }
1853  }
1854  rz_config_set_i(core->config, "scr.color", 1);
1855  rz_config_hold_free(hc);
1856  }
1857  } else {
1858  if (is_html) {
1859  nodes++;
1860  rz_cons_printf("<p class=\"block draggable\" style=\""
1861  "top: %dpx; left: %dpx; width: 400px;\" id=\""
1862  "_0x%08" PFMT64x "\">\n%s</p>\n",
1863  top, left, bbi->addr, str);
1864  left = left ? 0 : 600;
1865  if (!left) {
1866  top += 250;
1867  }
1868  } else if (!is_json && !is_keva) {
1869  bool current = rz_analysis_block_contains(bbi, core->offset);
1870  const char *label_color = bbi->traced
1871  ? pal_traced
1872  : (current && color_current)
1873  ? pal_curr
1874  : pal_box4;
1875  const char *fill_color = ((current && color_current) || label_color == pal_traced) ? pal_traced : "white";
1876  nodes++;
1877  if (is_star) {
1878  char *title = get_title(bbi->addr);
1879  char *body_b64 = rz_base64_encode_dyn((const ut8 *)str, strlen(str));
1880  int color = (bbi && bbi->diff) ? bbi->diff->type : 0;
1881  if (!title || !body_b64) {
1882  free(body_b64);
1883  free(title);
1884  return false;
1885  }
1886  body_b64 = rz_str_prepend(body_b64, "base64:");
1887  rz_cons_printf("agn %s %s %d\n", title, body_b64, color);
1888  free(body_b64);
1889  free(title);
1890  } else {
1891  rz_cons_printf("\t\"0x%08" PFMT64x "\" ["
1892  "URL=\"%s/0x%08" PFMT64x "\", fillcolor=\"%s\","
1893  "color=\"%s\", fontname=\"%s\","
1894  "label=\"%s\"]\n",
1895  bbi->addr, fcn->name, bbi->addr,
1896  fill_color, label_color, font, str);
1897  }
1898  }
1899  }
1900  free(str);
1901  }
1902  }
1903  return nodes;
1904 }
RZ_API int sdb_array_push_num(Sdb *s, const char *key, ut64 num, ut32 cas)
Definition: array.c:528
static char * core_analysis_graph_label(RzCore *core, RzAnalysisBlock *bb, int opts)
Definition: canalysis.c:1453
RZ_API char * rz_core_cmd_strf(RzCore *core, const char *fmt,...)
Definition: cmd.c:5472
RZ_API RzConfigNode * rz_config_set_i(RzConfig *cfg, RZ_NONNULL const char *name, const ut64 i)
Definition: config.c:419
RZ_API RZ_OWN RzDiff * rz_diff_lines_new(RZ_BORROW const char *a, RZ_BORROW const char *b, RZ_NULLABLE RzDiffIgnoreLine ignore)
Returns the structure needed to diff lines.
Definition: diff.c:219
RZ_API void rz_diff_free(RZ_NULLABLE RzDiff *diff)
frees the diff structure
Definition: diff.c:295
RZ_API int rz_core_print_disasm_json(RzCore *core, ut64 addr, ut8 *buf, int nb_bytes, int nb_opcodes, PJ *pj)
Definition: disasm.c:6040
RZ_API int rz_core_print_disasm(RZ_NONNULL RzCore *core, ut64 addr, RZ_NONNULL ut8 *buf, int len, int nlines, RZ_NULLABLE RzCmdStateOutput *state, RZ_NULLABLE RzCoreDisasmOptions *options)
Disassemble len bytes and nlines opcodes restricted by len and nlines at the same time.
Definition: disasm.c:5336
RZ_API RzConfigHold * rz_config_hold_new(RzConfig *cfg)
Create an opaque object to save/restore some configuration options.
Definition: hold.c:116
RZ_API bool rz_config_hold_i(RzConfigHold *h,...)
Save the current values of a list of config options that have integer values.
Definition: hold.c:81
RZ_API void rz_config_hold_free(RzConfigHold *h)
Free a RzConfigHold object h.
Definition: hold.c:152
voidpf void * buf
Definition: ioapi.h:138
uint8_t ut8
Definition: lh5801.h:11
void * malloc(size_t size)
Definition: malloc.c:123
@ RZ_ANALYSIS_DIFF_TYPE_MATCH
Definition: rz_analysis.h:206
@ RZ_ANALYSIS_DIFF_TYPE_UNMATCH
Definition: rz_analysis.h:207
RZ_API char * rz_base64_encode_dyn(const ut8 *bin, size_t sz)
Definition: ubase64.c:92
#define RZ_CORE_ANALYSIS_JSON_FORMAT_DISASM
Definition: rz_core.h:54
#define RZ_CORE_ANALYSIS_GRAPHDIFF
Definition: rz_core.h:51
RZ_API bool rz_io_read_at(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:300
#define rz_str_cpy(x, y)
Definition: rz_str.h:109
RZ_API char * rz_str_prepend(char *ptr, const char *string)
Definition: str.c:1027
RZ_API char * rz_str_replace(char *str, const char *key, const char *val, int g)
Definition: str.c:1110
#define PFMT64u
Definition: rz_types.h:395
RzAnalysisDiff * diff
Definition: rz_analysis.h:872
Represent the output state of a command handler.
Definition: rz_cmd.h:91
struct rz_core_t * c2
Definition: rz_core.h:379
Definition: diff.c:89
RZ_API RZ_OWN char * rz_diff_unified_text(RZ_NONNULL RzDiff *diff, RZ_NULLABLE const char *from, RZ_NULLABLE const char *to, bool show_time, bool color)
Produces a diff output with A and B inputs presented immediately adjacent to each other.
Definition: unified_diff.c:333
static int color
Definition: visual.c:20
if(dbg->bits==RZ_SYS_BITS_64)
Definition: windows-arm64.h:4

References rz_analysis_diff_t::addr, rz_analysis_case_obj_t::addr, rz_analysis_bb_t::addr, rz_analysis_function_t::bbs, c, rz_core_t::c2, color, rz_analysis_bb_t::colorize, rz_core_t::config, core_analysis_graph_label(), rz_debug_tracepoint_t::count, DB, rz_core_t::dbg, rz_analysis_bb_t::diff, eprintf, rz_analysis_bb_t::fail, free(), get_title(), if(), rz_core_t::io, rz_cons_t::is_html, rz_analysis_case_obj_t::jump, rz_analysis_bb_t::jump, key, malloc(), rz_analysis_function_t::name, NULL, rz_core_t::offset, palColorFor(), PFMT64u, PFMT64x, pj_a(), pj_end(), pj_k(), pj_ki(), pj_kn(), pj_o(), RZ_ANALYSIS_DIFF_TYPE_MATCH, RZ_ANALYSIS_DIFF_TYPE_UNMATCH, rz_base64_encode_dyn(), rz_config_get(), rz_config_get_i(), rz_config_hold_free(), rz_config_hold_i(), rz_config_hold_new(), rz_config_set_i(), rz_cons_printf(), rz_cons_singleton(), RZ_CORE_ANALYSIS_GRAPHDIFF, RZ_CORE_ANALYSIS_JSON, RZ_CORE_ANALYSIS_JSON_FORMAT_DISASM, RZ_CORE_ANALYSIS_KEYVALUE, RZ_CORE_ANALYSIS_STAR, rz_core_cmd_strf(), rz_core_print_disasm(), rz_core_print_disasm_json(), rz_debug_trace_get(), rz_diff_free(), rz_diff_lines_new(), rz_diff_unified_text(), rz_io_read_at(), RZ_OUTPUT_MODE_JSON, rz_str_cpy, rz_str_prepend(), rz_str_replace(), sdb_array_push_num(), sdb_num_set(), sdb_set(), rz_analysis_bb_t::size, snprintf, cmd_descs_generate::str, rz_analysis_bb_t::switch_op, rz_debug_tracepoint_t::times, rz_analysis_bb_t::traced, rz_analysis_diff_t::type, UT64_MAX, and rz_analysis_case_obj_t::value.

Referenced by core_analysis_graph_nodes().

◆ core_analysis_graph_label()

static char* core_analysis_graph_label ( RzCore core,
RzAnalysisBlock bb,
int  opts 
)
static

Definition at line 1453 of file canalysis.c.

1453  {
1454  int is_html = rz_cons_singleton()->is_html;
1455  int is_json = opts & RZ_CORE_ANALYSIS_JSON;
1456  char cmd[1024], file[1024], *cmdstr = NULL, *filestr = NULL, *str = NULL;
1457  int line = 0, oline = 0, idx = 0;
1458  ut64 at;
1459 
1460  if (opts & RZ_CORE_ANALYSIS_GRAPHLINES) {
1461  for (at = bb->addr; at < bb->addr + bb->size; at += 2) {
1462  rz_bin_addr2line(core->bin, at, file, sizeof(file) - 1, &line);
1463  if (line != 0 && line != oline && strcmp(file, "??")) {
1464  filestr = rz_file_slurp_line(file, line, 0);
1465  if (filestr) {
1466  int flen = strlen(filestr);
1467  cmdstr = realloc(cmdstr, idx + flen + 8);
1468  memcpy(cmdstr + idx, filestr, flen);
1469  idx += flen;
1470  if (is_json) {
1471  strcpy(cmdstr + idx, "\\n");
1472  idx += 2;
1473  } else if (is_html) {
1474  strcpy(cmdstr + idx, "<br />");
1475  idx += 6;
1476  } else {
1477  strcpy(cmdstr + idx, "\\l");
1478  idx += 2;
1479  }
1480  free(filestr);
1481  }
1482  }
1483  oline = line;
1484  }
1485  } else if (opts & RZ_CORE_ANALYSIS_STAR) {
1486  snprintf(cmd, sizeof(cmd), "pdb %" PFMT64u " @ 0x%08" PFMT64x, bb->size, bb->addr);
1487  str = rz_core_cmd_str(core, cmd);
1488  } else if (opts & RZ_CORE_ANALYSIS_GRAPHBODY) {
1489  const int scrColor = rz_config_get_i(core->config, "scr.color");
1490  const bool scrUtf8 = rz_config_get_b(core->config, "scr.utf8");
1491  rz_config_set_i(core->config, "scr.color", COLOR_MODE_DISABLED);
1492  rz_config_set(core->config, "scr.utf8", "false");
1493  snprintf(cmd, sizeof(cmd), "pD %" PFMT64u " @ 0x%08" PFMT64x, bb->size, bb->addr);
1494  cmdstr = rz_core_cmd_str(core, cmd);
1495  rz_config_set_i(core->config, "scr.color", scrColor);
1496  rz_config_set_i(core->config, "scr.utf8", scrUtf8);
1497  }
1498  if (cmdstr) {
1500  free(cmdstr);
1501  }
1502  return str;
1503 }
#define cmdstr(x)
RZ_API char * rz_core_cmd_str(RzCore *core, const char *cmd)
Executes a rizin command and returns the stdout as a string.
Definition: cmd.c:5513
RZ_API RzConfigNode * rz_config_set(RzConfig *cfg, RZ_NONNULL const char *name, const char *value)
Definition: config.c:267
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags cmd
Definition: sflib.h:79
RZ_DEPRECATE RZ_API bool rz_bin_addr2line(RzBin *bin, ut64 addr, char *file, int len, int *line)
Definition: dbginfo.c:194
void * realloc(void *ptr, size_t size)
Definition: malloc.c:144
line
Definition: setup.py:34
int idx
Definition: setup.py:197
@ COLOR_MODE_DISABLED
Definition: rz_cons.h:442
#define RZ_CORE_ANALYSIS_GRAPHBODY
Definition: rz_core.h:50
#define RZ_CORE_ANALYSIS_GRAPHLINES
Definition: rz_core.h:49
RZ_API bool RZ_API char * rz_file_slurp_line(const char *file, int line, int context)
Definition: file.c:673
RZ_API char * rz_str_escape_dot(const char *buf)
Definition: str.c:1587
Definition: gzappend.c:170

References addr, rz_analysis_bb_t::addr, rz_core_t::bin, cmd, cmdstr, COLOR_MODE_DISABLED, rz_core_t::config, free(), setup::idx, rz_cons_t::is_html, setup::line, memcpy(), NULL, PFMT64u, PFMT64x, realloc(), rz_bin_addr2line(), rz_config_get_b(), rz_config_get_i(), rz_config_set(), rz_config_set_i(), rz_cons_singleton(), RZ_CORE_ANALYSIS_GRAPHBODY, RZ_CORE_ANALYSIS_GRAPHLINES, RZ_CORE_ANALYSIS_JSON, RZ_CORE_ANALYSIS_STAR, rz_core_cmd_str(), rz_file_slurp_line(), rz_str_escape_dot(), rz_analysis_bb_t::size, snprintf, cmd_descs_generate::str, and ut64().

Referenced by core_analysis_graph_construct_nodes().

◆ core_analysis_graph_nodes()

static int core_analysis_graph_nodes ( RzCore core,
RzAnalysisFunction fcn,
int  opts,
PJ pj 
)
static

Definition at line 1906 of file canalysis.c.

1906  {
1907  rz_return_val_if_fail(fcn && fcn->bbs, -1);
1908  int is_json = opts & RZ_CORE_ANALYSIS_JSON;
1909  int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
1910  int nodes = 0;
1911  Sdb *DB = NULL;
1912  char *pal_jump = palColorFor("graph.true");
1913  char *pal_fail = palColorFor("graph.false");
1914  char *pal_trfa = palColorFor("graph.ujump");
1915  char *pal_curr = palColorFor("graph.current");
1916  char *pal_traced = palColorFor("graph.traced");
1917  char *pal_box4 = palColorFor("graph.box4");
1918 
1919  if (is_keva) {
1920  char ns[64];
1921  DB = sdb_ns(core->analysis->sdb, "graph", 1);
1922  snprintf(ns, sizeof(ns), "fcn.0x%08" PFMT64x, fcn->addr);
1923  DB = sdb_ns(DB, ns, 1);
1924  }
1925 
1926  if (is_keva) {
1927  char *ename = sdb_encode((const ut8 *)fcn->name, -1);
1928  sdb_set(DB, "name", fcn->name, 0);
1929  sdb_set(DB, "ename", ename, 0);
1930  free(ename);
1932  if (fcn->maxstack > 0) {
1933  sdb_num_set(DB, "stack", fcn->maxstack, 0);
1934  }
1935  sdb_set(DB, "pos", "0,0", 0); // needs to run layout
1936  sdb_set(DB, "type", rz_analysis_fcntype_tostring(fcn->type), 0);
1937  } else if (is_json) {
1938  // TODO: show vars, refs and xrefs
1939  char *fcn_name_escaped = rz_str_escape_utf8_for_json(fcn->name, -1);
1940  pj_o(pj);
1941  pj_ks(pj, "name", rz_str_get_null(fcn_name_escaped));
1942  free(fcn_name_escaped);
1943  pj_kn(pj, "offset", fcn->addr);
1944  pj_ki(pj, "ninstr", fcn->ninstr);
1945  pj_ki(pj, "nargs",
1946  rz_analysis_var_count(core->analysis, fcn, 'r', 1) +
1947  rz_analysis_var_count(core->analysis, fcn, 's', 1) +
1948  rz_analysis_var_count(core->analysis, fcn, 'b', 1));
1949  pj_ki(pj, "nlocals",
1950  rz_analysis_var_count(core->analysis, fcn, 'r', 0) +
1951  rz_analysis_var_count(core->analysis, fcn, 's', 0) +
1952  rz_analysis_var_count(core->analysis, fcn, 'b', 0));
1953  pj_kn(pj, "size", rz_analysis_function_linear_size(fcn));
1954  pj_ki(pj, "stack", fcn->maxstack);
1955  pj_ks(pj, "type", rz_analysis_fcntype_tostring(fcn->type));
1956  pj_k(pj, "blocks");
1957  pj_a(pj);
1958  }
1959  nodes += core_analysis_graph_construct_nodes(core, fcn, opts, pj, DB);
1960  nodes += core_analysis_graph_construct_edges(core, fcn, opts, pj, DB);
1961  if (is_json) {
1962  pj_end(pj);
1963  pj_end(pj);
1964  }
1965  free(pal_jump);
1966  free(pal_fail);
1967  free(pal_trfa);
1968  free(pal_curr);
1969  free(pal_traced);
1970  free(pal_box4);
1971  return nodes;
1972 }
RZ_API char * sdb_encode(const ut8 *bin, int len)
Definition: base64.c:18
static int core_analysis_graph_construct_edges(RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj, Sdb *DB)
Definition: canalysis.c:1525
static int core_analysis_graph_construct_nodes(RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj, Sdb *DB)
Definition: canalysis.c:1654
RZ_API Sdb * sdb_ns(Sdb *s, const char *name, int create)
Definition: ns.c:186
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
Definition: pj.c:170
static const char * rz_str_get_null(const char *str)
Definition: rz_str.h:190
RZ_API char * rz_str_escape_utf8_for_json(const char *s, int len)
Definition: str.c:1834
Definition: sdb.h:63
RZ_API int rz_analysis_var_count(RzAnalysis *a, RzAnalysisFunction *fcn, int kind, int type)
Definition: var.c:574

References rz_analysis_function_t::addr, rz_core_t::analysis, rz_analysis_function_t::bbs, core_analysis_graph_construct_edges(), core_analysis_graph_construct_nodes(), DB, free(), rz_analysis_function_t::maxstack, rz_analysis_function_t::name, rz_analysis_function_t::ninstr, NULL, palColorFor(), PFMT64x, pj_a(), pj_end(), pj_k(), pj_ki(), pj_kn(), pj_ks(), pj_o(), rz_analysis_fcntype_tostring(), rz_analysis_function_linear_size(), rz_analysis_var_count(), RZ_CORE_ANALYSIS_JSON, RZ_CORE_ANALYSIS_KEYVALUE, rz_return_val_if_fail, rz_str_escape_utf8_for_json(), rz_str_get_null(), rz_analysis_t::sdb, sdb_encode(), sdb_ns(), sdb_num_set(), sdb_set(), snprintf, and rz_analysis_function_t::type.

Referenced by rz_core_analysis_graph().

◆ core_search_for_xrefs_in_boundaries()

static bool core_search_for_xrefs_in_boundaries ( RzCore core,
ut64  from,
ut64  to 
)
static

Definition at line 3228 of file canalysis.c.

3228  {
3229  if ((from == UT64_MAX && to == UT64_MAX) ||
3230  (!from && !to) ||
3231  (to - from > rz_io_size(core->io))) {
3232  return false;
3233  }
3234  return rz_core_analysis_search_xrefs(core, from, to) > 0;
3235 }
RZ_API int rz_core_analysis_search_xrefs(RZ_NONNULL RzCore *core, ut64 from, ut64 to)
Searches for xrefs in the range of the paramters 'from' and 'to'.
Definition: canalysis.c:3380
RZ_API ut64 rz_io_size(RzIO *io)
Definition: io.c:399

References from, rz_core_t::io, rz_core_analysis_search_xrefs(), rz_io_size(), to, and UT64_MAX.

Referenced by rz_core_analysis_refs().

◆ delta_for_access()

static ut64 delta_for_access ( RzAnalysisOp op,
RzAnalysisVarAccessType  type 
)
static

Definition at line 4157 of file canalysis.c.

4157  {
4159  if (op->dst) {
4160  return op->dst->imm + op->dst->delta;
4161  }
4162  } else {
4163  if (op->src[1] && (op->src[1]->imm || op->src[1]->delta)) {
4164  return op->src[1]->imm + op->src[1]->delta;
4165  }
4166  if (op->src[0]) {
4167  return op->src[0]->imm + op->src[0]->delta;
4168  }
4169  }
4170  return 0;
4171 }
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE
Definition: rz_analysis.h:714

References RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE, and type.

Referenced by handle_var_stack_access().

◆ esilbreak_mem_read()

static int esilbreak_mem_read ( RzAnalysisEsil esil,
ut64  addr,
ut8 buf,
int  len 
)
static

resolve ptr

Definition at line 4211 of file canalysis.c.

4211  {
4212  RzCore *core = esil->analysis->coreb.core;
4213  ut8 str[128];
4214  if (addr != UT64_MAX) {
4216  }
4218  if (myvalid(core->io, addr) && rz_io_read_at(core->io, addr, (ut8 *)buf, len)) {
4219  ut64 refptr;
4220  bool trace = true;
4221  switch (len) {
4222  case 2:
4224  break;
4225  case 4:
4227  break;
4228  case 8:
4230  break;
4231  default:
4232  trace = false;
4233  rz_io_read_at(core->io, addr, (ut8 *)buf, len);
4234  break;
4235  }
4236  // TODO incorrect
4237  bool validRef = false;
4238  if (trace && myvalid(core->io, refptr)) {
4239  if (ntarget == UT64_MAX || ntarget == refptr) {
4240  str[0] = 0;
4241  if (rz_io_read_at(core->io, refptr, str, sizeof(str)) < 1) {
4242  // eprintf ("Invalid read\n");
4243  str[0] = 0;
4244  validRef = false;
4245  } else {
4247  str[sizeof(str) - 1] = 0;
4248  add_string_ref(core, esil->address, refptr);
4250  validRef = true;
4251  }
4252  }
4253  }
4254 
4256  if (ntarget == UT64_MAX || ntarget == addr || (ntarget == UT64_MAX && !validRef)) {
4258  }
4259  }
4260  return 0; // fallback
4261 }
static ut64 ntarget
Definition: canalysis.c:4208
static void add_string_ref(RzCore *core, ut64 xref_from, ut64 xref_to)
Definition: canalysis.c:4102
static ut64 esilbreak_last_read
Definition: canalysis.c:4205
static void handle_var_stack_access(RzAnalysisEsil *esil, ut64 addr, RzAnalysisVarAccessType type, int len)
Definition: canalysis.c:4173
static ut64 esilbreak_last_data
Definition: canalysis.c:4206
static bool myvalid(RzIO *io, ut64 addr)
Definition: canalysis.c:4124
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_READ
Definition: rz_analysis.h:713
static ut64 rz_read_ble64(const void *src, bool big_endian)
Definition: rz_endian.h:501
static ut32 rz_read_ble32(const void *src, bool big_endian)
Definition: rz_endian.h:497
static ut16 rz_read_ble16(const void *src, bool big_endian)
Definition: rz_endian.h:493
RzAnalysis * analysis
Definition: rz_analysis.h:1043
RzCoreBind coreb
Definition: rz_analysis.h:580
void * core
Definition: rz_bind.h:31

References add_string_ref(), addr, rz_analysis_esil_t::address, rz_analysis_esil_t::analysis, rz_core_t::analysis, rz_analysis_t::big_endian, rz_core_bind_t::core, rz_analysis_t::coreb, esilbreak_last_data, esilbreak_last_read, handle_var_stack_access(), rz_core_t::io, len, myvalid(), ntarget, RZ_ANALYSIS_VAR_ACCESS_TYPE_READ, RZ_ANALYSIS_XREF_TYPE_DATA, rz_analysis_xrefs_set(), rz_io_read_at(), rz_read_ble16(), rz_read_ble32(), rz_read_ble64(), cmd_descs_generate::str, ut64(), and UT64_MAX.

Referenced by rz_core_analysis_esil().

◆ esilbreak_mem_write()

static int esilbreak_mem_write ( RzAnalysisEsil esil,
ut64  addr,
const ut8 buf,
int  len 
)
static

Definition at line 4199 of file canalysis.c.

4199  {
4201  return 1;
4202 }

References addr, handle_var_stack_access(), len, and RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE.

Referenced by rz_core_analysis_esil().

◆ esilbreak_reg_write()

static int esilbreak_reg_write ( RzAnalysisEsil esil,
const char *  name,
ut64 val 
)
static

Definition at line 4263 of file canalysis.c.

4263  {
4264  if (!esil) {
4265  return 0;
4266  }
4267  RzAnalysis *analysis = esil->analysis;
4268  EsilBreakCtx *ctx = esil->user;
4269  RzAnalysisOp *op = ctx->op;
4270  RzCore *core = analysis->coreb.core;
4272  // specific case to handle blx/bx cases in arm through emulation
4273  // XXX this thing creates a lot of false positives
4274  ut64 at = *val;
4275  if (analysis && analysis->opt.armthumb) {
4276  if (analysis->cur && analysis->cur->arch && analysis->bits < 33 &&
4277  strstr(analysis->cur->arch, "arm") && !strcmp(name, "pc") && op) {
4278  switch (op->type) {
4279  case RZ_ANALYSIS_OP_TYPE_RCALL: // BLX
4280  case RZ_ANALYSIS_OP_TYPE_RJMP: // BX
4281  // maybe UJMP/UCALL is enough here
4282  if (!(*val & 1)) {
4283  rz_analysis_hint_set_bits(analysis, *val, 32);
4284  } else {
4285  ut64 snv = rz_reg_getv(analysis->reg, "pc");
4286  if (snv != UT32_MAX && snv != UT64_MAX) {
4287  if (rz_io_is_valid_offset(analysis->iob.io, *val, 1)) {
4288  rz_analysis_hint_set_bits(analysis, *val - 1, 16);
4289  }
4290  }
4291  }
4292  break;
4293  default:
4294  break;
4295  }
4296  }
4297  }
4298  if (core->rasm->bits == 32 && strstr(core->rasm->cur->name, "arm")) {
4299  if ((!(at & 1)) && rz_io_is_valid_offset(analysis->iob.io, at, 0)) { // !core->analysis->opt.noncode)) {
4300  add_string_ref(analysis->coreb.core, esil->address, at);
4301  }
4302  }
4303  return 0;
4304 }
RZ_API void rz_analysis_hint_set_bits(RzAnalysis *a, ut64 addr, int bits)
Definition: hint.c:288
RZ_API ut64 rz_reg_getv(RzReg *reg, const char *name)
Definition: reg.c:332
@ RZ_ANALYSIS_VAR_ACCESS_TYPE_PTR
Definition: rz_analysis.h:712
@ RZ_ANALYSIS_OP_TYPE_RJMP
Definition: rz_analysis.h:370
@ RZ_ANALYSIS_OP_TYPE_RCALL
Definition: rz_analysis.h:380
#define UT32_MAX
Definition: rz_types_base.h:99
RzIOBind iob
Definition: rz_analysis.h:574
RzIO * io
Definition: rz_io.h:232

References add_string_ref(), rz_analysis_esil_t::address, rz_analysis_esil_t::analysis, rz_analysis_plugin_t::arch, rz_analysis_options_t::armthumb, rz_analysis_t::bits, rz_asm_t::bits, rz_core_bind_t::core, rz_analysis_t::coreb, rz_analysis_t::cur, rz_asm_t::cur, handle_var_stack_access(), rz_io_bind_t::io, rz_analysis_t::iob, rz_analysis_t::opt, rz_core_t::rasm, rz_analysis_t::reg, rz_analysis_hint_set_bits(), RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_RJMP, RZ_ANALYSIS_VAR_ACCESS_TYPE_PTR, rz_io_is_valid_offset(), rz_reg_getv(), rz_analysis_esil_t::user, UT32_MAX, ut64(), UT64_MAX, and val.

Referenced by rz_core_analysis_esil().

◆ fcn_cmpaddr()

RZ_IPI int fcn_cmpaddr ( const void *  _a,
const void *  _b 
)

Definition at line 40 of file canalysis.c.

40  {
41  const RzAnalysisFunction *a = _a, *b = _b;
42  return (a->addr > b->addr) - (a->addr < b->addr);
43 }

References a, and b.

Referenced by rz_analysis_function_list_ascii_handler().

◆ find_bb()

static int find_bb ( ut64 addr,
RzAnalysisBlock bb 
)
static

Definition at line 4415 of file canalysis.c.

4415  {
4416  return *addr != bb->addr;
4417 }

References addr, and rz_analysis_bb_t::addr.

Referenced by get_next_i().

◆ find_block_at_xref_addr()

static RzAnalysisBlock* find_block_at_xref_addr ( RzCore core,
ut64  addr 
)
static

Definition at line 5500 of file canalysis.c.

5500  {
5502  if (!blocks) {
5503  return NULL;
5504  }
5505  RzAnalysisBlock *block = NULL;
5506  RzListIter *bit;
5507  RzAnalysisBlock *block_cur;
5508  rz_list_foreach (blocks, bit, block_cur) {
5509  if (rz_analysis_block_op_starts_at(block_cur, addr)) {
5510  block = block_cur;
5511  break;
5512  }
5513  }
5514  if (block) {
5515  rz_analysis_block_ref(block);
5516  }
5518  return block;
5519 }
RZ_API void rz_analysis_block_ref(RzAnalysisBlock *bb)
Definition: block.c:40
RZ_API RzList * rz_analysis_get_blocks_in(RzAnalysis *analysis, ut64 addr)
Definition: block.c:133
RZ_API bool rz_analysis_block_op_starts_at(RzAnalysisBlock *bb, ut64 addr)
Definition: block.c:582
RzCryptoSelector bit
Definition: crypto.c:16
uint64_t blocks
Definition: list.c:104

References addr, rz_core_t::analysis, bit, blocks, NULL, rz_analysis_block_op_starts_at(), rz_analysis_block_ref(), rz_analysis_get_blocks_in(), and rz_list_free().

Referenced by process_reference_noreturn_cb(), and rz_core_analysis_propagate_noreturn().

◆ find_sym_flag()

static int find_sym_flag ( const void *  a1,
const void *  a2 
)
static

Definition at line 2005 of file canalysis.c.

2005  {
2006  const RzFlagItem *f = (const RzFlagItem *)a2;
2007  return f->space && !strcmp(f->space->name, RZ_FLAGS_FS_SYMBOLS) ? 0 : 1;
2008 }
#define RZ_FLAGS_FS_SYMBOLS
Definition: rz_core.h:67

References f, and RZ_FLAGS_FS_SYMBOLS.

Referenced by is_skippable_addr().

◆ function_rename()

static void function_rename ( RzFlag flags,
RzAnalysisFunction fcn 
)
static

Definition at line 755 of file canalysis.c.

755  {
756  const char *locname = "loc.";
757  const size_t locsize = strlen(locname);
758  char *fcnname = fcn->name;
759 
760  if (strncmp(fcn->name, locname, locsize) == 0) {
761  const char *fcnpfx, *restofname;
762  RzFlagItem *f;
763 
765  fcnpfx = rz_analysis_fcntype_tostring(fcn->type);
766  restofname = fcn->name + locsize;
767  fcn->name = rz_str_newf("%s.%s", fcnpfx, restofname);
768 
769  f = rz_flag_get_i(flags, fcn->addr);
770  rz_flag_rename(flags, f, fcn->name);
771 
772  free(fcnname);
773  }
774 }
RZ_API int rz_flag_rename(RzFlag *f, RzFlagItem *item, const char *name)
Definition: flag.c:587
@ RZ_ANALYSIS_FCN_TYPE_FCN
Definition: rz_analysis.h:193

References rz_analysis_function_t::addr, f, flags, free(), rz_analysis_function_t::name, RZ_ANALYSIS_FCN_TYPE_FCN, rz_analysis_fcntype_tostring(), rz_flag_get_i(), rz_flag_rename(), rz_str_newf(), and rz_analysis_function_t::type.

Referenced by rz_core_analysis_fcn().

◆ get_next_i()

static bool get_next_i ( IterCtx ctx,
size_t next_i 
)
inlinestatic

Definition at line 4419 of file canalysis.c.

4419  {
4420  (*next_i)++;
4421  ut64 cur_addr = *next_i + ctx->start_addr;
4422  if (ctx->fcn) {
4423  if (!ctx->cur_bb) {
4424  ctx->path = rz_list_new();
4425  ctx->switch_path = rz_list_new();
4426  ctx->bbl = rz_list_clone(ctx->fcn->bbs);
4427  ctx->cur_bb = rz_analysis_get_block_at(ctx->fcn->analysis, ctx->fcn->addr);
4428  rz_list_push(ctx->path, ctx->cur_bb);
4429  }
4430  RzAnalysisBlock *bb = ctx->cur_bb;
4431  if (cur_addr >= bb->addr + bb->size) {
4432  rz_reg_arena_push(ctx->fcn->analysis->reg);
4433  RzListIter *bbit = NULL;
4434  if (bb->switch_op) {
4436  bbit = rz_list_find(ctx->bbl, &cop->jump, (RzListComparator)find_bb);
4437  if (bbit) {
4438  rz_list_push(ctx->switch_path, bb->switch_op->cases->head);
4439  }
4440  } else {
4441  bbit = rz_list_find(ctx->bbl, &bb->jump, (RzListComparator)find_bb);
4442  if (!bbit && bb->fail != UT64_MAX) {
4443  bbit = rz_list_find(ctx->bbl, &bb->fail, (RzListComparator)find_bb);
4444  }
4445  }
4446  if (!bbit) {
4447  RzListIter *cop_it = rz_list_last(ctx->switch_path);
4448  RzAnalysisBlock *prev_bb = NULL;
4449  do {
4450  rz_reg_arena_pop(ctx->fcn->analysis->reg);
4451  prev_bb = rz_list_pop(ctx->path);
4452  if (prev_bb->fail != UT64_MAX) {
4453  bbit = rz_list_find(ctx->bbl, &prev_bb->fail, (RzListComparator)find_bb);
4454  if (bbit) {
4455  rz_reg_arena_push(ctx->fcn->analysis->reg);
4456  rz_list_push(ctx->path, prev_bb);
4457  }
4458  }
4459  if (!bbit && cop_it) {
4460  RzAnalysisCaseOp *cop = cop_it->data;
4461  if (cop->jump == prev_bb->addr && cop_it->n) {
4462  cop = cop_it->n->data;
4463  rz_list_pop(ctx->switch_path);
4464  rz_list_push(ctx->switch_path, cop_it->n);
4465  cop_it = cop_it->n;
4466  bbit = rz_list_find(ctx->bbl, &cop->jump, (RzListComparator)find_bb);
4467  }
4468  }
4469  if (cop_it && !cop_it->n) {
4470  rz_list_pop(ctx->switch_path);
4471  cop_it = rz_list_last(ctx->switch_path);
4472  }
4473  } while (!bbit && !rz_list_empty(ctx->path));
4474  }
4475  if (!bbit) {
4476  rz_list_free(ctx->path);
4477  rz_list_free(ctx->switch_path);
4478  rz_list_free(ctx->bbl);
4479  return false;
4480  }
4481  ctx->cur_bb = bbit->data;
4482  rz_list_push(ctx->path, ctx->cur_bb);
4483  rz_list_delete(ctx->bbl, bbit);
4484  *next_i = ctx->cur_bb->addr - ctx->start_addr;
4485  }
4486  } else if (cur_addr >= ctx->end_addr) {
4487  return false;
4488  }
4489  return true;
4490 }
RZ_API int rz_reg_arena_push(RzReg *reg)
Definition: arena.c:236
RZ_API void rz_reg_arena_pop(RzReg *reg)
Definition: arena.c:216
RZ_API RzAnalysisBlock * rz_analysis_get_block_at(RzAnalysis *analysis, ut64 addr)
Definition: block.c:90
static int find_bb(ut64 *addr, RzAnalysisBlock *bb)
Definition: canalysis.c:4415
RZ_API RZ_BORROW RzListIter * rz_list_find(RZ_NONNULL const RzList *list, const void *p, RZ_NONNULL RzListComparator cmp)
Returns RzListIter element which matches via the RzListComparator.
Definition: list.c:620
RZ_API void rz_list_delete(RZ_NONNULL RzList *list, RZ_NONNULL RzListIter *iter)
Removes an entry in the list by using the RzListIter pointer.
Definition: list.c:162
RZ_API RZ_OWN RzList * rz_list_clone(RZ_NONNULL const RzList *list)
Shallow copies of the list (but doesn't free its elements)
Definition: list.c:496
RZ_API RZ_BORROW void * rz_list_last(RZ_NONNULL const RzList *list)
Returns the last element of the list.
Definition: list.c:86
RZ_API RZ_BORROW RzListIter * rz_list_push(RZ_NONNULL RzList *list, void *item)
Alias for rz_list_append.
Definition: list.c:60
int(* RzListComparator)(const void *value, const void *list_data)
Definition: rz_list.h:33
struct rz_list_iter_t * n
Definition: rz_list.h:15
void * data
Definition: rz_list.h:14
RzListIter * head
Definition: rz_list.h:19

References rz_analysis_bb_t::addr, rz_analysis_switch_obj_t::cases, rz_list_iter_t::data, rz_analysis_bb_t::fail, find_bb(), rz_list_t::head, rz_analysis_case_obj_t::jump, rz_analysis_bb_t::jump, rz_list_iter_t::n, NULL, rz_analysis_get_block_at(), rz_list_clone(), rz_list_delete(), rz_list_find(), rz_list_first(), rz_list_free(), rz_list_last(), rz_list_new(), rz_list_pop(), rz_list_push(), rz_reg_arena_pop(), rz_reg_arena_push(), rz_analysis_bb_t::size, rz_analysis_bb_t::switch_op, ut64(), and UT64_MAX.

Referenced by rz_core_analysis_esil().

◆ get_title()

static char* get_title ( ut64  addr)
static

◆ getFunctionName()

static char* getFunctionName ( RzCore core,
ut64  addr 
)
static

Definition at line 45 of file canalysis.c.

45  {
46  RzBinFile *bf = rz_bin_cur(core->bin);
47  if (bf && bf->o) {
48  RzBinSymbol *sym = ht_up_find(bf->o->addrzklassmethod, addr, NULL);
49  if (sym && sym->classname && sym->name) {
50  return rz_str_newf("method.%s.%s", sym->classname, sym->name);
51  }
52  }
54  return (flag && flag->name) ? strdup(flag->name) : NULL;
55 }
RZ_API RzBinFile * rz_bin_cur(RzBin *bin)
Definition: bin.c:895
XX curplugin == o->plugin.
Definition: rz_bin.h:298
RzBinObject * o
Definition: rz_bin.h:305
HtUP * addrzklassmethod
Definition: rz_bin.h:292
char * classname
Definition: rz_bin.h:678

References addr, rz_bin_object_t::addrzklassmethod, rz_core_t::bin, rz_bin_symbol_t::classname, rz_core_t::flags, rz_bin_symbol_t::name, rz_flag_item_t::name, NULL, rz_bin_file_t::o, rz_bin_cur(), rz_core_flag_get_by_spaces(), rz_str_newf(), and strdup().

Referenced by __core_analysis_fcn().

◆ getFunctionNamePrefix()

static char* getFunctionNamePrefix ( RzCore core,
ut64  off,
const char *  name 
)
static

Definition at line 57 of file canalysis.c.

57  {
58  if (rz_reg_get(core->analysis->reg, name, -1)) {
59  return rz_str_newf("%s.%08" PFMT64x, "fcn", off);
60  }
61  return strdup(name);
62 }
int off
Definition: pal.c:13
RZ_API RzRegItem * rz_reg_get(RzReg *reg, const char *name, int type)
Definition: reg.c:344

References rz_core_t::analysis, off, PFMT64x, rz_analysis_t::reg, rz_reg_get(), rz_str_newf(), and strdup().

Referenced by rz_core_analysis_function_rename().

◆ getpcfromstack()

static void getpcfromstack ( RzCore core,
RzAnalysisEsil esil 
)
static

Definition at line 4306 of file canalysis.c.

4306  {
4307  ut64 cur;
4308  ut64 addr;
4309  ut64 size;
4310  int idx;
4311  RzAnalysisEsil esil_cpy;
4313  RzAnalysisFunction *fcn = NULL;
4314  ut8 *buf = NULL;
4315  char *tmp_esil_str = NULL;
4316  int tmp_esil_str_len;
4317  const char *esilstr;
4318  const int maxaddrlen = 20;
4319  const char *spname = NULL;
4320  if (!esil) {
4321  return;
4322  }
4323 
4324  memcpy(&esil_cpy, esil, sizeof(esil_cpy));
4325  addr = cur = esil_cpy.cur;
4326  fcn = rz_analysis_get_fcn_in(core->analysis, addr, 0);
4327  if (!fcn) {
4328  return;
4329  }
4330 
4332  if (size <= 0) {
4333  return;
4334  }
4335 
4336  buf = malloc(size + 2);
4337  if (!buf) {
4338  perror("malloc");
4339  return;
4340  }
4341 
4342  rz_io_read_at(core->io, addr, buf, size + 1);
4343 
4344  // TODO Hardcoding for 2 instructions (mov e_p,[esp];ret). More work needed
4345  idx = 0;
4346  if (rz_analysis_op(core->analysis, &op, cur, buf + idx, size - idx, RZ_ANALYSIS_OP_MASK_ESIL) <= 0 ||
4347  op.size <= 0 ||
4348  (op.type != RZ_ANALYSIS_OP_TYPE_MOV && op.type != RZ_ANALYSIS_OP_TYPE_CMOV)) {
4349  goto err_analysis_op;
4350  }
4351 
4352  rz_asm_set_pc(core->rasm, cur);
4353  esilstr = RZ_STRBUF_SAFEGET(&op.esil);
4354  if (!esilstr) {
4355  goto err_analysis_op;
4356  }
4357  // Ugly code
4358  // This is a hack, since ESIL doesn't always preserve values pushed on the stack. That probably needs to be rectified
4359  spname = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP);
4360  if (!spname || !*spname) {
4361  goto err_analysis_op;
4362  }
4363  tmp_esil_str_len = strlen(esilstr) + strlen(spname) + maxaddrlen;
4364  tmp_esil_str = (char *)malloc(tmp_esil_str_len);
4365  if (!tmp_esil_str) {
4366  goto err_analysis_op;
4367  }
4368  tmp_esil_str[tmp_esil_str_len - 1] = '\0';
4369  snprintf(tmp_esil_str, tmp_esil_str_len - 1, "%s,[", spname);
4370  if (!*esilstr || (strncmp(esilstr, tmp_esil_str, strlen(tmp_esil_str)))) {
4371  free(tmp_esil_str);
4372  goto err_analysis_op;
4373  }
4374 
4375  snprintf(tmp_esil_str, tmp_esil_str_len - 1, "%20" PFMT64u "%s", esil_cpy.old, &esilstr[strlen(spname) + 4]);
4376  rz_str_trim(tmp_esil_str);
4377  idx += op.size;
4378  rz_analysis_esil_set_pc(&esil_cpy, cur);
4379  rz_analysis_esil_parse(&esil_cpy, tmp_esil_str);
4380  rz_analysis_esil_stack_free(&esil_cpy);
4381  free(tmp_esil_str);
4382 
4383  cur = addr + idx;
4385  if (rz_analysis_op(core->analysis, &op, cur, buf + idx, size - idx, RZ_ANALYSIS_OP_MASK_ESIL) <= 0 ||
4386  op.size <= 0 ||
4387  (op.type != RZ_ANALYSIS_OP_TYPE_RET && op.type != RZ_ANALYSIS_OP_TYPE_CRET)) {
4388  goto err_analysis_op;
4389  }
4390  rz_asm_set_pc(core->rasm, cur);
4391 
4392  esilstr = RZ_STRBUF_SAFEGET(&op.esil);
4393  rz_analysis_esil_set_pc(&esil_cpy, cur);
4394  if (!esilstr || !*esilstr) {
4395  goto err_analysis_op;
4396  }
4397  rz_analysis_esil_parse(&esil_cpy, esilstr);
4398  rz_analysis_esil_stack_free(&esil_cpy);
4399 
4400  memcpy(esil, &esil_cpy, sizeof(esil_cpy));
4401 
4402 err_analysis_op:
4404  free(buf);
4405 }
RZ_API int rz_asm_set_pc(RzAsm *a, ut64 pc)
Definition: asm.c:533
RZ_API void rz_analysis_esil_stack_free(RzAnalysisEsil *esil)
Definition: esil.c:3103
RZ_API bool rz_analysis_esil_set_pc(RzAnalysisEsil *esil, ut64 addr)
Definition: esil.c:155
RZ_API bool rz_analysis_esil_parse(RzAnalysisEsil *esil, const char *str)
Definition: esil.c:2998
RZ_API bool rz_analysis_op_fini(RzAnalysisOp *op)
Definition: op.c:37
RZ_API int rz_analysis_op(RzAnalysis *analysis, RzAnalysisOp *op, ut64 addr, const ut8 *data, int len, RzAnalysisOpMask mask)
Definition: op.c:96
RZ_API const char * rz_reg_get_name(RzReg *reg, int role)
Definition: reg.c:147
@ RZ_ANALYSIS_OP_TYPE_CMOV
Definition: rz_analysis.h:391
@ RZ_ANALYSIS_OP_TYPE_CRET
Definition: rz_analysis.h:386
@ RZ_ANALYSIS_OP_TYPE_MOV
Definition: rz_analysis.h:390
@ RZ_REG_NAME_SP
Definition: rz_reg.h:44
RZ_API void rz_str_trim(RZ_NONNULL RZ_INOUT char *str)
Removes whitespace characters (space, tab, newline etc.) from the beginning and end of a string.
Definition: str_trim.c:190
#define RZ_STRBUF_SAFEGET(sb)
Definition: rz_strbuf.h:18
#define RZ_EMPTY
Definition: rz_types_base.h:68

References addr, rz_core_t::analysis, rz_analysis_esil_t::cur, free(), setup::idx, rz_core_t::io, malloc(), memcpy(), NULL, rz_analysis_esil_t::old, PFMT64u, rz_core_t::rasm, rz_analysis_t::reg, rz_analysis_esil_parse(), rz_analysis_esil_set_pc(), rz_analysis_esil_stack_free(), rz_analysis_function_linear_size(), rz_analysis_get_fcn_in(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_TYPE_CMOV, RZ_ANALYSIS_OP_TYPE_CRET, RZ_ANALYSIS_OP_TYPE_MOV, RZ_ANALYSIS_OP_TYPE_RET, rz_asm_set_pc(), RZ_EMPTY, rz_io_read_at(), rz_reg_get_name(), RZ_REG_NAME_SP, rz_str_trim(), RZ_STRBUF_SAFEGET, snprintf, and ut64().

Referenced by rz_core_analysis_esil().

◆ handle_var_stack_access()

static void handle_var_stack_access ( RzAnalysisEsil esil,
ut64  addr,
RzAnalysisVarAccessType  type,
int  len 
)
static

Definition at line 4173 of file canalysis.c.

4173  {
4174  EsilBreakCtx *ctx = esil->user;
4175  const char *regname = reg_name_for_access(ctx->op, type);
4176  if (ctx->fcn && regname) {
4177  ut64 spaddr = rz_reg_getv(esil->analysis->reg, ctx->spname);
4178  if (addr >= spaddr && addr < ctx->initial_sp) {
4179  int stack_off = addr - ctx->initial_sp;
4181  if (!var) {
4183  }
4184  if (!var && stack_off >= -ctx->fcn->maxstack) {
4185  char *varname;
4186  varname = ctx->fcn->analysis->opt.varname_stack
4187  ? rz_str_newf("var_%xh", RZ_ABS(stack_off))
4189  var = rz_analysis_function_set_var(ctx->fcn, stack_off, RZ_ANALYSIS_VAR_KIND_SPV, NULL, len, false, varname);
4190  free(varname);
4191  }
4192  if (var) {
4194  }
4195  }
4196  }
4197 }
static const char * reg_name_for_access(RzAnalysisOp *op, RzAnalysisVarAccessType type)
Definition: canalysis.c:4144
static ut64 delta_for_access(RzAnalysisOp *op, RzAnalysisVarAccessType type)
Definition: canalysis.c:4157
@ RZ_ABS
@ RZ_ANALYSIS_VAR_KIND_SPV
Definition: rz_analysis.h:705
RZ_API RZ_OWN char * rz_analysis_function_autoname_var(RzAnalysisFunction *fcn, char kind, const char *pfx, int ptr)
Definition: var.c:633
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_get_var(RzAnalysisFunction *fcn, char kind, int delta)
Definition: var.c:259
RZ_API void rz_analysis_var_set_access(RzAnalysisVar *var, const char *reg, ut64 access_addr, int access_type, st64 stackptr)
Definition: var.c:441
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)
Definition: var.c:111
static char * regname(int reg)
Definition: dis.c:71

References addr, rz_analysis_esil_t::analysis, delta_for_access(), free(), len, NULL, rz_analysis_t::reg, reg_name_for_access(), regname(), RZ_ABS, rz_analysis_function_autoname_var(), rz_analysis_function_get_var(), rz_analysis_function_set_var(), RZ_ANALYSIS_VAR_KIND_BPV, RZ_ANALYSIS_VAR_KIND_SPV, rz_analysis_var_set_access(), rz_reg_getv(), rz_str_newf(), type, rz_analysis_esil_t::user, and ut64().

Referenced by esilbreak_mem_read(), esilbreak_mem_write(), and esilbreak_reg_write().

◆ HEAPTYPE()

HEAPTYPE ( ut64  )

◆ hint_node_cmp()

int hint_node_cmp ( const void *  incoming,
const RBNode in_tree,
void *  user 
)

Definition at line 1334 of file canalysis.c.

1334  {
1335  ut64 ia = *(ut64 *)incoming;
1336  ut64 ta = container_of(in_tree, const HintNode, rb)->addr;
1337  if (ia < ta) {
1338  return -1;
1339  } else if (ia > ta) {
1340  return 1;
1341  }
1342  return 0;
1343 }
#define container_of(ptr, type, member)
Definition: rz_types.h:650

References container_of, and ut64().

Referenced by print_addr_hint_cb(), print_arch_hint_cb(), and print_bits_hint_cb().

◆ hint_node_free()

void hint_node_free ( RBNode node,
void *  user 
)

Definition at line 1330 of file canalysis.c.

1330  {
1331  free(container_of(node, HintNode, rb));
1332 }

References container_of, and free().

Referenced by rz_core_analysis_hint_list_print(), and rz_core_analysis_hint_print().

◆ hint_node_print()

static void hint_node_print ( HintNode node,
RzOutputMode  mode,
PJ pj 
)
static

Definition at line 1176 of file canalysis.c.

1176  {
1177  switch (mode) {
1178  case RZ_OUTPUT_MODE_RIZIN:
1179 #define HINTCMD_ADDR(hint, fmt, x) rz_cons_printf(fmt " @ 0x%" PFMT64x "\n", x, (hint)->addr)
1180  switch (node->type) {
1181  case HINT_NODE_ADDR: {
1184  switch (record->type) {
1186  HINTCMD_ADDR(node, "ahi %d", record->immbase);
1187  break;
1189  HINTCMD_ADDR(node, "ahc 0x%" PFMT64x, record->jump);
1190  break;
1192  HINTCMD_ADDR(node, "ahf 0x%" PFMT64x, record->fail);
1193  break;
1195  HINTCMD_ADDR(node, "ahF 0x%" PFMT64x, record->stackframe);
1196  break;
1198  HINTCMD_ADDR(node, "ahp 0x%" PFMT64x, record->ptr);
1199  break;
1201  // no command for this
1202  break;
1204  HINTCMD_ADDR(node, "ahr 0x%" PFMT64x, record->retval);
1205  break;
1207  // no command for this
1208  break;
1210  HINTCMD_ADDR(node, "ahs 0x%" PFMT64x, record->size);
1211  break;
1213  HINTCMD_ADDR(node, "ahS %s", record->syntax); // TODO: escape for newcmd
1214  break;
1216  const char *type = rz_analysis_optype_to_string(record->optype);
1217  if (type) {
1218  HINTCMD_ADDR(node, "aho %s", type); // TODO: escape for newcmd
1219  }
1220  break;
1221  }
1223  HINTCMD_ADDR(node, "ahd %s", record->opcode);
1224  break;
1226  HINTCMD_ADDR(node, "aht %s", record->type_offset); // TODO: escape for newcmd
1227  break;
1229  HINTCMD_ADDR(node, "ahe %s", record->esil); // TODO: escape for newcmd
1230  break;
1232  rz_cons_printf("ahh @ 0x%" PFMT64x "\n", node->addr);
1233  break;
1235  // no command for this
1236  break;
1237  }
1238  }
1239  break;
1240  }
1241  case HINT_NODE_ARCH:
1242  HINTCMD_ADDR(node, "aha %s", node->arch ? node->arch : "0");
1243  break;
1244  case HINT_NODE_BITS:
1245  HINTCMD_ADDR(node, "ahb %d", node->bits);
1246  break;
1247  }
1248 #undef HINTCMD_ADDR
1249  break;
1250  case RZ_OUTPUT_MODE_JSON:
1251  switch (node->type) {
1252  case HINT_NODE_ADDR: {
1255  switch (record->type) {
1257  pj_ki(pj, "immbase", record->immbase);
1258  break;
1260  pj_kn(pj, "jump", record->jump);
1261  break;
1263  pj_kn(pj, "fail", record->fail);
1264  break;
1266  pj_kn(pj, "stackframe", record->stackframe);
1267  break;
1269  pj_kn(pj, "ptr", record->ptr);
1270  break;
1272  pj_ki(pj, "nword", record->nword);
1273  break;
1275  pj_kn(pj, "ret", record->retval);
1276  break;
1278  pj_ki(pj, "newbits", record->newbits);
1279  break;
1281  pj_kn(pj, "size", record->size);
1282  break;
1284  pj_ks(pj, "syntax", record->syntax);
1285  break;
1287  const char *type = rz_analysis_optype_to_string(record->optype);
1288  if (type) {
1289  pj_ks(pj, "type", type);
1290  }
1291  break;
1292  }
1294  pj_ks(pj, "opcode", record->opcode);
1295  break;
1297  pj_ks(pj, "offset", record->type_offset);
1298  break;
1300  pj_ks(pj, "esil", record->esil);
1301  break;
1303  pj_kb(pj, "high", true);
1304  break;
1306  pj_kn(pj, "val", record->val);
1307  break;
1308  }
1309  }
1310  break;
1311  }
1312  case HINT_NODE_ARCH:
1313  if (node->arch) {
1314  pj_ks(pj, "arch", node->arch);
1315  } else {
1316  pj_knull(pj, "arch");
1317  }
1318  break;
1319  case HINT_NODE_BITS:
1320  pj_ki(pj, "bits", node->bits);
1321  break;
1322  }
1323  break;
1324  default:
1325  print_hint_h_format(node);
1326  break;
1327  }
1328 }
static void print_hint_h_format(HintNode *node)
Definition: canalysis.c:1097
#define HINTCMD_ADDR(hint, fmt, x)
RZ_API const char * rz_analysis_optype_to_string(int type)
Definition: op.c:310
@ RZ_ANALYSIS_ADDR_HINT_TYPE_SYNTAX
Definition: rz_analysis.h:639
@ RZ_ANALYSIS_ADDR_HINT_TYPE_PTR
Definition: rz_analysis.h:634
@ RZ_ANALYSIS_ADDR_HINT_TYPE_SIZE
Definition: rz_analysis.h:638
@ RZ_ANALYSIS_ADDR_HINT_TYPE_STACKFRAME
Definition: rz_analysis.h:633
@ RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH
Definition: rz_analysis.h:644
@ RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL
Definition: rz_analysis.h:643
@ RZ_ANALYSIS_ADDR_HINT_TYPE_NEW_BITS
Definition: rz_analysis.h:637
@ RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET
Definition: rz_analysis.h:642
@ RZ_ANALYSIS_ADDR_HINT_TYPE_JUMP
Definition: rz_analysis.h:631
@ RZ_ANALYSIS_ADDR_HINT_TYPE_OPTYPE
Definition: rz_analysis.h:640
@ RZ_ANALYSIS_ADDR_HINT_TYPE_RET
Definition: rz_analysis.h:636
@ RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE
Definition: rz_analysis.h:630
@ RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD
Definition: rz_analysis.h:635
@ RZ_ANALYSIS_ADDR_HINT_TYPE_FAIL
Definition: rz_analysis.h:632
@ RZ_ANALYSIS_ADDR_HINT_TYPE_OPCODE
Definition: rz_analysis.h:641
@ RZ_ANALYSIS_ADDR_HINT_TYPE_VAL
Definition: rz_analysis.h:645
RZ_API PJ * pj_knull(PJ *j, const char *k)
Definition: pj.c:114
#define rz_vector_foreach(vec, it)
Definition: rz_vector.h:169
const RzVector * addr_hints
Definition: canalysis.c:1091
int bits
Definition: canalysis.c:1093
enum HintNode::@221 type
ut64 addr
Definition: canalysis.c:1084
const char * arch
Definition: canalysis.c:1092
Definition: tar.h:52

References HintNode::addr, HintNode::addr_hints, HintNode::arch, HintNode::bits, HINTCMD_ADDR, PFMT64x, pj_kb(), pj_ki(), pj_kn(), pj_knull(), pj_ks(), print_hint_h_format(), RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL, RZ_ANALYSIS_ADDR_HINT_TYPE_FAIL, RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH, RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE, RZ_ANALYSIS_ADDR_HINT_TYPE_JUMP, RZ_ANALYSIS_ADDR_HINT_TYPE_NEW_BITS, RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD, RZ_ANALYSIS_ADDR_HINT_TYPE_OPCODE, RZ_ANALYSIS_ADDR_HINT_TYPE_OPTYPE, RZ_ANALYSIS_ADDR_HINT_TYPE_PTR, RZ_ANALYSIS_ADDR_HINT_TYPE_RET, RZ_ANALYSIS_ADDR_HINT_TYPE_SIZE, RZ_ANALYSIS_ADDR_HINT_TYPE_STACKFRAME, RZ_ANALYSIS_ADDR_HINT_TYPE_SYNTAX, RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET, RZ_ANALYSIS_ADDR_HINT_TYPE_VAL, rz_analysis_optype_to_string(), rz_cons_printf(), RZ_OUTPUT_MODE_JSON, RZ_OUTPUT_MODE_RIZIN, rz_vector_foreach, type, and HintNode::type.

Referenced by print_hint_tree().

◆ is_apple_target()

static bool is_apple_target ( RzCore core)
static

Definition at line 5765 of file canalysis.c.

5765  {
5766  const char *arch = rz_config_get(core->config, "asm.arch");
5767  if (!strstr(arch, "ppc") && !strstr(arch, "arm") && !strstr(arch, "x86")) {
5768  return false;
5769  }
5770  RzBinObject *bo = rz_bin_cur_object(core->bin);
5771  rz_return_val_if_fail(!bo || (bo->plugin && bo->plugin->name), false);
5772  return bo ? strstr(bo->plugin->name, "mach") : false;
5773 }
RZ_API RzBinObject * rz_bin_cur_object(RzBin *bin)
Definition: bin.c:900
cs_arch arch
Definition: cstool.c:13
#define false
struct rz_bin_plugin_t * plugin
Definition: rz_bin.h:289
char * name
Definition: rz_bin.h:509

References arch, rz_core_t::bin, rz_core_t::config, core_noretl::core, rz_bin_plugin_t::name, rz_bin_object_t::plugin, rz_bin_cur_object(), rz_config_get(), and rz_return_val_if_fail.

Referenced by rz_core_analysis_everything().

◆ is_entry_flag()

static bool is_entry_flag ( RzFlagItem f)
static

Definition at line 809 of file canalysis.c.

809  {
810  return f->space && !strcmp(f->space->name, RZ_FLAGS_FS_SYMBOLS) && rz_str_startswith(f->name, "entry.");
811 }

References f, RZ_FLAGS_FS_SYMBOLS, and rz_str_startswith().

Referenced by __core_analysis_fcn().

◆ is_skippable_addr()

static bool is_skippable_addr ( RzCore core,
ut64  addr 
)
static

Definition at line 2010 of file canalysis.c.

2010  {
2012  if (!fcn) {
2013  return false;
2014  }
2015  if (fcn->addr == addr) {
2016  return true;
2017  }
2018  const RzList *flags = rz_flag_get_list(core->flags, addr);
2019  return !(flags && rz_list_find(flags, fcn, find_sym_flag));
2020 }
static int find_sym_flag(const void *a1, const void *a2)
Definition: canalysis.c:2005
RZ_API const RzList * rz_flag_get_list(RzFlag *f, ut64 off)
Definition: flag.c:475

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, find_sym_flag(), rz_core_t::flags, flags, rz_analysis_get_fcn_in(), rz_flag_get_list(), and rz_list_find().

Referenced by rz_core_analysis_fcn().

◆ is_string()

static int is_string ( const ut8 buf,
int  size,
int len 
)
static

Definition at line 66 of file canalysis.c.

66  {
67  int i, fakeLen = 0;
68  if (size < 1) {
69  return 0;
70  }
71  if (!len) {
72  len = &fakeLen;
73  }
74  if (size > 3 && buf[0] && !buf[1] && buf[2] && !buf[3]) {
75  *len = 1; // XXX: TODO: Measure wide string length
76  return 2; // is wide
77  }
78  for (i = 0; i < size; i++) {
79  if (!buf[i] && i > MINLEN) {
80  *len = i;
81  return 1;
82  }
83  if (buf[i] == 10 || buf[i] == 13 || buf[i] == 9) {
84  continue;
85  }
86  if (buf[i] < 32 || buf[i] > 127) {
87  // not ascii text
88  return 0;
89  }
90  if (!IS_PRINTABLE(buf[i])) {
91  *len = i;
92  return 0;
93  }
94  }
95  *len = i;
96  return 1;
97 }
#define MINLEN
Definition: canalysis.c:65
#define IS_PRINTABLE(x)
Definition: rz_str_util.h:10

References i, IS_PRINTABLE, len, and MINLEN.

Referenced by is_string_at(), and stringAt().

◆ is_string_at()

static char* is_string_at ( RzCore core,
ut64  addr,
int olen 
)
static

Definition at line 99 of file canalysis.c.

99  {
100  ut8 rstr[128] = { 0 };
101  int ret = 0, len = 0;
102  ut8 *str = calloc(256, 1);
103  if (!str) {
104  if (olen) {
105  *olen = 0;
106  }
107  return NULL;
108  }
109  rz_io_read_at(core->io, addr, str, 255);
110 
111  str[255] = 0;
112  if (is_string(str, 256, &len)) {
113  if (olen) {
114  *olen = len;
115  }
116  return (char *)str;
117  }
118 
119  ut64 *cstr = (ut64 *)str;
120  ut64 lowptr = cstr[0];
121  if (lowptr >> 32) { // must be pa mode only
122  lowptr &= UT32_MAX;
123  }
124  // cstring
125  if (cstr[0] == 0 && cstr[1] < 0x1000) {
126  ut64 ptr = cstr[2];
127  if (ptr >> 32) { // must be pa mode only
128  ptr &= UT32_MAX;
129  }
130  if (ptr) {
131  rz_io_read_at(core->io, ptr, rstr, sizeof(rstr));
132  rstr[127] = 0;
133  ret = is_string(rstr, 128, &len);
134  if (ret) {
135  strcpy((char *)str, (char *)rstr);
136  if (olen) {
137  *olen = len;
138  }
139  return (char *)str;
140  }
141  }
142  } else {
143  // pstring
144  rz_io_read_at(core->io, lowptr, rstr, sizeof(rstr));
145  rstr[127] = 0;
146  ret = is_string(rstr, sizeof(rstr), &len);
147  if (ret) {
148  strcpy((char *)str, (char *)rstr);
149  if (olen) {
150  *olen = len;
151  }
152  return (char *)str;
153  }
154  }
155  // check if current section have no exec bit
156  if (len < 1) {
157  ret = 0;
158  free(str);
159  len = -1;
160  } else if (olen) {
161  *olen = len;
162  }
163  // NOTE: coverity says that ret is always 0 here, so str is dead code
164  return ret ? (char *)str : NULL;
165 }
static int is_string(const ut8 *buf, int size, int *len)
Definition: canalysis.c:66
void * calloc(size_t number, size_t size)
Definition: malloc.c:102

References addr, calloc(), free(), rz_core_t::io, is_string(), len, NULL, rz_io_read_at(), cmd_descs_generate::str, UT32_MAX, and ut64().

Referenced by add_string_ref(), rz_core_analysis_esil(), and set_new_xref().

◆ is_unknown_file()

static bool is_unknown_file ( RzCore core)
static

Definition at line 5758 of file canalysis.c.

5758  {
5759  if (core->bin->cur && core->bin->cur->o) {
5760  return (rz_list_empty(core->bin->cur->o->sections));
5761  }
5762  return true;
5763 }
RzList * sections
Definition: rz_bin.h:267
RZ_DEPRECATE RzBinFile * cur
never use this in new code! Get a file from the binfiles list or track it yourself.
Definition: rz_bin.h:330

References rz_core_t::bin, core_noretl::core, rz_bin_t::cur, rz_bin_file_t::o, and rz_bin_object_t::sections.

Referenced by rz_core_analysis_everything().

◆ is_valid_xref()

static bool is_valid_xref ( RzCore core,
ut64  xref_to,
RzAnalysisXRefType  type,
int  cfg_debug 
)
static

Validates a xref. Mainly checks if it points out of the memory map.

Parameters
coreThe rizin core.
xref_toThe target address of the xref.
typeThe xref type.
cfg_debugFlag if debugging configured.
Returns
true xref is valid.
false xref is not valid.

Definition at line 3324 of file canalysis.c.

3324  {
3326  return false;
3327  }
3328  if (cfg_debug) {
3329  if (!rz_debug_map_get(core->dbg, xref_to)) {
3330  return false;
3331  }
3332  } else if (core->io->va) {
3333  if (!rz_io_is_valid_offset(core->io, xref_to, 0)) {
3334  return false;
3335  }
3336  }
3337  return true;
3338 }
RZ_API RzDebugMap * rz_debug_map_get(RzDebug *dbg, ut64 addr)
Definition: dmap.c:65
int va
Definition: rz_io.h:63

References rz_core_t::dbg, rz_core_t::io, RZ_ANALYSIS_XREF_TYPE_NULL, rz_debug_map_get(), rz_io_is_valid_offset(), type, and rz_io_t::va.

Referenced by rz_core_analysis_search_xrefs().

◆ isSkippable()

static bool isSkippable ( RzBinSymbol s)
static

Definition at line 3535 of file canalysis.c.

3535  {
3536  if (s && s->name && s->bind) {
3537  if (rz_str_startswith(s->name, "radr://")) {
3538  return true;
3539  }
3540  if (!strcmp(s->name, "__mh_execute_header")) {
3541  return true;
3542  }
3543  if (!strcmp(s->bind, "NONE")) {
3544  if (s->is_imported && s->libname && strstr(s->libname, ".dll")) {
3545  return true;
3546  }
3547  }
3548  }
3549  return false;
3550 }
static RzSocket * s
Definition: rtr.c:28

References rz_str_startswith(), and s.

Referenced by rz_core_analysis_all().

◆ isValidAddress()

static bool isValidAddress ( RzCore core,
ut64  addr 
)
static

Definition at line 4863 of file canalysis.c.

4863  {
4864  // check if address is mapped
4865  RzIOMap *map = rz_io_map_get(core->io, addr);
4866  if (!map) {
4867  return false;
4868  }
4869  st64 fdsz = (st64)rz_io_fd_size(core->io, map->fd);
4870  if (fdsz > 0 && map->delta > fdsz) {
4871  return false;
4872  }
4873  // check if associated file is opened
4874  RzIODesc *desc = rz_io_desc_get(core->io, map->fd);
4875  if (!desc) {
4876  return false;
4877  }
4878  // check if current map->fd is null://
4879  if (!strncmp(desc->name, "null://", 7)) {
4880  return false;
4881  }
4882  return true;
4883 }
const char * desc
Definition: bin_vsf.c:19
RZ_API ut64 rz_io_fd_size(RzIO *io, int fd)
Definition: io_fd.c:42
RZ_API RzIODesc * rz_io_desc_get(RzIO *io, int fd)
Definition: io_desc.c:73
#define st64
Definition: rz_types_base.h:10

References addr, desc, rz_core_t::io, map(), rz_io_desc_get(), rz_io_fd_size(), rz_io_map_get(), and st64.

Referenced by rz_core_search_value_in_range().

◆ isValidSymbol()

static bool isValidSymbol ( RzBinSymbol symbol)
static

Definition at line 3527 of file canalysis.c.

3527  {
3528  if (symbol && symbol->type) {
3529  const char *type = symbol->type;
3530  return (symbol->paddr != UT64_MAX) && (!strcmp(type, RZ_BIN_TYPE_FUNC_STR) || !strcmp(type, RZ_BIN_TYPE_HIOS_STR) || !strcmp(type, RZ_BIN_TYPE_LOOS_STR) || !strcmp(type, RZ_BIN_TYPE_METH_STR) || !strcmp(type, RZ_BIN_TYPE_STATIC_STR));
3531  }
3532  return false;
3533 }
#define RZ_BIN_TYPE_HIOS_STR
Definition: rz_bin.h:130
#define RZ_BIN_TYPE_METH_STR
Definition: rz_bin.h:122
#define RZ_BIN_TYPE_LOOS_STR
Definition: rz_bin.h:129
#define RZ_BIN_TYPE_STATIC_STR
Definition: rz_bin.h:123

References rz_bin_symbol_t::paddr, RZ_BIN_TYPE_FUNC_STR, RZ_BIN_TYPE_HIOS_STR, RZ_BIN_TYPE_LOOS_STR, RZ_BIN_TYPE_METH_STR, RZ_BIN_TYPE_STATIC_STR, type, rz_bin_symbol_t::type, and UT64_MAX.

Referenced by rz_core_analysis_all().

◆ loganalysis()

static void loganalysis ( ut64  from,
ut64  to,
int  depth 
)
static

Definition at line 30 of file canalysis.c.

30  {
32  eprintf("0x%08" PFMT64x " > 0x%08" PFMT64x " %d\r", from, to, depth);
33 }

References eprintf, from, PFMT64x, rz_cons_clear_line(), and to.

Referenced by __core_analysis_fcn(), and rz_core_analysis_cycles().

◆ myvalid()

static bool myvalid ( RzIO io,
ut64  addr 
)
static

Definition at line 4124 of file canalysis.c.

4124  {
4125  if (addr < 0x100) {
4126  return false;
4127  }
4128  if (addr == UT32_MAX || addr == UT64_MAX) { // the best of the best of the best :(
4129  return false;
4130  }
4131  if (!rz_io_is_valid_offset(io, addr, 0)) {
4132  return false;
4133  }
4134  return true;
4135 }

References addr, rz_io_is_valid_offset(), UT32_MAX, and UT64_MAX.

Referenced by esilbreak_mem_read(), and rz_core_analysis_esil().

◆ next_append()

static ut64* next_append ( ut64 next,
int nexti,
ut64  v 
)
static

Definition at line 636 of file canalysis.c.

636  {
637  ut64 *tmp_next = realloc(next, sizeof(ut64) * (1 + *nexti));
638  if (!tmp_next) {
639  return NULL;
640  }
641  next = tmp_next;
642  next[*nexti] = v;
643  (*nexti)++;
644  return next;
645 }

References NULL, realloc(), ut64(), and v.

Referenced by __core_analysis_fcn().

◆ opiscall()

static bool opiscall ( RzCore core,
RzAnalysisOp aop,
ut64  addr,
const ut8 buf,
int  len,
int  arch 
)
static

Definition at line 3039 of file canalysis.c.

3039  {
3040  switch (arch) {
3041  case RZ_ARCH_ARM64:
3042  aop->size = 4;
3043  // addr should be aligned by 4 in aarch64
3044  if (addr % 4) {
3045  char diff = addr % 4;
3046  addr = addr - diff;
3047  buf = buf - diff;
3048  }
3049  // if is not bl do not analyze
3050  if (buf[3] == 0x94) {
3051  if (rz_analysis_op(core->analysis, aop, addr, buf, len, RZ_ANALYSIS_OP_MASK_BASIC) > 0) {
3052  return true;
3053  }
3054  }
3055  break;
3056  default:
3057  aop->size = 1;
3058  if (rz_analysis_op(core->analysis, aop, addr, buf, len, RZ_ANALYSIS_OP_MASK_BASIC) > 0) {
3059  switch (aop->type & RZ_ANALYSIS_OP_TYPE_MASK) {
3062  return true;
3063  }
3064  }
3065  break;
3066  }
3067  return false;
3068 }
@ RZ_ANALYSIS_OP_TYPE_CCALL
Definition: rz_analysis.h:383

References addr, rz_core_t::analysis, arch, len, rz_analysis_op(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_MASK, RZ_ARCH_ARM64, rz_analysis_op_t::size, and rz_analysis_op_t::type.

Referenced by rz_core_analysis_search().

◆ palColorFor()

static char* palColorFor ( const char *  k)
static

Definition at line 1505 of file canalysis.c.

1505  {
1506  if (!rz_cons_singleton()) {
1507  return NULL;
1508  }
1511 }
const char * k
Definition: dsignal.c:11
RZ_API RzColor rz_cons_pal_get(const char *key)
Definition: pal.c:626
RzColor rcolor
Definition: pal.c:97
RZ_API char * rz_cons_rgb_tostring(ut8 r, ut8 g, ut8 b)
Definition: rgb.c:322
ut8 g
Definition: rz_cons.h:183
ut8 b
Definition: rz_cons.h:184
ut8 r
Definition: rz_cons.h:182

References rcolor_t::b, rcolor_t::g, k, NULL, rcolor_t::r, rcolor, rz_cons_pal_get(), rz_cons_rgb_tostring(), and rz_cons_singleton().

Referenced by core_analysis_color_curr_node(), core_analysis_graph_construct_edges(), core_analysis_graph_construct_nodes(), and core_analysis_graph_nodes().

◆ print_addr_hint_cb()

bool print_addr_hint_cb ( ut64  addr,
const RzVector records,
void *  user 
)

Definition at line 1345 of file canalysis.c.

1345  {
1346  HintNode *node = RZ_NEW0(HintNode);
1347  if (!node) {
1348  return false;
1349  }
1350  node->addr = addr;
1351  node->type = HINT_NODE_ADDR;
1352  node->addr_hints = records;
1353  rz_rbtree_insert(user, &addr, &node->rb, hint_node_cmp, NULL);
1354  return true;
1355 }
int hint_node_cmp(const void *incoming, const RBNode *in_tree, void *user)
Definition: canalysis.c:1334
RZ_API bool rz_rbtree_insert(RBNode **root, void *data, RBNode *node, RBComparator cmp, void *user)
Returns true if the node was inserted successfully.
Definition: rbtree.c:291
#define RZ_NEW0(x)
Definition: rz_types.h:284
RBNode rb
Definition: canalysis.c:1083

References addr, HintNode::addr, HintNode::addr_hints, hint_node_cmp(), NULL, HintNode::rb, RZ_NEW0, rz_rbtree_insert(), and HintNode::type.

Referenced by rz_core_analysis_hint_list_print(), and rz_core_analysis_hint_print().

◆ print_arch_hint_cb()

bool print_arch_hint_cb ( ut64  addr,
RZ_NULLABLE const char *  arch,
void *  user 
)

Definition at line 1357 of file canalysis.c.

1357  {
1358  HintNode *node = RZ_NEW0(HintNode);
1359  if (!node) {
1360  return false;
1361  }
1362  node->addr = addr;
1363  node->type = HINT_NODE_ARCH;
1364  node->arch = arch;
1365  rz_rbtree_insert(user, &addr, &node->rb, hint_node_cmp, NULL);
1366  return true;
1367 }

References addr, HintNode::addr, HintNode::arch, arch, hint_node_cmp(), NULL, HintNode::rb, RZ_NEW0, rz_rbtree_insert(), and HintNode::type.

Referenced by rz_core_analysis_hint_list_print(), and rz_core_analysis_hint_print().

◆ print_bits_hint_cb()

bool print_bits_hint_cb ( ut64  addr,
int  bits,
void *  user 
)

Definition at line 1369 of file canalysis.c.

1369  {
1370  HintNode *node = RZ_NEW0(HintNode);
1371  if (!node) {
1372  return false;
1373  }
1374  node->addr = addr;
1375  node->type = HINT_NODE_BITS;
1376  node->bits = bits;
1377  rz_rbtree_insert(user, &addr, &node->rb, hint_node_cmp, NULL);
1378  return true;
1379 }
int bits(struct state *s, int need)
Definition: blast.c:72

References addr, HintNode::addr, HintNode::bits, bits(), hint_node_cmp(), NULL, HintNode::rb, RZ_NEW0, rz_rbtree_insert(), and HintNode::type.

Referenced by rz_core_analysis_hint_list_print(), and rz_core_analysis_hint_print().

◆ print_hint_h_format()

static void print_hint_h_format ( HintNode node)
static

Definition at line 1097 of file canalysis.c.

1097  {
1098  switch (node->type) {
1099  case HINT_NODE_ADDR: {
1102  switch (record->type) {
1104  rz_cons_printf(" immbase=%d", record->immbase);
1105  break;
1107  rz_cons_printf(" jump=0x%08" PFMT64x, record->jump);
1108  break;
1110  rz_cons_printf(" fail=0x%08" PFMT64x, record->fail);
1111  break;
1113  rz_cons_printf(" stackframe=0x%" PFMT64x, record->stackframe);
1114  break;
1116  rz_cons_printf(" ptr=0x%" PFMT64x, record->ptr);
1117  break;
1119  rz_cons_printf(" nword=%d", record->nword);
1120  break;
1122  rz_cons_printf(" ret=0x%08" PFMT64x, record->retval);
1123  break;
1125  rz_cons_printf(" newbits=%d", record->newbits);
1126  break;
1128  rz_cons_printf(" size=%" PFMT64u, record->size);
1129  break;
1131  rz_cons_printf(" syntax='%s'", record->syntax);
1132  break;
1134  const char *type = rz_analysis_optype_to_string(record->optype);
1135  if (type) {
1136  rz_cons_printf(" type='%s'", type);
1137  }
1138  break;
1139  }
1141  rz_cons_printf(" opcode='%s'", record->opcode);
1142  break;
1144  rz_cons_printf(" offset='%s'", record->type_offset);
1145  break;
1147  rz_cons_printf(" esil='%s'", record->esil);
1148  break;
1150  rz_cons_printf(" high=true");
1151  break;
1153  rz_cons_printf(" val=0x%08" PFMT64x, record->val);
1154  break;
1155  }
1156  }
1157  break;
1158  }
1159  case HINT_NODE_ARCH:
1160  if (node->arch) {
1161  rz_cons_printf(" arch='%s'", node->arch);
1162  } else {
1163  rz_cons_print(" arch=RESET");
1164  }
1165  break;
1166  case HINT_NODE_BITS:
1167  if (node->bits) {
1168  rz_cons_printf(" bits=%d", node->bits);
1169  } else {
1170  rz_cons_print(" bits=RESET");
1171  }
1172  break;
1173  }
1174 }

References HintNode::addr_hints, HintNode::arch, HintNode::bits, PFMT64u, PFMT64x, RZ_ANALYSIS_ADDR_HINT_TYPE_ESIL, RZ_ANALYSIS_ADDR_HINT_TYPE_FAIL, RZ_ANALYSIS_ADDR_HINT_TYPE_HIGH, RZ_ANALYSIS_ADDR_HINT_TYPE_IMMBASE, RZ_ANALYSIS_ADDR_HINT_TYPE_JUMP, RZ_ANALYSIS_ADDR_HINT_TYPE_NEW_BITS, RZ_ANALYSIS_ADDR_HINT_TYPE_NWORD, RZ_ANALYSIS_ADDR_HINT_TYPE_OPCODE, RZ_ANALYSIS_ADDR_HINT_TYPE_OPTYPE, RZ_ANALYSIS_ADDR_HINT_TYPE_PTR, RZ_ANALYSIS_ADDR_HINT_TYPE_RET, RZ_ANALYSIS_ADDR_HINT_TYPE_SIZE, RZ_ANALYSIS_ADDR_HINT_TYPE_STACKFRAME, RZ_ANALYSIS_ADDR_HINT_TYPE_SYNTAX, RZ_ANALYSIS_ADDR_HINT_TYPE_TYPE_OFFSET, RZ_ANALYSIS_ADDR_HINT_TYPE_VAL, rz_analysis_optype_to_string(), rz_cons_printf(), rz_vector_foreach, type, and HintNode::type.

Referenced by hint_node_print().

◆ print_hint_tree()

static void print_hint_tree ( RBTree  tree,
RzCmdStateOutput state 
)
static

Definition at line 1381 of file canalysis.c.

1381  {
1382  PJ *pj = state->mode == RZ_OUTPUT_MODE_JSON ? state->d.pj : NULL;
1383  if (state->mode == RZ_OUTPUT_MODE_JSON) {
1384  pj_a(pj);
1385  }
1386 #define END_ADDR \
1387  if (pj) { \
1388  pj_end(pj); \
1389  } else if (state->mode == RZ_OUTPUT_MODE_STANDARD) { \
1390  rz_cons_newline(); \
1391  }
1392  RBIter it;
1393  HintNode *node;
1394  ut64 last_addr = 0;
1395  bool in_addr = false;
1396  rz_rbtree_foreach (tree, it, node, HintNode, rb) {
1397  if (!in_addr || last_addr != node->addr) {
1398  if (in_addr) {
1399  END_ADDR
1400  }
1401  in_addr = true;
1402  last_addr = node->addr;
1403  if (pj) {
1404  pj_o(pj);
1405  pj_kn(pj, "addr", node->addr);
1406  } else if (state->mode == RZ_OUTPUT_MODE_STANDARD) {
1407  rz_cons_printf(" 0x%08" PFMT64x " =>", node->addr);
1408  }
1409  }
1410  hint_node_print(node, state->mode, pj);
1411  }
1412  if (in_addr) {
1413  END_ADDR
1414  }
1415 #undef BEGIN_ADDR
1416 #undef END_ADDR
1417  if (pj) {
1418  pj_end(pj);
1419  }
1420 }
#define END_ADDR
static void hint_node_print(HintNode *node, RzOutputMode mode, PJ *pj)
Definition: canalysis.c:1176
#define rz_rbtree_foreach(root, it, data, struc, rb)
Definition: rz_rbtree.h:101
Definition: rz_pj.h:12

References HintNode::addr, END_ADDR, hint_node_print(), NULL, PFMT64x, pj_a(), pj_end(), pj_kn(), pj_o(), rz_cons_printf(), RZ_OUTPUT_MODE_JSON, RZ_OUTPUT_MODE_STANDARD, rz_rbtree_foreach, and ut64().

Referenced by rz_core_analysis_hint_list_print(), and rz_core_analysis_hint_print().

◆ printAnalPaths()

static bool printAnalPaths ( RzCoreAnalPaths p,
PJ pj 
)
static

Definition at line 5037 of file canalysis.c.

5037  {
5038  RzListIter *iter;
5040  if (pj) {
5041  pj_a(pj);
5042  } else {
5043  rz_cons_printf("pdb @@= ");
5044  }
5045 
5046  rz_list_foreach (p->path, iter, path) {
5047  if (pj) {
5048  pj_n(pj, path->addr);
5049  } else {
5050  rz_cons_printf("0x%08" PFMT64x " ", path->addr);
5051  }
5052  }
5053 
5054  if (pj) {
5055  pj_end(pj);
5056  } else {
5057  rz_cons_printf("\n");
5058  }
5059  return (p->count < 1 || --p->count > 0);
5060 }
RZ_API PJ * pj_n(PJ *j, ut64 n)
Definition: pj.c:252

References p, path, PFMT64x, pj_a(), pj_end(), pj_n(), and rz_cons_printf().

Referenced by analPaths().

◆ process_reference_noreturn_cb()

static bool process_reference_noreturn_cb ( void *  u,
const ut64  k,
const void *  v 
)
static

Definition at line 5562 of file canalysis.c.

5562  {
5563  RzCore *core = ((struct core_noretl *)u)->core;
5564  RzList *noretl = ((struct core_noretl *)u)->noretl;
5565  SetU *todo = ((struct core_noretl *)u)->todo;
5566  RzAnalysisXRef *xref = (RzAnalysisXRef *)v;
5568  // At first we check if there are any relocations that override the call address
5569  // Note, that the relocation overrides only the part of the instruction
5570  ut64 addr = k;
5571  ut8 buf[CALL_BUF_SIZE] = { 0 };
5572  RzAnalysisOp op = { 0 };
5574  if (rz_analysis_op(core->analysis, &op, addr, buf, core->blocksize, 0) > 0) {
5575  RzBinReloc *rel = rz_core_getreloc(core, addr, op.size);
5576  if (rel) {
5577  // Find the block that has an instruction at exactly the reference addr
5579  if (!block) {
5581  return true;
5582  }
5583  relocation_noreturn_process(core, noretl, todo, block, rel, op.size, addr);
5584  }
5585  }
5587  } else {
5588  RZ_LOG_INFO("analysis: Fail to load %d bytes of data at 0x%08" PFMT64x "\n", CALL_BUF_SIZE, addr);
5589  }
5590  }
5591  return true;
5592 }
static RzAnalysisBlock * find_block_at_xref_addr(RzCore *core, ut64 addr)
Definition: canalysis.c:5500
#define CALL_BUF_SIZE
Definition: canalysis.c:5554
static void relocation_noreturn_process(RzCore *core, RzList *noretl, SetU *todo, RzAnalysisBlock *b, RzBinReloc *rel, ut64 opsize, ut64 addr)
Definition: canalysis.c:5536
RZ_API RzBinReloc * rz_core_getreloc(RzCore *core, ut64 addr, int size)
Definition: core.c:178
#define RZ_LOG_INFO(fmtstr,...)
Definition: rz_log.h:54
HtUP SetU
Definition: set.h:22
RzList * noretl
Definition: canalysis.c:5558
SetU * todo
Definition: canalysis.c:5559
RzCore * core
Definition: canalysis.c:5557
ut32 blocksize
Definition: rz_core.h:303
RzIOReadAt read_at
Definition: rz_io.h:240

References addr, rz_core_t::analysis, rz_core_t::blocksize, CALL_BUF_SIZE, core_noretl::core, find_block_at_xref_addr(), rz_io_bind_t::io, rz_analysis_t::iob, k, core_noretl::noretl, PFMT64x, rz_io_bind_t::read_at, relocation_noreturn_process(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_XREF_TYPE_CALL, RZ_ANALYSIS_XREF_TYPE_CODE, rz_core_getreloc(), RZ_LOG_INFO, core_noretl::todo, rz_analysis_ref_t::type, ut64(), and v.

Referenced by process_refs_cb().

◆ process_refs_cb()

static bool process_refs_cb ( void *  u,
const ut64  k,
const void *  v 
)
static

Definition at line 5594 of file canalysis.c.

5594  {
5595  HtUP *ht = (HtUP *)v;
5596  ht_up_foreach(ht, process_reference_noreturn_cb, u);
5597  return true;
5598 }
static bool process_reference_noreturn_cb(void *u, const ut64 k, const void *v)
Definition: canalysis.c:5562

References process_reference_noreturn_cb(), and v.

Referenced by rz_core_analysis_propagate_noreturn_relocs().

◆ reanalyze_fcns_cb()

static bool reanalyze_fcns_cb ( void *  u,
const ut64  k,
const void *  v 
)
static

Definition at line 5600 of file canalysis.c.

5600  {
5601  RzCore *core = u;
5602  RzAnalysisFunction *fcn = (RzAnalysisFunction *)(size_t)k;
5603  if (fcn->addr && analyze_noreturn_function(core, fcn)) {
5604  fcn->is_noreturn = true;
5606  }
5607  return true;
5608 }
RZ_API bool rz_analysis_noreturn_add(RzAnalysis *analysis, const char *name, ut64 addr)
Definition: analysis.c:466
static bool analyze_noreturn_function(RzCore *core, RzAnalysisFunction *f)
Definition: canalysis.c:5168

References rz_analysis_function_t::addr, rz_core_t::analysis, analyze_noreturn_function(), core_noretl::core, rz_analysis_function_t::is_noreturn, k, NULL, and rz_analysis_noreturn_add().

Referenced by rz_core_analysis_propagate_noreturn_relocs().

◆ recurse()

static RzList* recurse ( RzCore core,
RzAnalysisBlock from,
RzAnalysisBlock dest 
)
static

Definition at line 2683 of file canalysis.c.

2683  {
2684  recurse_bb(core, from->jump, dest);
2685  recurse_bb(core, from->fail, dest);
2686 
2687  /* same for all calls */
2688  // TODO: RzAnalysisBlock must contain a linked list of calls
2689  return NULL;
2690 }
static RzList * recurse_bb(RzCore *core, ut64 addr, RzAnalysisBlock *dest)
Definition: canalysis.c:2692
char * dest
Definition: lz4.h:697

References dest, from, NULL, and recurse_bb().

Referenced by recurse_bb().

◆ recurse_bb()

static RzList * recurse_bb ( RzCore core,
ut64  addr,
RzAnalysisBlock dest 
)
static

Definition at line 2692 of file canalysis.c.

2692  {
2694  if (bb == dest) {
2695  eprintf("path found!");
2696  return NULL;
2697  }
2698  return recurse(core, bb, dest);
2699 }
static RzList * recurse(RzCore *core, RzAnalysisBlock *from, RzAnalysisBlock *dest)
Definition: canalysis.c:2683

References addr, rz_core_t::analysis, dest, eprintf, NULL, recurse(), and rz_analysis_find_most_relevant_block_in().

Referenced by recurse().

◆ reg_name_for_access()

static const char* reg_name_for_access ( RzAnalysisOp op,
RzAnalysisVarAccessType  type 
)
static

Definition at line 4144 of file canalysis.c.

4144  {
4146  if (op->dst && op->dst->reg) {
4147  return op->dst->reg->name;
4148  }
4149  } else {
4150  if (op->src[0] && op->src[0]->reg) {
4151  return op->src[0]->reg->name;
4152  }
4153  }
4154  return NULL;
4155 }

References NULL, RZ_ANALYSIS_VAR_ACCESS_TYPE_WRITE, and type.

Referenced by handle_var_stack_access().

◆ relocation_function_process_noreturn()

static void relocation_function_process_noreturn ( RzCore core,
RzAnalysisBlock b,
SetU todo,
ut64  opsize,
ut64  reladdr,
ut64  addr 
)
static

Definition at line 5521 of file canalysis.c.

5521  {
5522  rz_analysis_noreturn_add(core->analysis, NULL, reladdr);
5523 
5524  // Add all functions that might have become noreturn by this to the todo list to reanalyze them later.
5525  // This must be done before chopping because b might get freed.
5526  RzListIter *it;
5527  RzAnalysisFunction *fcn;
5528  rz_list_foreach (b->fcns, it, fcn) {
5529  set_u_add(todo, (ut64)(size_t)fcn);
5530  }
5531 
5532  // Chop the block
5534 }
RZ_API RzAnalysisBlock * rz_analysis_block_chop_noreturn(RzAnalysisBlock *block, ut64 addr)
Definition: block.c:766
RZ_API void set_u_add(SetU *s, ut64 u)
Definition: set.c:34

References addr, rz_core_t::analysis, b, NULL, rz_analysis_block_chop_noreturn(), rz_analysis_noreturn_add(), set_u_add(), and ut64().

Referenced by relocation_noreturn_process().

◆ relocation_noreturn_process()

static void relocation_noreturn_process ( RzCore core,
RzList noretl,
SetU todo,
RzAnalysisBlock b,
RzBinReloc rel,
ut64  opsize,
ut64  addr 
)
static

Definition at line 5536 of file canalysis.c.

5536  {
5537  RzListIter *iter3;
5538  char *noret;
5539  if (rel->import) {
5540  rz_list_foreach (noretl, iter3, noret) {
5541  if (!strcmp(rel->import->name, noret)) {
5542  relocation_function_process_noreturn(core, b, todo, opsize, rel->vaddr, addr);
5543  }
5544  }
5545  } else if (rel->symbol) {
5546  rz_list_foreach (noretl, iter3, noret) {
5547  if (!strcmp(rel->symbol->name, noret)) {
5548  relocation_function_process_noreturn(core, b, todo, opsize, rel->symbol->vaddr, addr);
5549  }
5550  }
5551  }
5552 }
static void relocation_function_process_noreturn(RzCore *core, RzAnalysisBlock *b, SetU *todo, ut64 opsize, ut64 reladdr, ut64 addr)
Definition: canalysis.c:5521
char * name
Definition: rz_bin.h:701
ut64 vaddr
the vaddr where the value should be patched into
Definition: rz_bin.h:716
RzBinImport * import
Definition: rz_bin.h:714
RzBinSymbol * symbol
Definition: rz_bin.h:713

References addr, b, rz_bin_reloc_t::import, rz_bin_symbol_t::name, rz_bin_import_t::name, relocation_function_process_noreturn(), rz_bin_reloc_t::symbol, rz_bin_symbol_t::vaddr, and rz_bin_reloc_t::vaddr.

Referenced by process_reference_noreturn_cb().

◆ rz_analysis_add_device_peripheral_map()

RZ_API bool rz_analysis_add_device_peripheral_map ( RzBinObject o,
RzAnalysis analysis 
)

Maps the device peripherals as sections.

Gets the ROM_ADDRESS and ROM_SIZE from the corresponding CPU Profile and adds it as a section (RzBinSection) named ".rom" which will appear when you run iS.

Parameters
oreference to RzBinObject
analysisreference to RzAnalysis

Definition at line 6295 of file canalysis.c.

6295  {
6296  rz_return_val_if_fail(o && analysis, false);
6297  if (!o || !analysis) {
6298  return false;
6299  }
6300  ut64 rom_size = analysis->arch_target->profile->rom_size;
6301  ut64 rom_address = analysis->arch_target->profile->rom_address;
6302  if (rom_address == 0 || rom_size == 0) {
6303  return false;
6304  }
6305  if (!o->sections) {
6306  return false;
6307  }
6308  if (rz_list_find(o->sections, ".rom", check_rom_exists)) {
6309  return false;
6310  }
6312  if (!s) {
6313  return false;
6314  }
6315  s->name = strdup(".rom");
6316  s->vaddr = rom_address;
6317  s->vsize = rom_size;
6318  s->size = rom_size;
6319  s->paddr = rom_address;
6320  s->perm = RZ_PERM_RX;
6321  rz_list_append(o->sections, s);
6322  return true;
6323 }
static int check_rom_exists(const void *value, const void *data)
Definition: canalysis.c:6279
#define RZ_PERM_RX
Definition: rz_types.h:97
RzPlatformTarget * arch_target
Definition: rz_analysis.h:622
RzPlatformProfile * profile
Definition: rz_platform.h:34

References rz_analysis_t::arch_target, check_rom_exists(), rz_platform_target_t::profile, rz_platform_profile_t::rom_address, rz_platform_profile_t::rom_size, rz_list_append(), rz_list_find(), RZ_NEW0, RZ_PERM_RX, rz_return_val_if_fail, s, rz_bin_object_t::sections, strdup(), and ut64().

Referenced by rz_core_analysis_everything().

◆ rz_analysis_analyze_fcn_refs()

static int rz_analysis_analyze_fcn_refs ( RzCore core,
RzAnalysisFunction fcn,
int  depth 
)
static

Definition at line 726 of file canalysis.c.

726  {
727  RzListIter *iter;
728  RzAnalysisXRef *xref;
730 
731  rz_list_foreach (xrefs, iter, xref) {
732  if (xref->to == UT64_MAX) {
733  continue;
734  }
735  switch (xref->type) {
737  if (core->analysis->opt.followdatarefs) {
738  rz_analysis_try_get_fcn(core, xref, depth, 2);
739  }
740  break;
743  rz_core_analysis_fcn(core, xref->to, xref->from, xref->type, depth - 1);
744  break;
745  default:
746  break;
747  }
748  // TODO: fix memleak here, fcn not freed even though it is
749  // added in core->analysis->fcns which is freed in rz_analysis_free()
750  }
751  rz_list_free(xrefs);
752  return 1;
753 }
static bool rz_analysis_try_get_fcn(RzCore *core, RzAnalysisXRef *xref, int fcndepth, int refdepth)
Definition: canalysis.c:665

References rz_core_t::analysis, rz_analysis_options_t::followdatarefs, rz_analysis_ref_t::from, rz_analysis_t::opt, rz_analysis_function_get_xrefs_from(), rz_analysis_try_get_fcn(), RZ_ANALYSIS_XREF_TYPE_CALL, RZ_ANALYSIS_XREF_TYPE_CODE, RZ_ANALYSIS_XREF_TYPE_DATA, rz_core_analysis_fcn(), rz_list_free(), rz_analysis_ref_t::to, rz_analysis_ref_t::type, and UT64_MAX.

Referenced by __core_analysis_fcn().

◆ rz_analysis_bytes_free()

RZ_API void rz_analysis_bytes_free ( RZ_NULLABLE void *  ptr)

Free RzAnalysisBytes

Parameters
ptrRzAnalysisBytes pointer

Definition at line 6791 of file canalysis.c.

6791  {
6792  if (!ptr) {
6793  return;
6794  }
6795  RzAnalysisBytes *ab = ptr;
6796  rz_analysis_op_free(ab->op);
6797  rz_analysis_hint_free(ab->hint);
6798  free(ab->opcode);
6799  free(ab->disasm);
6800  free(ab->pseudo);
6801  free(ab->description);
6802  free(ab->mask);
6803  free(ab->bytes);
6804  free(ab);
6805 }

References free(), rz_analysis_hint_free(), and rz_analysis_op_free().

Referenced by rz_core_analysis_bytes().

◆ rz_analysis_set_stringrefs()

static void rz_analysis_set_stringrefs ( RzCore core,
RzAnalysisFunction fcn 
)
static

Definition at line 647 of file canalysis.c.

647  {
648  bool is_va = core->io->va;
649  RzBinObject *bobj = rz_bin_cur_object(core->bin);
650  if (!bobj) {
651  return;
652  }
653  RzListIter *iter;
654  RzAnalysisXRef *xref;
656  rz_list_foreach (xrefs, iter, xref) {
657  if (xref->type == RZ_ANALYSIS_XREF_TYPE_DATA &&
658  rz_bin_object_get_string_at(bobj, xref->to, is_va)) {
660  }
661  }
662  rz_list_free(xrefs);
663 }
RZ_API RZ_BORROW RzBinString * rz_bin_object_get_string_at(RZ_NONNULL RzBinObject *obj, ut64 address, bool is_va)
Return RzBinString if at address there is an entry in the RzBinObject string database.
Definition: bobj.c:861
@ RZ_ANALYSIS_XREF_TYPE_STRING
Definition: rz_analysis.h:903

References rz_core_t::analysis, rz_core_t::bin, rz_analysis_ref_t::from, rz_core_t::io, rz_analysis_function_get_xrefs_from(), RZ_ANALYSIS_XREF_TYPE_DATA, RZ_ANALYSIS_XREF_TYPE_STRING, rz_analysis_xrefs_set(), rz_bin_cur_object(), rz_bin_object_get_string_at(), rz_list_free(), rz_analysis_ref_t::to, rz_analysis_ref_t::type, and rz_io_t::va.

Referenced by __core_analysis_fcn().

◆ rz_analysis_try_get_fcn()

static bool rz_analysis_try_get_fcn ( RzCore core,
RzAnalysisXRef xref,
int  fcndepth,
int  refdepth 
)
static

Definition at line 665 of file canalysis.c.

665  {
666  if (!refdepth) {
667  return false;
668  }
669  RzIOMap *map = rz_io_map_get(core->io, xref->to);
670  if (!map) {
671  return false;
672  }
673 
674  if (map->perm & RZ_PERM_X) {
675  ut8 buf[64];
676  rz_io_read_at(core->io, xref->to, buf, sizeof(buf));
677  bool looksLikeAFunction = rz_analysis_check_fcn(core->analysis, buf, sizeof(buf), xref->to, map->itv.addr,
678  map->itv.addr + map->itv.size);
679  if (looksLikeAFunction) {
680  if (core->analysis->limit) {
681  if (xref->to < core->analysis->limit->from ||
682  xref->to > core->analysis->limit->to) {
683  return 1;
684  }
685  }
686  rz_core_analysis_fcn(core, xref->to, xref->from, xref->type, fcndepth - 1);
687  }
688  } else {
689  ut64 offs = 0;
690  ut64 sz = core->analysis->bits >> 3;
691  RzAnalysisXRef xref1;
693  xref1.from = xref->to;
694  xref1.to = 0;
695  ut32 i32;
696  ut16 i16;
697  ut8 i8;
698  ut64 offe = offs + 1024;
699  for (offs = 0; offs < offe; offs += sz, xref1.from += sz) {
700  ut8 bo[8];
701  rz_io_read_at(core->io, xref->to + offs, bo, RZ_MIN(sizeof(bo), sz));
702  bool be = core->analysis->big_endian;
703  switch (sz) {
704  case 1:
705  i8 = rz_read_ble8(bo);
706  xref1.to = (ut64)i8;
707  break;
708  case 2:
709  i16 = rz_read_ble16(bo, be);
710  xref1.to = (ut64)i16;
711  break;
712  case 4:
713  i32 = rz_read_ble32(bo, be);
714  xref1.to = (ut64)i32;
715  break;
716  case 8:
717  xref1.to = rz_read_ble64(bo, be);
718  break;
719  }
720  rz_analysis_try_get_fcn(core, &xref1, fcndepth, refdepth - 1);
721  }
722  }
723  return 1;
724 }
uint16_t ut16
uint32_t ut32
RZ_API bool rz_analysis_check_fcn(RzAnalysis *analysis, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high)
Definition: fcn.c:1538
static ut8 rz_read_ble8(const void *src)
Definition: rz_endian.h:12
#define RZ_MIN(x, y)
RzAnalysisRange * limit
Definition: rz_analysis.h:587

References rz_core_t::analysis, rz_analysis_t::big_endian, rz_analysis_t::bits, rz_analysis_range_t::from, rz_analysis_ref_t::from, rz_core_t::io, rz_analysis_t::limit, map(), rz_analysis_check_fcn(), RZ_ANALYSIS_XREF_TYPE_DATA, rz_core_analysis_fcn(), rz_io_map_get(), rz_io_read_at(), RZ_MIN, RZ_PERM_X, rz_read_ble16(), rz_read_ble32(), rz_read_ble64(), rz_read_ble8(), rz_analysis_range_t::to, rz_analysis_ref_t::to, rz_analysis_ref_t::type, and ut64().

Referenced by rz_analysis_analyze_fcn_refs().

◆ rz_analysis_var_global_list_show()

RZ_IPI bool rz_analysis_var_global_list_show ( RzAnalysis analysis,
RzCmdStateOutput state,
RZ_NULLABLE const char *  name 
)

Definition at line 6220 of file canalysis.c.

6220  {
6221  rz_return_val_if_fail(analysis && state, false);
6222  RzList *global_vars = NULL;
6223  RzAnalysisVarGlobal *glob = NULL;
6224  if (name) {
6225  global_vars = rz_list_new();
6226  if (!global_vars) {
6227  return false;
6228  }
6229  glob = rz_analysis_var_global_get_byname(analysis, name);
6230  if (!glob) {
6231  RZ_LOG_ERROR("Global variable '%s' does not exist!\n", name);
6232  rz_list_free(global_vars);
6233  return false;
6234  }
6235  rz_list_append(global_vars, glob);
6236  } else {
6237  global_vars = rz_analysis_var_global_get_all(analysis);
6238  }
6239 
6240  RzListIter *it = NULL;
6241  char *var_type = NULL;
6242  bool json = state->mode == RZ_OUTPUT_MODE_JSON;
6243  PJ *pj = json ? state->d.pj : NULL;
6244 
6246  if (!global_vars) {
6248  return false;
6249  }
6250  rz_list_foreach (global_vars, it, glob) {
6251  var_type = rz_type_as_string(analysis->typedb, glob->type);
6252  if (!var_type) {
6253  continue;
6254  }
6255  switch (state->mode) {
6257  rz_cons_printf("global %s %s @ 0x%" PFMT64x "\n",
6258  var_type, glob->name, glob->addr);
6259  break;
6260  case RZ_OUTPUT_MODE_JSON:
6261  pj_o(pj);
6262  pj_ks(pj, "name", glob->name);
6263  pj_ks(pj, "type", var_type);
6264  char addr[32];
6265  rz_strf(addr, "0x%" PFMT64x, glob->addr);
6266  pj_ks(pj, "addr", addr);
6267  pj_end(pj);
6268  break;
6269  default:
6270  break;
6271  }
6272  free(var_type);
6273  }
6275  rz_list_free(global_vars);
6276  return true;
6277 }
RZ_API void rz_cmd_state_output_array_start(RzCmdStateOutput *state)
Mark the start of an array of elements in the output.
Definition: cmd_api.c:2558
RZ_API void rz_cmd_state_output_array_end(RzCmdStateOutput *state)
Mark the end of an array of elements in the output.
Definition: cmd_api.c:2572
#define rz_strf(buf,...)
Convenience macro for local temporary strings.
Definition: rz_str.h:59
RzTypeDB * typedb
Definition: rz_analysis.h:602
Global variables.
Definition: rz_analysis.h:744
RzType * type
type of the variable
Definition: rz_analysis.h:748
ut64 addr
address of the global variable
Definition: rz_analysis.h:747
char * name
name of the variable
Definition: rz_analysis.h:746
RZ_API RZ_OWN char * rz_type_as_string(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Returns the type C representation.
Definition: type.c:817
RZ_API RZ_OWN RzList * rz_analysis_var_global_get_all(RzAnalysis *analysis)
Get all of the added global variables.
Definition: var_global.c:259
RZ_API RZ_BORROW RzAnalysisVarGlobal * rz_analysis_var_global_get_byname(RzAnalysis *analysis, RZ_NONNULL const char *name)
Get the instance of global variable by its name.
Definition: var_global.c:190

References addr, rz_analysis_var_global_t::addr, free(), rz_analysis_var_global_t::name, NULL, PFMT64x, pj_end(), pj_ks(), pj_o(), rz_analysis_var_global_get_all(), rz_analysis_var_global_get_byname(), rz_cmd_state_output_array_end(), rz_cmd_state_output_array_start(), rz_cons_printf(), rz_list_append(), rz_list_free(), rz_list_new(), RZ_LOG_ERROR, RZ_OUTPUT_MODE_JSON, RZ_OUTPUT_MODE_STANDARD, rz_return_val_if_fail, rz_strf, rz_type_as_string(), rz_analysis_var_global_t::type, and rz_analysis_t::typedb.

Referenced by rz_analysis_print_global_variable_handler().

◆ rz_core_analysis_address()

RZ_API ut64 rz_core_analysis_address ( RzCore core,
ut64  addr 
)

Definition at line 168 of file canalysis.c.

168  {
169  ut64 types = 0;
170  RzRegSet *rs = NULL;
171  if (!core) {
172  return 0;
173  }
175  if (rs) {
176  RzRegItem *r;
177  RzListIter *iter;
178  rz_list_foreach (rs->regs, iter, r) {
179  if (r->type == RZ_REG_TYPE_GPR) {
180  ut64 val = rz_reg_getv(core->analysis->reg, r->name);
181  if (addr == val) {
183  break;
184  }
185  }
186  }
187  }
188  if (rz_flag_get_i(core->flags, addr)) {
190  }
191  if (rz_analysis_get_fcn_in(core->analysis, addr, 0)) {
193  }
194  // check registers
195  if (rz_core_is_debug(core)) {
196  RzDebugMap *map;
197  RzListIter *iter;
198  // use 'dm'
199  // XXX: this line makes rz debugging MUCH slower
200  // rz_debug_map_sync (core->dbg);
201  rz_list_foreach (core->dbg->maps, iter, map) {
202  if (addr >= map->addr && addr < map->addr_end) {
203  if (map->name && map->name[0] == '/') {
204  if (core->io && core->io->desc &&
205  core->io->desc->name &&
206  !strcmp(map->name,
207  core->io->desc->name)) {
209  } else {
211  }
212  }
213  if (map->perm & RZ_PERM_X) {
215  }
216  if (map->perm & RZ_PERM_R) {
218  }
219  if (map->perm & RZ_PERM_W) {
221  }
222  // find function
223  if (map->name && strstr(map->name, "heap")) {
225  }
226  if (map->name && strstr(map->name, "stack")) {
228  }
229  break;
230  }
231  }
232  } else {
233  int _perm = -1;
234  if (core->io) {
235  // sections
236  void **it;
237  RzPVector *maps = rz_io_maps(core->io);
238  rz_pvector_foreach (maps, it) {
239  RzIOMap *s = *it;
240  if (addr >= s->itv.addr && addr < (s->itv.addr + s->itv.size)) {
241  // sections overlap, so we want to get the one with lower perms
242  _perm = (_perm != -1) ? RZ_MIN(_perm, s->perm) : s->perm;
243  // TODO: we should identify which maps come from the program or other
244  // types |= RZ_ANALYSIS_ADDR_TYPE_PROGRAM;
245  // find function those sections should be created by hand or esil init
246  if (s->name && strstr(s->name, "heap")) {
248  }
249  if (s->name && strstr(s->name, "stack")) {
251  }
252  }
253  }
254  }
255  if (_perm != -1) {
256  if (_perm & RZ_PERM_X) {
258  }
259  if (_perm & RZ_PERM_R) {
261  }
262  if (_perm & RZ_PERM_W) {
264  }
265  }
266  }
267 
268  // check if it's ascii
269  if (addr != 0) {
270  int not_ascii = 0;
271  int i, failed_sequence, dir, on;
272  for (i = 0; i < 8; i++) {
273  ut8 n = (addr >> (i * 8)) & 0xff;
274  if (n && !IS_PRINTABLE(n)) {
275  not_ascii = 1;
276  }
277  }
278  if (!not_ascii) {
280  }
281  failed_sequence = 0;
282  dir = on = -1;
283  for (i = 0; i < 8; i++) {
284  ut8 n = (addr >> (i * 8)) & 0xff;
285  if (on != -1) {
286  if (dir == -1) {
287  dir = (n > on) ? 1 : -1;
288  }
289  if (n == on + dir) {
290  // ok
291  } else {
292  failed_sequence = 1;
293  break;
294  }
295  }
296  on = n;
297  }
298  if (!failed_sequence) {
300  }
301  }
302  return types;
303 }
#define rs()
static RzList * maps(RzBinFile *bf)
Definition: bin_bf.c:116
RZ_API bool rz_core_is_debug(RzCore *core)
Check whether the core is in debug mode (equivalent to cfg.debug)
Definition: cdebug.c:13
#define r
Definition: crypto_rc6.c:12
int n
Definition: mipsasm.c:19
insn_type_descr_t types[]
Definition: or1k_disas.c:7
RZ_API RzRegSet * rz_reg_regset_get(RzReg *r, int type)
Definition: reg.c:452
#define RZ_ANALYSIS_ADDR_TYPE_STACK
Definition: rz_analysis.h:91
#define RZ_ANALYSIS_ADDR_TYPE_SEQUENCE
Definition: rz_analysis.h:96
#define RZ_ANALYSIS_ADDR_TYPE_ASCII
Definition: rz_analysis.h:95
#define RZ_ANALYSIS_ADDR_TYPE_EXEC
Definition: rz_analysis.h:85
#define RZ_ANALYSIS_ADDR_TYPE_HEAP
Definition: rz_analysis.h:90
#define RZ_ANALYSIS_ADDR_TYPE_FLAG
Definition: rz_analysis.h:88
#define RZ_ANALYSIS_ADDR_TYPE_LIBRARY
Definition: rz_analysis.h:94
#define RZ_ANALYSIS_ADDR_TYPE_REG
Definition: rz_analysis.h:92
#define RZ_ANALYSIS_ADDR_TYPE_WRITE
Definition: rz_analysis.h:87
#define RZ_ANALYSIS_ADDR_TYPE_FUNC
Definition: rz_analysis.h:89
#define RZ_ANALYSIS_ADDR_TYPE_READ
Definition: rz_analysis.h:86
#define RZ_ANALYSIS_ADDR_TYPE_PROGRAM
Definition: rz_analysis.h:93
RZ_API RZ_BORROW RzPVector * rz_io_maps(RzIO *io)
Returns the pointer to vector containing maps list.
Definition: io_map.c:435
@ RZ_REG_TYPE_GPR
Definition: rz_reg.h:21
#define RZ_PERM_R
Definition: rz_types.h:93
#define RZ_PERM_W
Definition: rz_types.h:94
#define rz_pvector_foreach(vec, it)
Definition: rz_vector.h:334
RzList * maps
Definition: rz_debug.h:306
char * name
Definition: rz_io.h:99
struct rz_io_desc_t * desc
Definition: rz_io.h:60

References addr, rz_core_t::analysis, rz_core_t::dbg, rz_io_t::desc, rz_core_t::flags, i, rz_core_t::io, IS_PRINTABLE, map(), maps(), rz_debug_t::maps, n, rz_io_desc_t::name, NULL, r, rz_analysis_t::reg, rs, RZ_ANALYSIS_ADDR_TYPE_ASCII, RZ_ANALYSIS_ADDR_TYPE_EXEC, RZ_ANALYSIS_ADDR_TYPE_FLAG, RZ_ANALYSIS_ADDR_TYPE_FUNC, RZ_ANALYSIS_ADDR_TYPE_HEAP, RZ_ANALYSIS_ADDR_TYPE_LIBRARY, RZ_ANALYSIS_ADDR_TYPE_PROGRAM, RZ_ANALYSIS_ADDR_TYPE_READ, RZ_ANALYSIS_ADDR_TYPE_REG, RZ_ANALYSIS_ADDR_TYPE_SEQUENCE, RZ_ANALYSIS_ADDR_TYPE_STACK, RZ_ANALYSIS_ADDR_TYPE_WRITE, rz_analysis_get_fcn_in(), rz_core_is_debug(), rz_flag_get_i(), rz_io_maps(), RZ_MIN, RZ_PERM_R, RZ_PERM_W, RZ_PERM_X, rz_pvector_foreach, rz_reg_getv(), rz_reg_regset_get(), RZ_REG_TYPE_GPR, s, types, ut64(), and val.

Referenced by cmd_address_info(), ds_print_ptr(), esil_addrinfo(), rz_core_analysis_hasrefs_to_depth(), and rz_core_analysis_optype_colorfor().

◆ rz_core_analysis_all()

RZ_API int rz_core_analysis_all ( RzCore core)

Definition at line 3552 of file canalysis.c.

3552  {
3553  RzList *list;
3554  RzListIter *iter;
3555  RzFlagItem *item;
3556  RzAnalysisFunction *fcni;
3557  const RzBinAddr *binmain;
3558  RzBinAddr *entry;
3559  RzBinSymbol *symbol;
3560  int depth = core->analysis->opt.depth;
3561  bool analysis_vars = rz_config_get_i(core->config, "analysis.vars");
3562 
3563  /* Analyze Functions */
3564  /* Entries */
3565  item = rz_flag_get(core->flags, "entry0");
3566  if (item) {
3567  rz_core_analysis_fcn(core, item->offset, -1, RZ_ANALYSIS_XREF_TYPE_NULL, depth - 1);
3568  rz_core_analysis_function_rename(core, item->offset, "entry0");
3569  } else {
3570  rz_core_analysis_function_add(core, NULL, core->offset, false);
3571  }
3572 
3573  rz_core_task_yield(&core->tasks);
3574 
3576 
3577  RzBinFile *bf = core->bin->cur;
3578  RzBinObject *o = bf ? bf->o : NULL;
3579  /* Symbols (Imports are already analyzed by rz_bin on init) */
3580  if (o && (list = o->symbols) != NULL) {
3581  rz_list_foreach (list, iter, symbol) {
3582  if (rz_cons_is_breaked()) {
3583  break;
3584  }
3585  // Stop analyzing PE imports further
3586  if (isSkippable(symbol)) {
3587  continue;
3588  }
3589  if (isValidSymbol(symbol)) {
3590  ut64 addr = rz_bin_object_get_vaddr(o, symbol->paddr, symbol->vaddr);
3591  rz_core_analysis_fcn(core, addr, -1, RZ_ANALYSIS_XREF_TYPE_NULL, depth - 1);
3592  }
3593  }
3594  }
3595  rz_core_task_yield(&core->tasks);
3596  /* Main */
3598  if (binmain->paddr != UT64_MAX) {
3599  ut64 addr = rz_bin_object_get_vaddr(o, binmain->paddr, binmain->vaddr);
3600  rz_core_analysis_fcn(core, addr, -1, RZ_ANALYSIS_XREF_TYPE_NULL, depth - 1);
3601  }
3602  }
3603  rz_core_task_yield(&core->tasks);
3604  if ((list = rz_bin_get_entries(core->bin))) {
3605  rz_list_foreach (list, iter, entry) {
3606  if (entry->paddr == UT64_MAX) {
3607  continue;
3608  }
3609  ut64 addr = rz_bin_object_get_vaddr(o, entry->paddr, entry->vaddr);
3610  rz_core_analysis_fcn(core, addr, -1, RZ_ANALYSIS_XREF_TYPE_NULL, depth - 1);
3611  }
3612  }
3613  rz_core_task_yield(&core->tasks);
3614  if (analysis_vars) {
3615  /* Set fcn type to RZ_ANALYSIS_FCN_TYPE_SYM for symbols */
3616  rz_list_foreach_prev(core->analysis->fcns, iter, fcni) {
3617  if (rz_cons_is_breaked()) {
3618  break;
3619  }
3620  rz_core_recover_vars(core, fcni, true);
3621  if (!strncmp(fcni->name, "sym.", 4) || !strncmp(fcni->name, "main", 4)) {
3623  }
3624  }
3625  }
3626  rz_core_task_yield(&core->tasks);
3627 
3630 
3632  return true;
3633 }
RZ_DEPRECATE RZ_API RZ_BORROW RzList * rz_bin_get_entries(RZ_NONNULL RzBin *bin)
Definition: bin.c:567
RZ_API const RzBinAddr * rz_bin_object_get_special_symbol(RzBinObject *o, RzBinSpecialSymbol sym)
Return the RzBinAddr structure representing the special symbol sym.
Definition: bobj.c:699
RZ_API ut64 rz_bin_object_get_vaddr(RzBinObject *o, ut64 paddr, ut64 vaddr)
Definition: bobj.c:669
RZ_API void rz_core_recover_vars(RzCore *core, RzAnalysisFunction *fcn, bool argonly)
Definition: canalysis.c:2779
RZ_API bool rz_core_analysis_function_add(RzCore *core, const char *name, ut64 addr, bool analyze_recursively)
Definition: canalysis.c:5298
static bool isValidSymbol(RzBinSymbol *symbol)
Definition: canalysis.c:3527
static bool isSkippable(RzBinSymbol *s)
Definition: canalysis.c:3535
RZ_API bool rz_platform_index_add_flags_comments(RzCore *core)
Adds the information from the Platform Profiles as flags and comments.
Definition: canalysis.c:5263
RZ_API bool rz_core_analysis_function_rename(RzCore *core, ut64 addr, const char *_name)
Definition: canalysis.c:5270
RZ_API void rz_platform_profile_add_flag_every_io(RzPlatformProfile *profile, RzFlag *flags)
Adds the IO and extended IO registers from the CPU profiles as flags.
Definition: canalysis.c:5236
RZ_API void rz_cons_break_pop(void)
Definition: cons.c:361
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
Definition: cons.c:357
RZ_API RzFlagItem * rz_flag_get(RzFlag *f, const char *name)
Definition: flag.c:310
@ RZ_ANALYSIS_FCN_TYPE_SYM
Definition: rz_analysis.h:195
@ RZ_BIN_SPECIAL_SYMBOL_MAIN
Definition: rz_bin.h:139
Definition: zipcmp.c:77
RzList * fcns
Definition: rz_analysis.h:565
ut64 vaddr
Definition: rz_bin.h:186
ut64 paddr
Definition: rz_bin.h:187
RzList * symbols
Definition: rz_bin.h:269
RzCoreTaskScheduler tasks
Definition: rz_core.h:362
RZ_API void rz_core_task_yield(RzCoreTaskScheduler *scheduler)
Definition: task.c:336

References addr, rz_core_t::analysis, rz_analysis_t::arch_target, rz_core_t::bin, rz_core_t::config, rz_bin_t::cur, rz_analysis_options_t::depth, rz_analysis_t::fcns, rz_core_t::flags, isSkippable(), isValidSymbol(), list(), rz_analysis_function_t::name, NULL, rz_bin_file_t::o, rz_core_t::offset, rz_flag_item_t::offset, rz_analysis_t::opt, rz_bin_addr_t::paddr, rz_bin_symbol_t::paddr, rz_platform_target_t::profile, RZ_ANALYSIS_FCN_TYPE_SYM, RZ_ANALYSIS_XREF_TYPE_NULL, rz_bin_get_entries(), rz_bin_object_get_special_symbol(), rz_bin_object_get_vaddr(), RZ_BIN_SPECIAL_SYMBOL_MAIN, rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_core_analysis_fcn(), rz_core_analysis_function_add(), rz_core_analysis_function_rename(), rz_core_recover_vars(), rz_core_task_yield(), rz_flag_get(), rz_platform_index_add_flags_comments(), rz_platform_profile_add_flag_every_io(), rz_bin_object_t::symbols, rz_core_t::tasks, rz_analysis_function_t::type, ut64(), UT64_MAX, rz_bin_addr_t::vaddr, and rz_bin_symbol_t::vaddr.

Referenced by __program_cb(), __symbols_cb(), and core_perform_auto_analysis().

◆ rz_core_analysis_all_vars_display()

RZ_IPI char* rz_core_analysis_all_vars_display ( RzCore core,
RzAnalysisFunction fcn,
bool  add_name 
)

Definition at line 6206 of file canalysis.c.

6206  {
6207  RzListIter *iter;
6208  RzAnalysisVar *p;
6211  rz_list_foreach (list, iter, p) {
6212  char *r = rz_core_analysis_var_display(core, p, add_name);
6213  rz_strbuf_append(sb, r);
6214  free(r);
6215  }
6216  rz_list_free(list);
6217  return rz_strbuf_drain(sb);
6218 }
static SblHeader sb
Definition: bin_mbn.c:26
RZ_IPI char * rz_core_analysis_var_display(RzCore *core, RzAnalysisVar *var, bool add_name)
Definition: canalysis.c:6148
RZ_API RZ_OWN char * rz_strbuf_drain(RzStrBuf *sb)
Definition: strbuf.c:342
RZ_API bool rz_strbuf_append(RzStrBuf *sb, const char *s)
Definition: strbuf.c:222
RZ_API RzStrBuf * rz_strbuf_new(const char *s)
Definition: strbuf.c:8
RZ_DEPRECATE RZ_API RzList * rz_analysis_var_all_list(RzAnalysis *analysis, RzAnalysisFunction *fcn)
Definition: var.c:1135

References rz_core_t::analysis, core_noretl::core, free(), list(), NULL, p, r, rz_analysis_var_all_list(), rz_core_analysis_var_display(), rz_list_free(), rz_strbuf_append(), rz_strbuf_drain(), rz_strbuf_new(), and sb.

Referenced by backtrace_vars(), and rz_analysis_function_vars_display_handler().

◆ rz_core_analysis_autoname_all_fcns()

RZ_API void rz_core_analysis_autoname_all_fcns ( RzCore core)

Definition at line 504 of file canalysis.c.

504  {
505  RzListIter *it;
506  RzAnalysisFunction *fcn;
507 
508  rz_list_foreach (core->analysis->fcns, it, fcn) {
509  if (!strncmp(fcn->name, "fcn.", 4) || !strncmp(fcn->name, "sym.func.", 9)) {
510  RzFlagItem *item = rz_flag_get(core->flags, fcn->name);
511  if (item) {
512  char *name = rz_core_analysis_function_autoname(core, fcn);
513  if (name) {
514  rz_flag_rename(core->flags, item, name);
515  free(fcn->name);
516  fcn->name = name;
517  }
518  } else {
519  // there should always be a flag for a function
521  }
522  }
523  }
524 }
RZ_API RZ_OWN char * rz_core_analysis_function_autoname(RZ_NONNULL RzCore *core, RZ_NONNULL RzAnalysisFunction *fcn)
Suggest a name for the function.
Definition: canalysis.c:545
const char * name
Definition: op.c:541

References rz_core_t::analysis, rz_analysis_t::fcns, rz_core_t::flags, free(), name, rz_analysis_function_t::name, rz_core_analysis_function_autoname(), rz_flag_get(), rz_flag_rename(), and rz_warn_if_reached.

Referenced by rz_autoname_all_functions_handler(), and rz_core_analysis_everything().

◆ rz_core_analysis_bb_info_print()

RZ_IPI void rz_core_analysis_bb_info_print ( RzCore core,
RzAnalysisBlock bb,
ut64  addr,
RzCmdStateOutput state 
)

Definition at line 496 of file canalysis.c.

496  {
497  rz_return_if_fail(core && bb && state);
498  rz_cmd_state_output_set_columnsf(state, "xdxx", "addr", "size", "jump", "fail");
500  bb_info_print(core, fcn, bb, addr, state->mode, state->d.pj, state->d.t);
501 }
static void bb_info_print(RzCore *core, RzAnalysisFunction *fcn, RzAnalysisBlock *bb, ut64 addr, RzOutputMode mode, PJ *pj, RzTable *t)
Definition: canalysis.c:363
RZ_API void rz_cmd_state_output_set_columnsf(RzCmdStateOutput *state, const char *fmt,...)
Specify the columns of the command output.
Definition: cmd_api.c:2589

References addr, bb_info_print(), rz_analysis_bb_t::fcns, rz_cmd_state_output_set_columnsf(), rz_list_first(), and rz_return_if_fail.

Referenced by rz_analysis_basic_block_info_handler(), and rz_analysis_function_blocks_info_handler().

◆ rz_core_analysis_bb_seek()

RZ_API bool rz_core_analysis_bb_seek ( RzCore core,
ut64  addr 
)

Definition at line 1975 of file canalysis.c.

1975  {
1977  if (block) {
1978  rz_core_seek_and_save(core, block->addr, false);
1979  return true;
1980  }
1981  return false;
1982 }
RZ_API bool rz_core_seek_and_save(RzCore *core, ut64 addr, bool rb)
Save currently marked state in seek history and seek to addr .
Definition: seek.c:101

References addr, rz_analysis_bb_t::addr, rz_core_t::analysis, rz_analysis_find_most_relevant_block_in(), and rz_core_seek_and_save().

◆ rz_core_analysis_bbs_asciiart()

RZ_IPI void rz_core_analysis_bbs_asciiart ( RzCore core,
RzAnalysisFunction fcn 
)

Definition at line 305 of file canalysis.c.

305  {
307  if (!flist) {
308  return;
309  }
310  RzListIter *iter;
312  ls_foreach (fcn->bbs, iter, b) {
313  RzInterval inter = (RzInterval){ b->addr, b->size };
314  RzListInfo *info = rz_listinfo_new(NULL, inter, inter, -1, NULL);
315  if (!info) {
316  break;
317  }
318  rz_list_append(flist, info);
319  }
320  RzTable *table = rz_core_table(core);
321  rz_table_visual_list(table, flist, core->offset, core->blocksize,
322  rz_cons_get_size(NULL), rz_config_get_i(core->config, "scr.color"));
323  rz_cons_printf("\n%s\n", rz_table_tostring(table));
324  rz_table_free(table);
325  rz_list_free(flist);
326 }
RzBinInfo * info(RzBinFile *bf)
Definition: bin_ne.c:86
RZ_API int rz_cons_get_size(int *rows)
Definition: cons.c:1446
RZ_API RzTable * rz_core_table(RzCore *core)
Definition: core.c:3449
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
Definition: list.c:248
#define ls_foreach(list, it, pos)
Definition: ls.h:31
struct rz_interval_t RzInterval
void(* RzListFree)(void *ptr)
Definition: rz_list.h:11
RZ_API void rz_table_visual_list(RzTable *table, RzList *list, ut64 seek, ut64 len, int width, bool va)
Definition: table.c:1205
RZ_API void rz_table_free(RzTable *t)
Definition: table.c:114
RZ_API char * rz_table_tostring(RzTable *t)
Definition: table.c:510
RZ_API RzListInfo * rz_listinfo_new(const char *name, RzInterval pitv, RzInterval vitv, int perm, const char *extra)
Definition: visual.c:4020
RZ_API void rz_listinfo_free(RzListInfo *info)
Definition: visual.c:4032

References b, rz_analysis_function_t::bbs, rz_core_t::blocksize, rz_core_t::config, info(), ls_foreach, NULL, rz_core_t::offset, rz_config_get_i(), rz_cons_get_size(), rz_cons_printf(), rz_core_table(), rz_list_append(), rz_list_free(), rz_list_newf(), rz_listinfo_free(), rz_listinfo_new(), rz_table_free(), rz_table_tostring(), and rz_table_visual_list().

Referenced by rz_analysis_function_blocks_asciiart_handler().

◆ rz_core_analysis_bbs_info_print()

RZ_IPI void rz_core_analysis_bbs_info_print ( RzCore core,
RzAnalysisFunction fcn,
RzCmdStateOutput state 
)

Definition at line 478 of file canalysis.c.

478  {
479  rz_return_if_fail(core && fcn && state);
480  RzListIter *iter;
481  RzAnalysisBlock *bb;
483  rz_cmd_state_output_set_columnsf(state, "xdxx", "addr", "size", "jump", "fail");
484  if (state->mode == RZ_OUTPUT_MODE_RIZIN) {
485  rz_cons_printf("fs blocks\n");
486  }
487 
488  rz_list_sort(fcn->bbs, bb_cmp);
489  rz_list_foreach (fcn->bbs, iter, bb) {
490  bb_info_print(core, fcn, bb, bb->addr, state->mode, state->d.pj, state->d.t);
491  }
492 
494 }
static int bb_cmp(const void *a, const void *b)
Definition: canalysis.c:472
RZ_API void rz_list_sort(RZ_NONNULL RzList *list, RZ_NONNULL RzListComparator cmp)
Sorts via merge sort or via insertion sort a list.
Definition: list.c:743

References rz_analysis_bb_t::addr, bb_cmp(), bb_info_print(), rz_analysis_function_t::bbs, rz_cmd_state_output_array_end(), rz_cmd_state_output_array_start(), rz_cmd_state_output_set_columnsf(), rz_cons_printf(), rz_list_sort(), RZ_OUTPUT_MODE_RIZIN, and rz_return_if_fail.

Referenced by rz_analysis_function_blocks_list_handler().

◆ rz_core_analysis_bytes()

RZ_API RZ_OWN RzPVector* rz_core_analysis_bytes ( RZ_NONNULL RzCore core,
RZ_NONNULL const ut8 buf,
int  len,
int  nops 
)

Analyze and disassemble bytes use rz_analysis_op and rz_asm_disassemble

Parameters
coreThe RzCore instance
bufdata to analysis
lenanalysis len bytes
nopsanalysis n ops
Returns
list of RzAnalysisBytes

Definition at line 6817 of file canalysis.c.

6817  {
6818  rz_return_val_if_fail(core && buf, NULL);
6820  if (!vec) {
6821  return NULL;
6822  }
6823  rz_pvector_reserve(vec, nops);
6824  int min_op_size = rz_analysis_archinfo(core->analysis, RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE);
6825  min_op_size = min_op_size > 0 ? min_op_size : 1;
6826 
6827  bool bigendian = rz_config_get_b(core->config, "cfg.bigendian");
6828  bool asm_sub_var = rz_config_get_i(core->config, "asm.sub.var");
6829  core->parser->subrel = rz_config_get_i(core->config, "asm.sub.rel");
6830  core->parser->localvar_only = rz_config_get_i(core->config, "asm.sub.varonly");
6831 
6832  const int addrbytes = (int)core->io->addrbytes;
6834  RzAsmOp asmop;
6835  int oplen = 0;
6836  char disasm[512];
6837  for (int i_ops = 0, i_offset = 0, i_delta = 0;
6838  rz_disasm_check_end(nops, i_ops, len, i_delta * addrbytes);
6839  i_ops++, i_offset += oplen, i_delta += oplen) {
6840 
6841  RzAnalysisBytes *ab = RZ_NEW0(RzAnalysisBytes);
6842  if (!ab) {
6843  rz_pvector_free(vec);
6844  return NULL;
6845  }
6846 
6847  rz_pvector_push(vec, ab);
6848  ut64 addr = core->offset + i_offset;
6849  const ut8 *ptr = buf + i_offset;
6850  rz_asm_set_pc(core->rasm, addr);
6851 
6852  if (nops > 0 && i_delta >= len - 32) {
6853  rz_io_read_at(core->io, addr, (ut8 *)buf, len);
6854  i_delta = 0;
6855  }
6856 
6857  ab->hint = rz_analysis_hint_get(core->analysis, addr);
6858  RzAnalysisOp *op = ab->op = rz_analysis_op_new();
6859  if (!op) {
6860  rz_pvector_free(vec);
6861  return NULL;
6862  }
6863 
6864  int reta = rz_analysis_op(core->analysis, ab->op, addr, ptr, len - i_delta, mask);
6865  int ret = rz_asm_disassemble(core->rasm, &asmop, ptr, len - i_delta);
6866  if (reta < 1 || ret < 1) {
6867  oplen = min_op_size;
6868  ab->opcode = strdup("invalid");
6869  ab->disasm = strdup("invalid");
6870  ab->bytes = rz_asm_op_get_hex(&asmop);
6871  continue;
6872  }
6873 
6874  oplen = rz_asm_op_get_size(&asmop);
6875 
6876  if (core->parser->subrel) {
6877  ut64 subrel_addr = UT64_MAX;
6878  if (rz_io_read_i(core->io, op->ptr, &subrel_addr, op->refptr, bigendian)) {
6879  core->parser->subrel_addr = subrel_addr;
6880  }
6881  }
6882 
6883  const char *an_asm = rz_asm_op_get_asm(&asmop);
6884  ab->opcode = strdup(an_asm);
6885  char *mnem = strdup(an_asm);
6886  char *sp = strchr(mnem, ' ');
6887  if (sp) {
6888  *sp = 0;
6889  if (op->prefix) {
6890  char *arg = strdup(sp + 1);
6891  sp = strchr(arg, ' ');
6892  if (sp) {
6893  *sp = 0;
6894  }
6895  free(mnem);
6896  mnem = arg;
6897  }
6898  }
6899  op->mnemonic = mnem;
6900 
6901  RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, addr);
6902  char *asm_buff = calloc(strlen(an_asm) + 128, sizeof(char));
6903  strcpy(asm_buff, an_asm);
6904 
6905  if (asm_sub_var) {
6906  core->parser->get_ptr_at = rz_analysis_function_get_var_stackptr_at;
6907  core->parser->get_reg_at = rz_analysis_function_get_var_reg_at;
6908  rz_parse_subvar(core->parser, fcn, op,
6909  asm_buff, asm_buff, sizeof(asmop.buf_asm));
6910  }
6911 
6912  rz_parse_filter(core->parser, addr, core->flags, ab->hint,
6913  asm_buff, disasm, sizeof(disasm), bigendian);
6914  rz_asm_op_set_asm(&asmop, asm_buff);
6915  free(asm_buff);
6916 
6917  ab->disasm = strdup(disasm);
6918 
6919  rz_core_asm_bb_middle(core, addr, &oplen, &ret);
6920  ab->oplen = oplen;
6921 
6922  // apply pseudo if needed
6923  ab->pseudo = rz_parse_pseudocode(core->parser, disasm);
6924 
6925  char *opname = strdup(disasm);
6926  sp = strchr(opname, ' ');
6927  if (sp) {
6928  *sp = 0;
6929  }
6930  ab->description = rz_asm_describe(core->rasm, opname);
6931  free(opname);
6932 
6933  ut8 *mask = rz_analysis_mask(core->analysis, len - i_offset, ptr, addr);
6934  ab->mask = rz_hex_bin2strdup(mask, oplen);
6935  free(mask);
6936 
6937  ab->bytes = rz_asm_op_get_hex(&asmop);
6938  }
6939  return vec;
6940 }
#define mnem(n, mn)
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
Definition: function.c:184
RZ_API ut8 * rz_analysis_mask(RzAnalysis *analysis, ut32 size, const ut8 *data, ut64 at)
Definition: analysis.c:334
#define mask()
RZ_API int rz_asm_op_get_size(RzAsmOp *op)
Definition: aop.c:47
RZ_API char * rz_asm_op_get_hex(RzAsmOp *op)
Definition: aop.c:28
RZ_API void rz_asm_op_set_asm(RzAsmOp *op, const char *str)
Definition: aop.c:53
RZ_API char * rz_asm_op_get_asm(RzAsmOp *op)
Definition: aop.c:37
static const char * arg(RzAnalysis *a, csh *handle, cs_insn *insn, char *buf, int n)
Definition: arm_esil32.c:136
RZ_API char * rz_asm_describe(RzAsm *a, const char *str)
Definition: asm.c:1187
RZ_API int rz_asm_disassemble(RzAsm *a, RzAsmOp *op, const ut8 *buf, int len)
Definition: asm.c:543
RZ_API void rz_analysis_bytes_free(RZ_NULLABLE void *ptr)
Definition: canalysis.c:6791
RZ_IPI void rz_core_asm_bb_middle(RZ_NONNULL RzCore *core, ut64 at, RZ_INOUT RZ_NONNULL int *oplen, RZ_NONNULL int *ret)
Update oplen by "asm.bb.middle" and "asm.flags.middle".
Definition: disasm.c:1684
RZ_IPI bool rz_disasm_check_end(int nb_opcodes, int i_opcodes, int nb_bytes, int i_bytes)
Is i_opcodes < nb_opcodes and i_bytes < nb_bytes ?
Definition: disasm.c:5804
RZ_API RzAnalysisOp * rz_analysis_op_new(void)
Definition: op.c:9
RZ_API bool rz_parse_filter(RzParse *p, ut64 addr, RzFlag *f, RzAnalysisHint *hint, char *data, char *str, int len, bool big_endian)
filter the opcode in data into str by following the flags and hints information
Definition: filter.c:592
RZ_API char * rz_parse_pseudocode(RzParse *p, const char *assembly)
Converts the assembly line into pseudocode.
Definition: parse.c:107
RZ_API bool rz_parse_subvar(RzParse *p, RZ_NULLABLE RzAnalysisFunction *f, RZ_NONNULL RzAnalysisOp *op, RZ_NONNULL RZ_IN char *data, RZ_BORROW RZ_NONNULL RZ_OUT char *str, int len)
Definition: parse.c:166
@ RZ_ANALYSIS_OP_MASK_OPEX
Definition: rz_analysis.h:444
@ RZ_ANALYSIS_OP_MASK_IL
Definition: rz_analysis.h:446
#define RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE
Definition: rz_analysis.h:98
RZ_API char * rz_hex_bin2strdup(const ut8 *in, int len)
Definition: hex.c:415
static void ** rz_pvector_reserve(RzPVector *vec, size_t capacity)
Definition: rz_vector.h:312
RZ_API RzPVector * rz_pvector_new(RzPVectorFree free)
Definition: vector.c:302
RZ_API void rz_pvector_free(RzPVector *vec)
Definition: vector.c:336
RZ_API st64 rz_analysis_function_get_var_stackptr_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: var.c:284
RZ_API const char * rz_analysis_function_get_var_reg_at(RzAnalysisFunction *fcn, st64 delta, ut64 addr)
Definition: var.c:314
static int sp
Definition: z80asm.c:91

References addr, rz_io_t::addrbytes, rz_core_t::analysis, arg(), calloc(), rz_core_t::config, core_noretl::core, rz_core_t::flags, free(), rz_parse_t::get_ptr_at, rz_parse_t::get_reg_at, int, rz_core_t::io, len, rz_parse_t::localvar_only, mask, mnem, NULL, rz_core_t::offset, rz_core_t::parser, rz_core_t::rasm, rz_analysis_archinfo(), RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE, rz_analysis_bytes_free(), rz_analysis_function_get_var_reg_at(), rz_analysis_function_get_var_stackptr_at(), rz_analysis_get_function_at(), rz_analysis_hint_get(), rz_analysis_mask(), rz_analysis_op(), RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_MASK_IL, RZ_ANALYSIS_OP_MASK_OPEX, rz_analysis_op_new(), rz_asm_describe(), rz_asm_disassemble(), rz_asm_op_get_asm(), rz_asm_op_get_hex(), rz_asm_op_get_size(), rz_asm_op_set_asm(), rz_asm_set_pc(), rz_config_get_b(), rz_config_get_i(), rz_core_asm_bb_middle(), rz_disasm_check_end(), rz_hex_bin2strdup(), rz_io_read_at(), rz_io_read_i(), RZ_NEW0, rz_parse_filter(), rz_parse_pseudocode(), rz_parse_subvar(), rz_pvector_free(), rz_pvector_new(), rz_pvector_push(), rz_pvector_reserve(), rz_return_val_if_fail, sp, strdup(), rz_parse_t::subrel, rz_parse_t::subrel_addr, ut64(), and UT64_MAX.

Referenced by core_analysis_bytes_json(), core_analysis_bytes_standard(), and rz_core_print_disasm_json().

◆ rz_core_analysis_callgraph()

RZ_API void rz_core_analysis_callgraph ( RzCore core,
ut64  addr,
int  fmt 
)

Definition at line 2425 of file canalysis.c.

2425  {
2426  const char *font = rz_config_get(core->config, "graph.font");
2427  int is_html = rz_cons_singleton()->is_html;
2428  bool refgraph = rz_config_get_i(core->config, "graph.refs");
2429  RzListIter *iter, *iter2;
2430  int usenames = rz_config_get_i(core->config, "graph.json.usenames");
2431  ;
2432  RzAnalysisFunction *fcni;
2433  RzAnalysisXRef *fcnr;
2434  PJ *pj = NULL;
2435 
2436  ut64 from = rz_config_get_i(core->config, "graph.from");
2437  ut64 to = rz_config_get_i(core->config, "graph.to");
2438 
2439  switch (fmt) {
2440  case RZ_GRAPH_FORMAT_JSON:
2441  pj = pj_new();
2442  if (!pj) {
2443  return;
2444  }
2445  pj_a(pj);
2446  break;
2447  case RZ_GRAPH_FORMAT_GML:
2449  rz_cons_printf("graph\n[\n"
2450  "hierarchic 1\n"
2451  "label \"\"\n"
2452  "directed 1\n");
2453  break;
2454  case RZ_GRAPH_FORMAT_DOT:
2455  if (!is_html) {
2456  const char *gv_edge = rz_config_get(core->config, "graph.gv.edge");
2457  char *gv_node = strdup(rz_config_get(core->config, "graph.gv.node"));
2458  const char *gv_grph = rz_config_get(core->config, "graph.gv.graph");
2459  const char *gv_spline = rz_config_get(core->config, "graph.gv.spline");
2460  if (!gv_edge || !*gv_edge) {
2461  gv_edge = "arrowhead=\"normal\" style=bold weight=2";
2462  }
2463  if (!gv_node || !*gv_node) {
2464  free(gv_node);
2465  gv_node = rz_str_newf("penwidth=4 fillcolor=white style=filled fontname=\"%s Bold\" fontsize=14 shape=box", font);
2466  }
2467  if (!gv_grph || !*gv_grph) {
2468  gv_grph = "bgcolor=azure";
2469  }
2470  if (!gv_spline || !*gv_spline) {
2471  // ortho for bbgraph and curved for callgraph
2472  gv_spline = "splines=\"curved\"";
2473  }
2474  rz_cons_printf("digraph code {\n"
2475  "rankdir=LR;\n"
2476  "outputorder=edgesfirst;\n"
2477  "graph [%s fontname=\"%s\" %s];\n"
2478  "node [%s];\n"
2479  "edge [%s];\n",
2480  gv_grph, font, gv_spline,
2481  gv_node, gv_edge);
2482  free(gv_node);
2483  }
2484  break;
2485  }
2486  ut64 base = UT64_MAX;
2487  int iteration = 0;
2488 repeat:
2489  rz_list_foreach (core->analysis->fcns, iter, fcni) {
2490  if (base == UT64_MAX) {
2491  base = fcni->addr;
2492  }
2493  if (from != UT64_MAX && fcni->addr < from) {
2494  continue;
2495  }
2496  if (to != UT64_MAX && fcni->addr > to) {
2497  continue;
2498  }
2499  if (addr != UT64_MAX && addr != fcni->addr) {
2500  continue;
2501  }
2503  RzList *calls = rz_list_new();
2504  // TODO: maybe fcni->calls instead ?
2505  rz_list_foreach (xrefs, iter2, fcnr) {
2506  // TODO: tail calll jumps are also calls
2508  rz_list_append(calls, fcnr);
2509  }
2510  }
2511  if (rz_list_empty(calls)) {
2512  rz_list_free(xrefs);
2513  rz_list_free(calls);
2514  continue;
2515  }
2516  switch (fmt) {
2517  case RZ_GRAPH_FORMAT_NO:
2518  rz_cons_printf("0x%08" PFMT64x "\n", fcni->addr);
2519  break;
2520  case RZ_GRAPH_FORMAT_GML:
2521  case RZ_GRAPH_FORMAT_GMLFCN: {
2522  RzFlagItem *flag = rz_flag_get_i(core->flags, fcni->addr);
2523  if (iteration == 0) {
2524  char *msg = flag ? strdup(flag->name) : rz_str_newf("0x%08" PFMT64x, fcni->addr);
2525  rz_cons_printf(" node [\n"
2526  " id %" PFMT64d "\n"
2527  " label \"%s\"\n"
2528  " ]\n",
2529  fcni->addr - base, msg);
2530  free(msg);
2531  }
2532  break;
2533  }
2534  case RZ_GRAPH_FORMAT_JSON:
2535  pj_o(pj);
2536  if (usenames) {
2537  pj_ks(pj, "name", fcni->name);
2538  } else {
2539  char fcni_addr[20];
2540  snprintf(fcni_addr, sizeof(fcni_addr) - 1, "0x%08" PFMT64x, fcni->addr);
2541  pj_ks(pj, "name", fcni_addr);
2542  }
2543  pj_kn(pj, "size", rz_analysis_function_linear_size(fcni));
2544  pj_ka(pj, "imports");
2545  break;
2546  case RZ_GRAPH_FORMAT_DOT:
2547  rz_cons_printf(" \"0x%08" PFMT64x "\" "
2548  "[label=\"%s\""
2549  " URL=\"%s/0x%08" PFMT64x "\"];\n",
2550  fcni->addr, fcni->name,
2551  fcni->name, fcni->addr);
2552  }
2553  rz_list_foreach (calls, iter2, fcnr) {
2554  // TODO: display only code or data refs?
2555  RzFlagItem *flag = rz_flag_get_i(core->flags, fcnr->to);
2556  char *fcnr_name = (flag && flag->name) ? flag->name : rz_str_newf("unk.0x%" PFMT64x, fcnr->to);
2557  switch (fmt) {
2559  if (iteration == 0) {
2560  rz_cons_printf(" node [\n"
2561  " id %" PFMT64d "\n"
2562  " label \"%s\"\n"
2563  " ]\n",
2564  fcnr->to - base, fcnr_name);
2565  rz_cons_printf(" edge [\n"
2566  " source %" PFMT64d "\n"
2567  " target %" PFMT64d "\n"
2568  " ]\n",
2569  fcni->addr - base, fcnr->to - base);
2570  }
2571  // fallthrough
2572  case RZ_GRAPH_FORMAT_GML:
2573  if (iteration != 0) {
2574  rz_cons_printf(" edge [\n"
2575  " source %" PFMT64d "\n"
2576  " target %" PFMT64d "\n"
2577  " ]\n",
2578  fcni->addr - base, fcnr->to - base); //, "#000000"
2579  }
2580  break;
2581  case RZ_GRAPH_FORMAT_DOT:
2582  rz_cons_printf(" \"0x%08" PFMT64x "\" -> \"0x%08" PFMT64x "\" "
2583  "[color=\"%s\" URL=\"%s/0x%08" PFMT64x "\"];\n",
2584  //"[label=\"%s\" color=\"%s\" URL=\"%s/0x%08"PFMT64x"\"];\n",
2585  fcni->addr, fcnr->to, //, fcnr_name,
2586  "#61afef",
2587  fcnr_name, fcnr->to);
2588  rz_cons_printf(" \"0x%08" PFMT64x "\" "
2589  "[label=\"%s\""
2590  " URL=\"%s/0x%08" PFMT64x "\"];\n",
2591  fcnr->to, fcnr_name,
2592  fcnr_name, fcnr->to);
2593  break;
2594  case RZ_GRAPH_FORMAT_JSON:
2595  if (usenames) {
2596  pj_s(pj, fcnr_name);
2597  } else {
2598  char fcnr_addr[20];
2599  snprintf(fcnr_addr, sizeof(fcnr_addr) - 1, "0x%08" PFMT64x, fcnr->to);
2600  pj_s(pj, fcnr_addr);
2601  }
2602  break;
2603  default:
2604  if (refgraph || fcnr->type == RZ_ANALYSIS_XREF_TYPE_CALL) {
2605  // TODO: avoid recreating nodes unnecessarily
2606  rz_cons_printf("agn %s\n", fcni->name);
2607  rz_cons_printf("agn %s\n", fcnr_name);
2608  rz_cons_printf("age %s %s\n", fcni->name, fcnr_name);
2609  } else {
2610  rz_cons_printf("# - 0x%08" PFMT64x " (%c)\n", fcnr->to, fcnr->type);
2611  }
2612  }
2613  if (!(flag && flag->name)) {
2614  free(fcnr_name);
2615  }
2616  }
2617  rz_list_free(xrefs);
2618  rz_list_free(calls);
2619  if (fmt == RZ_GRAPH_FORMAT_JSON) {
2620  pj_end(pj);
2621  pj_end(pj);
2622  }
2623  }
2624  if (iteration == 0 && fmt == RZ_GRAPH_FORMAT_GML) {
2625  iteration++;
2626  goto repeat;
2627  }
2628  if (iteration == 0 && fmt == RZ_GRAPH_FORMAT_GMLFCN) {
2629  iteration++;
2630  }
2631  switch (fmt) {
2632  case RZ_GRAPH_FORMAT_GML:
2634  rz_cons_printf("]\n");
2635  break;
2636  case RZ_GRAPH_FORMAT_JSON:
2637  pj_end(pj);
2639  pj_free(pj);
2640  break;
2641  case RZ_GRAPH_FORMAT_DOT:
2642  rz_cons_printf("}\n");
2643  break;
2644  }
2645 }
static int RzAnalysisRef_cmp(const RzAnalysisXRef *xref1, const RzAnalysisXRef *xref2)
Definition: canalysis.c:2421
RZ_API void rz_cons_println(const char *str)
Definition: cons.c:233
static void repeat(struct parse *, sopno, int, int)
Definition: regcomp.c:1155
#define RZ_GRAPH_FORMAT_JSON
Definition: rz_core.h:78
#define RZ_GRAPH_FORMAT_DOT
Definition: rz_core.h:80
#define RZ_GRAPH_FORMAT_GML
Definition: rz_core.h:79
#define RZ_GRAPH_FORMAT_NO
Definition: rz_core.h:76
#define RZ_GRAPH_FORMAT_GMLFCN
Definition: rz_core.h:77
RZ_API PJ * pj_ka(PJ *j, const char *k)
Definition: pj.c:163
RZ_API PJ * pj_new(void)
Definition: pj.c:25
RZ_API const char * pj_string(PJ *pj)
Definition: pj.c:57
RZ_API void pj_free(PJ *j)
Definition: pj.c:34
RZ_API PJ * pj_s(PJ *j, const char *k)
Definition: pj.c:197
static struct sockaddr static addrlen static backlog const void msg
Definition: sfsocketcall.h:119

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, rz_core_t::config, rz_analysis_t::fcns, rz_core_t::flags, free(), from, rz_cons_t::is_html, msg, rz_analysis_function_t::name, rz_flag_item_t::name, NULL, PFMT64d, PFMT64x, pj_a(), pj_end(), pj_free(), pj_ka(), pj_kn(), pj_ks(), pj_new(), pj_o(), pj_s(), pj_string(), repeat(), rz_analysis_function_get_xrefs_from(), rz_analysis_function_linear_size(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_config_get(), rz_config_get_i(), rz_cons_printf(), rz_cons_println(), rz_cons_singleton(), rz_flag_get_i(), RZ_GRAPH_FORMAT_DOT, RZ_GRAPH_FORMAT_GML, RZ_GRAPH_FORMAT_GMLFCN, RZ_GRAPH_FORMAT_JSON, RZ_GRAPH_FORMAT_NO, rz_list_append(), rz_list_find(), rz_list_free(), rz_list_new(), rz_str_newf(), RzAnalysisRef_cmp(), snprintf, strdup(), rz_analysis_ref_t::to, to, rz_analysis_ref_t::type, ut64(), and UT64_MAX.

Referenced by cmd_analysis_graph().

◆ rz_core_analysis_calls_count()

RZ_API st64 rz_core_analysis_calls_count ( RZ_NONNULL RzCore core)

Compute analysis function xrefs count.

Definition at line 7115 of file canalysis.c.

7115  {
7116  rz_return_val_if_fail(core && core->analysis, ST64_MAX);
7117  RzListIter *iter;
7118  RzAnalysisFunction *fcn;
7119  st64 cov = 0;
7120  rz_list_foreach (core->analysis->fcns, iter, fcn) {
7122  if (xrefs) {
7123  cov += rz_list_length(xrefs);
7124  rz_list_free(xrefs);
7125  }
7126  }
7127  return cov;
7128 }
#define ST64_MAX
Definition: rz_types_base.h:84

References rz_core_t::analysis, core_noretl::core, rz_analysis_t::fcns, rz_analysis_function_get_xrefs_from(), rz_list_free(), rz_list_length(), rz_return_val_if_fail, st64, and ST64_MAX.

Referenced by rz_print_analysis_details_handler().

◆ rz_core_analysis_cc_init()

RZ_API void rz_core_analysis_cc_init ( RzCore core)

Definition at line 6628 of file canalysis.c.

6628  {
6629  const char *analysis_arch = rz_config_get(core->config, "analysis.arch");
6630  Sdb *cc = core->analysis->sdb_cc;
6631  if (!strcmp(analysis_arch, "null")) {
6632  sdb_reset(cc);
6633  RZ_FREE(cc->path);
6634  return;
6635  }
6636 
6637  int bits = core->analysis->bits;
6638  char *types_dir = rz_path_system(RZ_SDB_TYPES);
6639  char *home_types_dir = rz_path_home_prefix(RZ_SDB_TYPES);
6640  char buf[40];
6641  char *dbpath = rz_file_path_join(types_dir, rz_strf(buf, "cc-%s-%d.sdb", analysis_arch, bits));
6642  char *dbhomepath = rz_file_path_join(home_types_dir, rz_strf(buf, "cc-%s-%d.sdb", analysis_arch, bits));
6643  free(types_dir);
6644  free(home_types_dir);
6645 
6646  // Avoid sdb reloading
6647  if (cc->path && (!strcmp(cc->path, dbpath) || !strcmp(cc->path, dbhomepath))) {
6648  free(dbpath);
6649  free(dbhomepath);
6650  return;
6651  }
6652  sdb_reset(cc);
6653  RZ_FREE(cc->path);
6654  if (rz_file_exists(dbpath)) {
6655  sdb_concat_by_path(cc, dbpath);
6656  cc->path = strdup(dbpath);
6657  }
6658  if (rz_file_exists(dbhomepath)) {
6659  sdb_concat_by_path(cc, dbhomepath);
6660  cc->path = strdup(dbhomepath);
6661  }
6662  // same as "tcc `arcc`"
6663  char *s = rz_reg_profile_to_cc(core->analysis->reg);
6664  if (s) {
6665  if (!rz_analysis_cc_set(core->analysis, s)) {
6666  eprintf("Warning: Invalid CC from reg profile.\n");
6667  }
6668  free(s);
6669  } else {
6670  eprintf("Warning: Cannot derive CC from reg profile.\n");
6671  }
6672  if (sdb_isempty(core->analysis->sdb_cc)) {
6673  eprintf("Warning: Missing calling conventions for '%s'. Deriving it from the regprofile.\n", analysis_arch);
6674  }
6675  free(dbpath);
6676  free(dbhomepath);
6677 }
static void sdb_concat_by_path(Sdb *s, const char *path)
Definition: canalysis.c:6621
RZ_API bool rz_analysis_cc_set(RzAnalysis *analysis, const char *expr)
Definition: cc.c:25
RZ_API char * rz_reg_profile_to_cc(RzReg *reg)
Definition: profile.c:652
RZ_API bool rz_file_exists(const char *str)
Definition: file.c:192
RZ_API RZ_OWN char * rz_file_path_join(RZ_NONNULL const char *s1, RZ_NULLABLE const char *s2)
Concatenate two paths to create a new one with s1+s2 with the correct path separator.
Definition: file.c:1312
RZ_API RZ_OWN char * rz_path_home_prefix(RZ_NULLABLE const char *path)
Return path prefixed by the home prefix.
Definition: path.c:182
RZ_API RZ_OWN char * rz_path_system(RZ_NULLABLE const char *path)
Return the full system path of the given subpath path.
Definition: path.c:162
#define RZ_SDB_TYPES
Definition: rz_userconf.h:83
RZ_API bool sdb_isempty(Sdb *s)
Definition: sdb.c:148
RZ_API void sdb_reset(Sdb *s)
Definition: sdb.c:433

References rz_core_t::analysis, rz_analysis_t::bits, bits(), rz_core_t::config, core_noretl::core, eprintf, free(), sdb_t::path, rz_analysis_t::reg, rz_analysis_cc_set(), rz_config_get(), rz_file_exists(), rz_file_path_join(), RZ_FREE, rz_path_home_prefix(), rz_path_system(), rz_reg_profile_to_cc(), RZ_SDB_TYPES, rz_strf, s, rz_analysis_t::sdb_cc, sdb_concat_by_path(), sdb_isempty(), sdb_reset(), and strdup().

Referenced by cb_asmarch(), cb_asmbits(), cb_asmos(), and rz_core_bin_apply_config().

◆ rz_core_analysis_cc_print()

RZ_IPI void rz_core_analysis_cc_print ( RzCore core,
RZ_NONNULL const char *  cc,
RZ_NULLABLE PJ pj 
)

Print Calling Convention info.

Parameters
coreThe RzCore instance
ccCalling Convention name
pjOptional PJ instance for JSON mode

Definition at line 6686 of file canalysis.c.

6686  {
6687  rz_return_if_fail(core && cc);
6688  if (pj) {
6689  pj_o(pj);
6690  }
6691  if (pj) {
6692  pj_ks(pj, "name", cc);
6693  } else {
6694  rz_cons_printf("name: %s\n", cc);
6695  }
6696  const char *regname = rz_analysis_cc_ret(core->analysis, cc);
6697  if (regname) {
6698  if (pj) {
6699  pj_ks(pj, "ret", regname);
6700  } else {
6701  rz_cons_printf("ret: %s\n", regname);
6702  }
6703  }
6704  if (pj) {
6705  pj_ka(pj, "args");
6706  }
6707  int maxargs = rz_analysis_cc_max_arg(core->analysis, cc);
6708  for (int i = 0; i < maxargs; i++) {
6709  regname = rz_analysis_cc_arg(core->analysis, cc, i);
6710  if (pj) {
6711  pj_s(pj, regname);
6712  } else {
6713  rz_cons_printf("arg%d: %s\n", i, regname);
6714  }
6715  }
6716  if (pj) {
6717  pj_end(pj);
6718  }
6719  regname = rz_analysis_cc_self(core->analysis, cc);
6720  if (regname) {
6721  if (pj) {
6722  pj_ks(pj, "self", regname);
6723  } else {
6724  rz_cons_printf("self: %s\n", regname);
6725  }
6726  }
6727  regname = rz_analysis_cc_error(core->analysis, cc);
6728  if (regname) {
6729  if (pj) {
6730  pj_ks(pj, "error", regname);
6731  } else {
6732  rz_cons_printf("error: %s\n", regname);
6733  }
6734  }
6735  if (pj) {
6736  pj_end(pj);
6737  }
6738 }
RZ_API const char * rz_analysis_cc_arg(RzAnalysis *analysis, const char *convention, int n)
Definition: cc.c:122
RZ_API const char * rz_analysis_cc_self(RzAnalysis *analysis, const char *convention)
Definition: cc.c:138
RZ_API const char * rz_analysis_cc_error(RzAnalysis *analysis, const char *convention)
Definition: cc.c:155
RZ_API const char * rz_analysis_cc_ret(RzAnalysis *analysis, const char *convention)
Definition: cc.c:194

References rz_core_t::analysis, core_noretl::core, i, pj_end(), pj_ka(), pj_ks(), pj_o(), pj_s(), regname(), rz_analysis_cc_arg(), rz_analysis_cc_error(), rz_analysis_cc_max_arg(), rz_analysis_cc_ret(), rz_analysis_cc_self(), rz_cons_printf(), and rz_return_if_fail.

Referenced by rz_analysis_function_cc_reg_usage_handler(), and rz_core_types_calling_conventions_print().

◆ rz_core_analysis_code_count()

RZ_API st64 rz_core_analysis_code_count ( RZ_NONNULL RzCore core)

Compute analysis code count.

Definition at line 7098 of file canalysis.c.

7098  {
7100  st64 code = 0;
7101  void **it;
7102  RzPVector *maps = rz_io_maps(core->io);
7103  rz_pvector_foreach (maps, it) {
7104  RzIOMap *map = *it;
7105  if (map->perm & RZ_PERM_X) {
7106  code += (st64)map->itv.size;
7107  }
7108  }
7109  return code;
7110 }
const char * code
Definition: pal.c:98

References code, core_noretl::core, rz_core_t::io, map(), maps(), rz_io_maps(), RZ_PERM_X, rz_pvector_foreach, rz_return_val_if_fail, st64, and ST64_MAX.

Referenced by rz_print_analysis_details_handler().

◆ rz_core_analysis_coderefs()

RZ_API void rz_core_analysis_coderefs ( RzCore core,
ut64  addr 
)

Definition at line 2342 of file canalysis.c.

2342  {
2344  if (fcn) {
2345  const char *me = fcn->name;
2346  RzListIter *iter;
2347  RzAnalysisXRef *xref;
2349  rz_cons_printf("agn %s\n", me);
2350  rz_list_foreach (xrefs, iter, xref) {
2351  RzFlagItem *item = rz_flag_get_i(core->flags, xref->to);
2352  const char *dst = item ? item->name : sdb_fmt("0x%08" PFMT64x, xref->from);
2353  rz_cons_printf("agn %s\n", dst);
2354  rz_cons_printf("age %s %s\n", me, dst);
2355  }
2356  rz_list_free(xrefs);
2357  } else {
2358  eprintf("Not in a function. Use 'df' to define it.\n");
2359  }
2360 }
char * dst
Definition: lz4.h:724

References addr, rz_core_t::analysis, dst, eprintf, rz_core_t::flags, rz_analysis_ref_t::from, rz_analysis_function_t::name, rz_flag_item_t::name, PFMT64x, rz_analysis_function_get_xrefs_from(), rz_analysis_get_fcn_in(), rz_cons_printf(), rz_flag_get_i(), rz_list_free(), sdb_fmt(), and rz_analysis_ref_t::to.

Referenced by cmd_analysis_graph().

◆ rz_core_analysis_codexrefs()

RZ_API RzGraph* rz_core_analysis_codexrefs ( RzCore core,
ut64  addr 
)

Definition at line 2412 of file canalysis.c.

2412  {
2413  RzGraph *graph = rz_graph_new();
2414  if (!graph) {
2415  return NULL;
2416  }
2417  add_single_addr_xrefs(core, addr, graph);
2418  return graph;
2419 }
static void add_single_addr_xrefs(RzCore *core, ut64 addr, RzGraph *graph)
Definition: canalysis.c:2362
RZ_API RzGraph * rz_graph_new(void)
Definition: graph.c:108

References add_single_addr_xrefs(), addr, NULL, and rz_graph_new().

Referenced by cmd_analysis_graph().

◆ rz_core_analysis_continue_until_call()

RZ_API bool rz_core_analysis_continue_until_call ( RZ_NONNULL RzCore core)

Continue until call.

Parameters
coreThe RzCore instance
Returns
success

Definition at line 7041 of file canalysis.c.

7041  {
7042  rz_return_val_if_fail(core, false);
7043  const char *pc = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
7044  RzAnalysisOp *op = NULL;
7045  while (!rz_cons_is_breaked()) {
7046  if (!rz_core_esil_step(core, UT64_MAX, NULL, NULL, false)) {
7047  break;
7048  }
7050  ut64 addr = rz_num_get(core->num, pc);
7052  if (!op) {
7053  break;
7054  }
7055  if (op->type == RZ_ANALYSIS_OP_TYPE_CALL || op->type == RZ_ANALYSIS_OP_TYPE_UCALL) {
7056  RZ_LOG_ERROR("call at 0x%08" PFMT64x "\n", addr);
7057  break;
7058  }
7060  op = NULL;
7061  if (core->analysis->esil->trap || core->analysis->esil->trap_code) {
7062  break;
7063  }
7064  }
7066  return true;
7067 }
RZ_API int rz_core_esil_step(RzCore *core, ut64 until_addr, const char *until_expr, ut64 *prev_addr, bool stepOver)
Definition: cmd_analysis.c:860
RZ_API void rz_core_reg_update_flags(RzCore *core)
Update or create flags for all registers where it makes sense.
Definition: creg.c:106
@ RZ_ANALYSIS_OP_TYPE_UCALL
Definition: rz_analysis.h:379
RZ_API ut64 rz_num_get(RzNum *num, const char *str)
Definition: unum.c:172
@ RZ_REG_NAME_PC
Definition: rz_reg.h:43

References addr, rz_core_t::analysis, core_noretl::core, rz_analysis_t::esil, NULL, rz_core_t::num, pc, PFMT64x, rz_analysis_t::reg, rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_UCALL, rz_cons_is_breaked(), rz_core_analysis_op(), rz_core_esil_step(), rz_core_reg_update_flags(), RZ_LOG_ERROR, rz_num_get(), rz_reg_get_name(), RZ_REG_NAME_PC, rz_return_val_if_fail, rz_analysis_esil_t::trap, rz_analysis_esil_t::trap_code, ut64(), and UT64_MAX.

Referenced by rz_analysis_continue_until_call_handler().

◆ rz_core_analysis_continue_until_syscall()

RZ_API bool rz_core_analysis_continue_until_syscall ( RZ_NONNULL RzCore core)

Continue until syscall.

Parameters
coreThe RzCore instance
Returns
success

Definition at line 7005 of file canalysis.c.

7005  {
7006  rz_return_val_if_fail(core, false);
7007  const char *pc = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
7008  RzAnalysisOp *op = NULL;
7009  while (!rz_cons_is_breaked()) {
7010  if (!rz_core_esil_step(core, UT64_MAX, NULL, NULL, false)) {
7011  break;
7012  }
7014  ut64 addr = rz_num_get(core->num, pc);
7016  if (!op) {
7017  break;
7018  }
7019  if (op->type == RZ_ANALYSIS_OP_TYPE_SWI) {
7020  RZ_LOG_ERROR("syscall at 0x%08" PFMT64x "\n", addr);
7021  break;
7022  } else if (op->type == RZ_ANALYSIS_OP_TYPE_TRAP) {
7023  RZ_LOG_ERROR("trap at 0x%08" PFMT64x "\n", addr);
7024  break;
7025  }
7027  op = NULL;
7028  if (core->analysis->esil->trap || core->analysis->esil->trap_code) {
7029  break;
7030  }
7031  }
7033  return true;
7034 }
@ RZ_ANALYSIS_OP_TYPE_SWI
Definition: rz_analysis.h:393
@ RZ_ANALYSIS_OP_TYPE_TRAP
Definition: rz_analysis.h:392

References addr, rz_core_t::analysis, core_noretl::core, rz_analysis_t::esil, NULL, rz_core_t::num, pc, PFMT64x, rz_analysis_t::reg, rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_TYPE_SWI, RZ_ANALYSIS_OP_TYPE_TRAP, rz_cons_is_breaked(), rz_core_analysis_op(), rz_core_esil_step(), rz_core_reg_update_flags(), RZ_LOG_ERROR, rz_num_get(), rz_reg_get_name(), RZ_REG_NAME_PC, rz_return_val_if_fail, rz_analysis_esil_t::trap, rz_analysis_esil_t::trap_code, ut64(), and UT64_MAX.

Referenced by rz_analysis_continue_until_syscall_handler().

◆ rz_core_analysis_coverage_count()

RZ_API st64 rz_core_analysis_coverage_count ( RZ_NONNULL RzCore core)

Compute analysis coverage count.

Definition at line 7072 of file canalysis.c.

7072  {
7073  rz_return_val_if_fail(core && core->analysis, ST64_MAX);
7074  RzListIter *iter;
7075  RzAnalysisFunction *fcn;
7076  st64 cov = 0;
7077  cov += (st64)rz_meta_get_size(core->analysis, RZ_META_TYPE_DATA);
7078  rz_list_foreach (core->analysis->fcns, iter, fcn) {
7079  void **it;
7080  RzPVector *maps = rz_io_maps(core->io);
7081  rz_pvector_foreach (maps, it) {
7082  RzIOMap *map = *it;
7083  if (map->perm & RZ_PERM_X) {
7084  ut64 section_end = map->itv.addr + map->itv.size;
7086  if (fcn->addr >= map->itv.addr && (fcn->addr + s) < section_end) {
7087  cov += (st64)s;
7088  }
7089  }
7090  }
7091  }
7092  return cov;
7093 }
RZ_API ut64 rz_meta_get_size(RzAnalysis *a, RzAnalysisMetaType type)
Definition: meta.c:278

References rz_analysis_function_t::addr, rz_core_t::analysis, core_noretl::core, rz_analysis_t::fcns, rz_core_t::io, map(), maps(), rz_analysis_function_realsize(), rz_io_maps(), rz_meta_get_size(), RZ_META_TYPE_DATA, RZ_PERM_X, rz_pvector_foreach, rz_return_val_if_fail, s, st64, ST64_MAX, and ut64().

Referenced by rz_print_analysis_details_handler().

◆ rz_core_analysis_cycles()

RZ_API RzList* rz_core_analysis_cycles ( RzCore core,
int  ccl 
)

Definition at line 3847 of file canalysis.c.

3847  {
3848  ut64 addr = core->offset;
3849  int depth = 0;
3850  RzAnalysisOp *op = NULL;
3851  RzAnalysisCycleFrame *prev = NULL, *cf = NULL;
3852  RzAnalysisCycleHook *ch;
3853  RzList *hooks = rz_list_new();
3854  if (!hooks) {
3855  return NULL;
3856  }
3859  while (cf && !rz_cons_is_breaked()) {
3860  if ((op = rz_core_analysis_op(core, addr, RZ_ANALYSIS_OP_MASK_BASIC)) && (op->cycles) && (ccl > 0)) {
3861  rz_cons_clear_line(1);
3862  eprintf("%i -- ", ccl);
3863  addr += op->size;
3864  switch (op->type) {
3866  addr = op->jump;
3867  ccl -= op->cycles;
3868  loganalysis(op->addr, addr, depth);
3869  break;
3877  ch->addr = op->addr;
3878  eprintf("0x%08" PFMT64x " > ?\r", op->addr);
3879  ch->cycles = ccl;
3880  rz_list_append(hooks, ch);
3881  ch = NULL;
3882  while (!ch && cf) {
3883  ch = rz_list_pop(cf->hooks);
3884  if (ch) {
3885  addr = ch->addr;
3886  ccl = ch->cycles;
3887  free(ch);
3888  } else {
3890  cf = prev;
3891  if (cf) {
3892  prev = cf->prev;
3893  }
3894  }
3895  }
3896  break;
3899  ch->addr = addr;
3900  ch->cycles = ccl - op->failcycles;
3901  rz_list_push(cf->hooks, ch);
3902  ch = NULL;
3903  addr = op->jump;
3904  loganalysis(op->addr, addr, depth);
3905  break;
3909  ch->addr = op->addr;
3910  ch->cycles = ccl;
3911  rz_list_append(hooks, ch);
3912  ch = NULL;
3913  ccl -= op->failcycles;
3914  eprintf("0x%08" PFMT64x " > ?\r", op->addr);
3915  break;
3918  ch->addr = addr;
3919  ch->cycles = ccl - op->failcycles;
3920  rz_list_push(cf->hooks, ch);
3921  ch = NULL;
3922  // fallthrough
3924  if (op->addr != op->jump) { // no selfies
3925  cf->naddr = addr;
3926  prev = cf;
3928  cf->prev = prev;
3929  }
3930  ccl -= op->cycles;
3931  addr = op->jump;
3932  loganalysis(op->addr, addr, depth - 1);
3933  break;
3936  if (prev) {
3937  ch->addr = prev->naddr;
3938  ccl -= op->cycles;
3939  ch->cycles = ccl;
3940  rz_list_push(prev->hooks, ch);
3941  eprintf("0x%08" PFMT64x " < 0x%08" PFMT64x "\r", prev->naddr, op->addr);
3942  } else {
3943  ch->addr = op->addr;
3944  ch->cycles = ccl;
3945  rz_list_append(hooks, ch);
3946  eprintf("? < 0x%08" PFMT64x "\r", op->addr);
3947  }
3948  ch = NULL;
3949  while (!ch && cf) {
3950  ch = rz_list_pop(cf->hooks);
3951  if (ch) {
3952  addr = ch->addr;
3953  ccl = ch->cycles;
3954  free(ch);
3955  } else {
3957  cf = prev;
3958  if (cf) {
3959  prev = cf->prev;
3960  }
3961  }
3962  }
3963  break;
3966  if (prev) {
3967  ch->addr = prev->naddr;
3968  ch->cycles = ccl - op->cycles;
3969  rz_list_push(prev->hooks, ch);
3970  eprintf("0x%08" PFMT64x " < 0x%08" PFMT64x "\r", prev->naddr, op->addr);
3971  } else {
3972  ch->addr = op->addr;
3973  ch->cycles = ccl - op->cycles;
3974  rz_list_append(hooks, ch);
3975  eprintf("? < 0x%08" PFMT64x "\r", op->addr);
3976  }
3977  ccl -= op->failcycles;
3978  break;
3979  default:
3980  ccl -= op->cycles;
3981  eprintf("0x%08" PFMT64x "\r", op->addr);
3982  break;
3983  }
3984  } else {
3986  if (!ch) {
3988  rz_list_free(hooks);
3989  return NULL;
3990  }
3991  ch->addr = addr;
3992  ch->cycles = ccl;
3993  rz_list_append(hooks, ch);
3994  ch = NULL;
3995  while (!ch && cf) {
3996  ch = rz_list_pop(cf->hooks);
3997  if (ch) {
3998  addr = ch->addr;
3999  ccl = ch->cycles;
4000  free(ch);
4001  } else {
4003  cf = prev;
4004  if (cf) {
4005  prev = cf->prev;
4006  }
4007  }
4008  }
4009  }
4011  }
4012  if (rz_cons_is_breaked()) {
4013  while (cf) {
4014  ch = rz_list_pop(cf->hooks);
4015  while (ch) {
4016  free(ch);
4017  ch = rz_list_pop(cf->hooks);
4018  }
4019  prev = cf->prev;
4021  cf = prev;
4022  }
4023  }
4025  return hooks;
4026 }
RZ_API void rz_analysis_cycle_frame_free(RzAnalysisCycleFrame *cf)
Definition: cycles.c:18
RZ_API RzAnalysisCycleFrame * rz_analysis_cycle_frame_new(void)
Definition: cycles.c:8
@ RZ_ANALYSIS_OP_TYPE_ICALL
Definition: rz_analysis.h:381
@ RZ_ANALYSIS_OP_TYPE_UJMP
Definition: rz_analysis.h:369
@ RZ_ANALYSIS_OP_TYPE_UCCALL
Definition: rz_analysis.h:384
@ RZ_ANALYSIS_OP_TYPE_MJMP
Definition: rz_analysis.h:375
@ RZ_ANALYSIS_OP_TYPE_CJMP
Definition: rz_analysis.h:373
@ RZ_ANALYSIS_OP_TYPE_UCJMP
Definition: rz_analysis.h:377
@ RZ_ANALYSIS_OP_TYPE_IRCALL
Definition: rz_analysis.h:382
struct rz_analysis_cycle_frame_t * prev
Definition: rz_analysis.h:926

References addr, rz_analysis_cycle_hook_t::addr, rz_analysis_cycle_hook_t::cycles, eprintf, free(), rz_analysis_cycle_frame_t::hooks, loganalysis(), rz_analysis_cycle_frame_t::naddr, NULL, rz_core_t::offset, PFMT64x, rz_analysis_cycle_frame_t::prev, rz_analysis_cycle_frame_free(), rz_analysis_cycle_frame_new(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CRET, RZ_ANALYSIS_OP_TYPE_ICALL, RZ_ANALYSIS_OP_TYPE_IRCALL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_MJMP, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UCCALL, RZ_ANALYSIS_OP_TYPE_UCJMP, RZ_ANALYSIS_OP_TYPE_UJMP, rz_cons_break_pop(), rz_cons_break_push(), rz_cons_clear_line(), rz_cons_is_breaked(), rz_core_analysis_op(), rz_list_append(), rz_list_free(), rz_list_new(), rz_list_pop(), rz_list_push(), RZ_NEW0, and ut64().

Referenced by rz_analyze_cycles_handler().

◆ rz_core_analysis_data()

RZ_API int rz_core_analysis_data ( RzCore core,
ut64  addr,
int  count,
int  depth,
int  wordsize 
)

Definition at line 3635 of file canalysis.c.

3635  {
3636  RzAnalysisData *d;
3637  ut64 dstaddr = 0LL;
3638  ut8 *buf = core->block;
3639  int len = core->blocksize;
3640  int word = wordsize ? wordsize : core->rasm->bits / 8;
3641  char *str;
3642  int i, j;
3643 
3644  count = RZ_MIN(count, len);
3645  buf = malloc(len + 1);
3646  if (!buf) {
3647  return false;
3648  }
3649  memset(buf, 0xff, len);
3650  rz_io_read_at(core->io, addr, buf, len);
3651  buf[len - 1] = 0;
3652 
3653  RzConsPrintablePalette *pal = rz_config_get_i(core->config, "scr.color") ? &rz_cons_singleton()->context->pal : NULL;
3654  for (i = j = 0; j < count; j++) {
3655  if (i >= len) {
3656  rz_io_read_at(core->io, addr + i, buf, len);
3657  buf[len] = 0;
3658  addr += i;
3659  i = 0;
3660  continue;
3661  }
3662  /* rz_analysis_data requires null-terminated buffer according to coverity */
3663  /* but it should not.. so this must be fixed in analysis/data.c instead of */
3664  /* null terminating here */
3665  d = rz_analysis_data(core->analysis, addr + i, buf + i, len - i, wordsize);
3668 
3669  if (d) {
3670  switch (d->type) {
3672  rz_cons_printf("`- ");
3673  dstaddr = rz_mem_get_num(buf + i, word);
3674  if (depth > 0) {
3675  rz_core_analysis_data(core, dstaddr, 1, depth - 1, wordsize);
3676  }
3677  i += word;
3678  break;
3680  buf[len - 1] = 0;
3681  i += strlen((const char *)buf + i) + 1;
3682  break;
3683  default:
3684  i += (d->len > 3) ? d->len : word;
3685  break;
3686  }
3687  } else {
3688  i += word;
3689  }
3690  free(str);
3692  }
3693  free(buf);
3694  return true;
3695 }
RZ_API int rz_core_analysis_data(RzCore *core, ut64 addr, int count, int depth, int wordsize)
Definition: canalysis.c:3635
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void count
Definition: sflib.h:98
RZ_API RzAnalysisData * rz_analysis_data(RzAnalysis *analysis, ut64 addr, const ut8 *buf, int size, int wordsize)
Definition: data.c:283
RZ_API void rz_analysis_data_free(RzAnalysisData *d)
Definition: data.c:273
RZ_API char * rz_analysis_data_to_string(RzAnalysisData *d, RzConsPrintablePalette *pal)
Definition: data.c:104
return memset(p, 0, total)
@ RZ_ANALYSIS_DATA_TYPE_STRING
Definition: rz_analysis.h:74
@ RZ_ANALYSIS_DATA_TYPE_POINTER
Definition: rz_analysis.h:76
RZ_API ut64 rz_mem_get_num(const ut8 *b, int size)
Definition: mem.c:152
#define d(i)
Definition: sha256.c:44
RzConsPrintablePalette pal
Definition: rz_cons.h:491
RzConsContext * context
Definition: rz_cons.h:502
ut8 * block
Definition: rz_core.h:305

References addr, rz_core_t::analysis, rz_asm_t::bits, rz_core_t::block, rz_core_t::blocksize, rz_core_t::config, rz_cons_t::context, count, d, free(), i, rz_core_t::io, len, malloc(), memset(), NULL, rz_cons_context_t::pal, rz_core_t::rasm, rz_analysis_data(), rz_analysis_data_free(), rz_analysis_data_to_string(), RZ_ANALYSIS_DATA_TYPE_POINTER, RZ_ANALYSIS_DATA_TYPE_STRING, rz_config_get_i(), rz_cons_printf(), rz_cons_println(), rz_cons_singleton(), rz_io_read_at(), rz_mem_get_num(), RZ_MIN, cmd_descs_generate::str, and ut64().

Referenced by rz_cmd_analysis().

◆ rz_core_analysis_datarefs()

RZ_API void rz_core_analysis_datarefs ( RzCore core,
ut64  addr 
)

Definition at line 2314 of file canalysis.c.

2314  {
2316  if (fcn) {
2317  bool found = false;
2318  const char *me = fcn->name;
2319  RzListIter *iter;
2320  RzAnalysisXRef *xref;
2322  rz_list_foreach (xrefs, iter, xref) {
2323  RzBinObject *obj = rz_bin_cur_object(core->bin);
2324  RzBinSection *binsec = rz_bin_get_section_at(obj, xref->to, true);
2325  if (binsec && binsec->is_data) {
2326  if (!found) {
2327  rz_cons_printf("agn %s\n", me);
2328  found = true;
2329  }
2330  RzFlagItem *item = rz_flag_get_i(core->flags, xref->to);
2331  const char *dst = item ? item->name : sdb_fmt("0x%08" PFMT64x, xref->to);
2332  rz_cons_printf("agn %s\n", dst);
2333  rz_cons_printf("age %s %s\n", me, dst);
2334  }
2335  }
2336  rz_list_free(xrefs);
2337  } else {
2338  eprintf("Not in a function. Use 'df' to define it.\n");
2339  }
2340 }
RZ_API RZ_BORROW RzBinSection * rz_bin_get_section_at(RzBinObject *o, ut64 off, int va)
Find the binary section at offset off.
Definition: bin.c:611

References addr, rz_core_t::analysis, rz_core_t::bin, dst, eprintf, rz_core_t::flags, found, rz_bin_section_t::is_data, rz_analysis_function_t::name, rz_flag_item_t::name, PFMT64x, rz_analysis_function_get_xrefs_from(), rz_analysis_get_fcn_in(), rz_bin_cur_object(), rz_bin_get_section_at(), rz_cons_printf(), rz_flag_get_i(), rz_list_free(), sdb_fmt(), and rz_analysis_ref_t::to.

Referenced by cmd_analysis_graph().

◆ rz_core_analysis_esil()

RZ_API void rz_core_analysis_esil ( RzCore core,
ut64  addr,
ut64  size,
RZ_NULLABLE RzAnalysisFunction fcn 
)

Analyze references with esil (aae)

addr start address size number of bytes to analyze fcn optional, when analyzing for a specific function

Definition at line 4499 of file canalysis.c.

4499  {
4500  bool cfg_analysis_strings = rz_config_get_i(core->config, "analysis.strings");
4501  bool emu_lazy = rz_config_get_i(core->config, "emu.lazy");
4502  bool gp_fixed = rz_config_get_i(core->config, "analysis.gpfixed");
4503  ut64 refptr = 0LL;
4504  const char *pcname;
4506  ut8 *buf = NULL;
4507  int iend;
4508  int minopsize = 4; // XXX this depends on asm->mininstrsize
4509  bool archIsArm = false;
4510  ut64 start = addr;
4511  ut64 end = addr + size;
4512  if (end <= start) {
4513  return;
4514  }
4515  iend = end - start;
4516  if (iend < 0) {
4517  return;
4518  }
4519  if (iend > MAX_SCAN_SIZE) {
4520  eprintf("Warning: Not going to analyze 0x%08" PFMT64x " bytes.\n", (ut64)iend);
4521  return;
4522  }
4523  buf = malloc((size_t)iend + 2);
4524  if (!buf) {
4525  perror("malloc");
4526  return;
4527  }
4529  rz_io_read_at(core->io, start, buf, iend + 1);
4530  rz_reg_arena_push(core->analysis->reg);
4531 
4532  RzAnalysisEsil *ESIL = core->analysis->esil;
4533  if (!ESIL) {
4535  ESIL = core->analysis->esil;
4536  if (!ESIL) {
4537  eprintf("ESIL not initialized\n");
4538  goto out_pop_regs;
4539  }
4541  }
4542  const char *spname = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SP);
4543  EsilBreakCtx ctx = {
4544  &op,
4545  fcn,
4546  spname,
4547  rz_reg_getv(core->analysis->reg, spname)
4548  };
4549  ESIL->cb.hook_reg_write = &esilbreak_reg_write;
4550  // this is necessary for the hook to read the id of analop
4551  ESIL->user = &ctx;
4552  ESIL->cb.hook_mem_read = &esilbreak_mem_read;
4553  ESIL->cb.hook_mem_write = &esilbreak_mem_write;
4554 
4555  if (fcn && fcn->reg_save_area) {
4556  rz_reg_setv(core->analysis->reg, ctx.spname, ctx.initial_sp - fcn->reg_save_area);
4557  }
4558  // eprintf ("Analyzing ESIL refs from 0x%"PFMT64x" - 0x%"PFMT64x"\n", addr, end);
4559  // TODO: backup/restore register state before/after analysis
4560  pcname = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_PC);
4561  if (!pcname || !*pcname) {
4562  eprintf("Cannot find program counter register in the current profile.\n");
4563  goto out_pop_regs;
4564  }
4565  esil_analysis_stop = false;
4566  rz_cons_break_push(cccb, core);
4567 
4568  int arch = -1;
4569  if (!strcmp(core->analysis->cur->arch, "arm")) {
4570  switch (core->analysis->bits) {
4571  case 64: arch = RZ_ARCH_ARM64; break;
4572  case 32: arch = RZ_ARCH_ARM32; break;
4573  case 16: arch = RZ_ARCH_THUMB; break;
4574  }
4575  archIsArm = true;
4576  }
4577 
4578  ut64 gp = rz_config_get_i(core->config, "analysis.gp");
4579  const char *gp_reg = NULL;
4580  if (!strcmp(core->analysis->cur->arch, "mips")) {
4581  gp_reg = "gp";
4582  arch = RZ_ARCH_MIPS;
4583  }
4584 
4585  RZ_NULLABLE const char *sn = rz_reg_get_name(core->analysis->reg, RZ_REG_NAME_SN);
4586 
4587  IterCtx ictx = { start, end, fcn, NULL };
4588  size_t i = 0;
4589  do {
4591  break;
4592  }
4593  size_t i_old = i;
4594  ut64 cur = start + i;
4595  if (!rz_io_is_valid_offset(core->io, cur, 0)) {
4596  break;
4597  }
4598  {
4600  void **it;
4601  rz_pvector_foreach (list, it) {
4602  RzIntervalNode *node = *it;
4603  RzAnalysisMetaItem *meta = node->data;
4604  switch (meta->type) {
4605  case RZ_META_TYPE_DATA:
4606  case RZ_META_TYPE_STRING:
4607  case RZ_META_TYPE_FORMAT:
4608  i += 4;
4610  goto repeat;
4611  default:
4612  break;
4613  }
4614  }
4616  }
4617 
4618  /* realign address if needed */
4619  rz_core_seek_arch_bits(core, cur);
4620  int opalign = core->analysis->pcalign;
4621  if (opalign > 0) {
4622  cur -= (cur % opalign);
4623  }
4624 
4626  rz_asm_set_pc(core->rasm, cur);
4628  // if (op.type & 0x80000000 || op.type == 0) {
4629  if (op.type == RZ_ANALYSIS_OP_TYPE_ILL || op.type == RZ_ANALYSIS_OP_TYPE_UNK) {
4630  // i += 2
4632  goto repeat;
4633  }
4634  // we need to check again i because buf+i may goes beyond its boundaries
4635  // because of i+= minopsize - 1
4636  if (i > iend) {
4637  goto repeat;
4638  }
4639  if (op.size < 1) {
4640  i += minopsize - 1;
4641  goto repeat;
4642  }
4643  if (emu_lazy) {
4644  if (op.type & RZ_ANALYSIS_OP_TYPE_REP) {
4645  i += op.size - 1;
4646  goto repeat;
4647  }
4648  switch (op.type & RZ_ANALYSIS_OP_TYPE_MASK) {
4667  i += op.size - 1;
4668  goto repeat;
4669  // those require write support
4672  i += op.size - 1;
4673  goto repeat;
4674  }
4675  }
4676  if (sn && op.type == RZ_ANALYSIS_OP_TYPE_SWI) {
4677  rz_flag_space_set(core->flags, RZ_FLAGS_FS_SYSCALLS);
4678  int snv = (arch == RZ_ARCH_THUMB) ? op.val : (int)rz_reg_getv(core->analysis->reg, sn);
4679  RzSyscallItem *si = rz_syscall_get(core->analysis->syscall, snv, -1);
4680  if (si) {
4681  // eprintf ("0x%08"PFMT64x" SYSCALL %-4d %s\n", cur, snv, si->name);
4682  rz_flag_set_next(core->flags, sdb_fmt("syscall.%s", si->name), cur, 1);
4684  } else {
4685  // todo were doing less filtering up top because we can't match against 80 on all platforms
4686  // might get too many of this path now..
4687  // eprintf ("0x%08"PFMT64x" SYSCALL %d\n", cur, snv);
4688  rz_flag_set_next(core->flags, sdb_fmt("syscall.%d", snv), cur, 1);
4689  }
4690  rz_flag_space_set(core->flags, NULL);
4691  }
4692  const char *esilstr = RZ_STRBUF_SAFEGET(&op.esil);
4693  i += op.size - 1;
4694  if (!esilstr || !*esilstr) {
4695  goto repeat;
4696  }
4698  rz_reg_setv(core->analysis->reg, pcname, cur + op.size);
4699  if (gp_fixed && gp_reg) {
4700  rz_reg_setv(core->analysis->reg, gp_reg, gp);
4701  }
4702  (void)rz_analysis_esil_parse(ESIL, esilstr);
4703 #define CHECKREF(x) ((refptr && (x) == refptr) || !refptr)
4704  switch (op.type) {
4706  // arm64
4707  if (core->analysis->cur && arch == RZ_ARCH_ARM64) {
4708  if (CHECKREF(ESIL->cur)) {
4710  }
4711  }
4712  if (CHECKREF(ESIL->cur)) {
4713  if (op.ptr && rz_io_is_valid_offset(core->io, op.ptr, !core->analysis->opt.noncode)) {
4715  } else {
4717  }
4718  }
4719  if (cfg_analysis_strings) {
4720  add_string_ref(core, op.addr, op.ptr);
4721  }
4722  break;
4724  /* TODO: test if this is valid for other archs too */
4725  if (core->analysis->cur && archIsArm) {
4726  /* This code is known to work on Thumb, ARM and ARM64 */
4727  ut64 dst = ESIL->cur;
4728  if (CHECKREF(dst)) {
4730  }
4731  if (cfg_analysis_strings) {
4732  add_string_ref(core, op.addr, dst);
4733  }
4734  } else if ((core->analysis->bits == 32 && core->analysis->cur && arch == RZ_ARCH_MIPS)) {
4735  ut64 dst = ESIL->cur;
4736  if (!op.src[0] || !op.src[0]->reg || !op.src[0]->reg->name) {
4737  break;
4738  }
4739  if (!strcmp(op.src[0]->reg->name, "sp")) {
4740  break;
4741  }
4742  if (!strcmp(op.src[0]->reg->name, "zero")) {
4743  break;
4744  }
4745  if (dst > 0xffff && op.src[1] && (dst & 0xffff) == (op.src[1]->imm & 0xffff) && myvalid(core->io, dst)) {
4746  RzFlagItem *f;
4747  char *str;
4748  if (CHECKREF(dst) || CHECKREF(cur)) {
4750  if (cfg_analysis_strings) {
4751  add_string_ref(core, op.addr, dst);
4752  }
4753  if ((f = rz_core_flag_get_by_spaces(core->flags, dst))) {
4754  rz_meta_set_string(core->analysis, RZ_META_TYPE_COMMENT, cur, f->name);
4755  } else if ((str = is_string_at(core, dst, NULL))) {
4756  char *str2 = sdb_fmt("esilref: '%s'", str);
4757  // HACK avoid format string inside string used later as format
4758  // string crashes disasm inside agf under some conditions.
4759  rz_str_replace_char(str2, '%', '&');
4761  free(str);
4762  }
4763  }
4764  }
4765  }
4766  break;
4767  case RZ_ANALYSIS_OP_TYPE_LOAD: {
4769  if (dst != UT64_MAX && CHECKREF(dst)) {
4770  if (myvalid(core->io, dst)) {
4772  if (cfg_analysis_strings) {
4773  add_string_ref(core, op.addr, dst);
4774  }
4775  }
4776  }
4778  if (dst != UT64_MAX && CHECKREF(dst)) {
4779  if (myvalid(core->io, dst)) {
4781  if (cfg_analysis_strings) {
4782  add_string_ref(core, op.addr, dst);
4783  }
4784  }
4785  }
4786  } break;
4787  case RZ_ANALYSIS_OP_TYPE_JMP: {
4788  ut64 dst = op.jump;
4789  if (CHECKREF(dst)) {
4790  if (myvalid(core->io, dst)) {
4792  }
4793  }
4794  } break;
4795  case RZ_ANALYSIS_OP_TYPE_CALL: {
4796  ut64 dst = op.jump;
4797  if (CHECKREF(dst)) {
4798  if (myvalid(core->io, dst)) {
4800  }
4801  ESIL->old = cur + op.size;
4802  getpcfromstack(core, ESIL);
4803  }
4804  } break;
4811  case RZ_ANALYSIS_OP_TYPE_MJMP: {
4812  ut64 dst = core->analysis->esil->jump_target;
4813  if (dst == 0 || dst == UT64_MAX) {
4814  dst = rz_reg_getv(core->analysis->reg, pcname);
4815  }
4816  if (CHECKREF(dst)) {
4817  if (myvalid(core->io, dst)) {
4818  RzAnalysisXRefType ref =
4822  rz_analysis_xrefs_set(core->analysis, cur, dst, ref);
4824 // analyze function here
4825 #if 0
4826  if (op.type == RZ_ANALYSIS_OP_TYPE_UCALL || op.type == RZ_ANALYSIS_OP_TYPE_RCALL) {
4827  eprintf ("0x%08"PFMT64x" RCALL TO %llx\n", cur, dst);
4828  }
4829 #endif
4830  }
4831  }
4832  } break;
4833  default:
4834  break;
4835  }
4837  repeat:
4838  if (!rz_analysis_get_block_at(core->analysis, cur)) {
4839  for (size_t bb_i = i_old + 1; bb_i <= i; bb_i++) {
4840  if (rz_analysis_get_block_at(core->analysis, start + bb_i)) {
4841  i = bb_i - 1;
4842  break;
4843  }
4844  }
4845  }
4846  if (i > iend) {
4847  break;
4848  }
4849  } while (get_next_i(&ictx, &i));
4850 #undef CHECKREF
4851  free(buf);
4852  ESIL->cb.hook_mem_read = NULL;
4853  ESIL->cb.hook_mem_write = NULL;
4854  ESIL->cb.hook_reg_write = NULL;
4855  ESIL->user = NULL;
4858 out_pop_regs:
4859  // restore register
4860  rz_reg_arena_pop(core->analysis->reg);
4861 }
ut8 op
Definition: 6502dis.c:13
si
static int esilbreak_mem_write(RzAnalysisEsil *esil, ut64 addr, const ut8 *buf, int len)
Definition: canalysis.c:4199
static void cccb(void *u)
Definition: canalysis.c:4097
#define MAX_SCAN_SIZE
Definition: canalysis.c:28
#define CHECKREF(x)
static bool get_next_i(IterCtx *ctx, size_t *next_i)
Definition: canalysis.c:4419
static int esilbreak_reg_write(RzAnalysisEsil *esil, const char *name, ut64 *val)
Definition: canalysis.c:4263
static int esilbreak_mem_read(RzAnalysisEsil *esil, ut64 addr, ut8 *buf, int len)
Definition: canalysis.c:4211
static void getpcfromstack(RzCore *core, RzAnalysisEsil *esil)
Definition: canalysis.c:4306
RZ_API void rz_core_analysis_esil_init_mem(RZ_NONNULL RzCore *core, RZ_NULLABLE const char *name, ut64 addr, ut32 size)
Definition: cil.c:149
RZ_API void rz_core_analysis_esil_reinit(RZ_NONNULL RzCore *core)
Reinitialize ESIL.
Definition: cil.c:54
RZ_API void rz_core_seek_arch_bits(RzCore *core, ut64 addr)
Definition: cio.c:132
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void long static basep static whence static length const void static len static semflg const void static shmflg const struct timespec struct timespec static rem const char static group const void start
Definition: sflib.h:133
#define ESIL
Definition: desil.c:36
RZ_API RzFlagItem * rz_flag_set_next(RzFlag *f, const char *name, ut64 off, ut32 size)
Definition: flag.c:494
RZ_API bool rz_meta_set_string(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr, const char *s)
Definition: meta.c:141
RZ_API RzPVector * rz_meta_get_all_in(RzAnalysis *a, ut64 at, RzAnalysisMetaType type)
Definition: meta.c:223
RZ_API ut64 rz_reg_setv(RzReg *reg, const char *name, ut64 val)
Definition: reg.c:326
@ RZ_META_TYPE_STRING
Definition: rz_analysis.h:291
@ RZ_META_TYPE_COMMENT
Definition: rz_analysis.h:295
@ RZ_META_TYPE_FORMAT
Definition: rz_analysis.h:292
@ RZ_ANALYSIS_OP_TYPE_CMP
Definition: rz_analysis.h:399
@ RZ_ANALYSIS_OP_TYPE_LOAD
Definition: rz_analysis.h:416
@ RZ_ANALYSIS_OP_TYPE_CRYPTO
Definition: rz_analysis.h:430
@ RZ_ANALYSIS_OP_TYPE_UNK
Definition: rz_analysis.h:388
@ RZ_ANALYSIS_OP_TYPE_REP
Definition: rz_analysis.h:363
@ RZ_ANALYSIS_OP_TYPE_SYNC
Definition: rz_analysis.h:431
@ RZ_ANALYSIS_OP_TYPE_IO
Definition: rz_analysis.h:403
@ RZ_ANALYSIS_OP_TYPE_NULL
Definition: rz_analysis.h:367
@ RZ_ANALYSIS_OP_TYPE_LEAVE
Definition: rz_analysis.h:418
@ RZ_ANALYSIS_OP_TYPE_ADD
Definition: rz_analysis.h:401
@ RZ_ANALYSIS_OP_TYPE_CPL
Definition: rz_analysis.h:429
@ RZ_ANALYSIS_OP_TYPE_PUSH
Definition: rz_analysis.h:397
@ RZ_ANALYSIS_OP_TYPE_POP
Definition: rz_analysis.h:398
@ RZ_ANALYSIS_OP_TYPE_CSWI
Definition: rz_analysis.h:394
@ RZ_ANALYSIS_OP_TYPE_NOP
Definition: rz_analysis.h:389
@ RZ_ANALYSIS_OP_TYPE_ACMP
Definition: rz_analysis.h:400
@ RZ_ANALYSIS_OP_TYPE_LEA
Definition: rz_analysis.h:417
#define RZ_FLAGS_FS_SYSCALLS
Definition: rz_core.h:69
@ RZ_REG_NAME_SN
Definition: rz_reg.h:70
RZ_API int rz_str_replace_char(char *s, int a, int b)
Definition: str.c:169
#define RZ_NULLABLE
Definition: rz_types.h:65
RzAnalysisMetaType type
Definition: rz_analysis.h:302
RzSyscall * syscall
Definition: rz_analysis.h:570
RZ_API void rz_syscall_item_free(RzSyscallItem *si)
Definition: syscall.c:325
RZ_API RzSyscallItem * rz_syscall_get(RzSyscall *s, int num, int swi)
Definition: syscall.c:345

References add_string_ref(), addr, rz_core_t::analysis, rz_analysis_plugin_t::arch, arch, rz_analysis_t::bits, cccb(), CHECKREF, rz_core_t::config, rz_analysis_t::cur, rz_interval_node_t::data, dst, test_evm::end, eprintf, ESIL, rz_analysis_t::esil, esil_analysis_stop, esilbreak_last_data, esilbreak_last_read, esilbreak_mem_read(), esilbreak_mem_write(), esilbreak_reg_write(), f, rz_core_t::flags, free(), get_next_i(), getpcfromstack(), i, rz_core_t::io, is_string_at(), rz_analysis_esil_t::jump_target, list(), malloc(), MAX_SCAN_SIZE, myvalid(), rz_analysis_options_t::noncode, NULL, op, rz_analysis_t::opt, rz_analysis_t::pcalign, PFMT64x, rz_core_t::rasm, rz_analysis_t::reg, repeat(), rz_analysis_esil_parse(), rz_analysis_esil_set_pc(), rz_analysis_esil_stack_free(), rz_analysis_get_block_at(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_ESIL, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_MASK_VAL, RZ_ANALYSIS_OP_TYPE_ACMP, RZ_ANALYSIS_OP_TYPE_ADD, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_CMP, RZ_ANALYSIS_OP_TYPE_CPL, RZ_ANALYSIS_OP_TYPE_CRYPTO, RZ_ANALYSIS_OP_TYPE_CSWI, RZ_ANALYSIS_OP_TYPE_ICALL, RZ_ANALYSIS_OP_TYPE_ILL, RZ_ANALYSIS_OP_TYPE_IO, RZ_ANALYSIS_OP_TYPE_IRCALL, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_LEA, RZ_ANALYSIS_OP_TYPE_LEAVE, RZ_ANALYSIS_OP_TYPE_LOAD, RZ_ANALYSIS_OP_TYPE_MASK, RZ_ANALYSIS_OP_TYPE_MJMP, RZ_ANALYSIS_OP_TYPE_NOP, RZ_ANALYSIS_OP_TYPE_NULL, RZ_ANALYSIS_OP_TYPE_POP, RZ_ANALYSIS_OP_TYPE_PUSH, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_REP, RZ_ANALYSIS_OP_TYPE_RET, RZ_ANALYSIS_OP_TYPE_RJMP, RZ_ANALYSIS_OP_TYPE_SWI, RZ_ANALYSIS_OP_TYPE_SYNC, RZ_ANALYSIS_OP_TYPE_TRAP, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UJMP, RZ_ANALYSIS_OP_TYPE_UNK, RZ_ANALYSIS_XREF_TYPE_CALL, RZ_ANALYSIS_XREF_TYPE_CODE, RZ_ANALYSIS_XREF_TYPE_DATA, RZ_ANALYSIS_XREF_TYPE_NULL, RZ_ANALYSIS_XREF_TYPE_STRING, rz_analysis_xrefs_set(), RZ_ARCH_ARM32, RZ_ARCH_ARM64, RZ_ARCH_MIPS, RZ_ARCH_THUMB, rz_asm_set_pc(), rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_core_analysis_esil_init_mem(), rz_core_analysis_esil_reinit(), rz_core_analysis_fcn(), rz_core_flag_get_by_spaces(), rz_core_seek_arch_bits(), RZ_EMPTY, rz_flag_set_next(), RZ_FLAGS_FS_SYSCALLS, rz_io_is_valid_offset(), rz_io_read_at(), rz_meta_get_all_in(), rz_meta_set_string(), RZ_META_TYPE_ANY, RZ_META_TYPE_COMMENT, RZ_META_TYPE_DATA, RZ_META_TYPE_FORMAT, RZ_META_TYPE_STRING, RZ_NULLABLE, rz_pvector_foreach, rz_pvector_free(), rz_reg_arena_pop(), rz_reg_arena_push(), rz_reg_get_name(), rz_reg_getv(), RZ_REG_NAME_PC, RZ_REG_NAME_SN, RZ_REG_NAME_SP, rz_reg_setv(), rz_str_replace_char(), RZ_STRBUF_SAFEGET, rz_syscall_get(), rz_syscall_item_free(), sdb_fmt(), si, start, cmd_descs_generate::str, rz_analysis_t::syscall, rz_analysis_meta_item_t::type, UT32_MAX, ut64(), and UT64_MAX.

Referenced by rz_analysis_all_esil_handler(), rz_core_analysis_esil_default(), and rz_core_analysis_esil_references_all_functions().

◆ rz_core_analysis_esil_fcn()

RZ_API int rz_core_analysis_esil_fcn ( RzCore core,
ut64  at,
ut64  from,
int  reftype,
int  depth 
)

Definition at line 1984 of file canalysis.c.

1984  {
1985  const char *esil;
1986  eprintf("TODO\n");
1987  while (1) {
1988  // TODO: Implement the proper logic for doing esil analysis
1990  if (!op) {
1991  break;
1992  }
1993  esil = RZ_STRBUF_SAFEGET(&op->esil);
1994  eprintf("0x%08" PFMT64x " %d %s\n", at, op->size, esil);
1995  // at += op->size;
1996  // esilIsRet()
1997  // esilIsCall()
1998  // esilIsJmp()
2000  break;
2001  }
2002  return 0;
2003 }

References eprintf, PFMT64x, rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_ESIL, rz_core_analysis_op(), and RZ_STRBUF_SAFEGET.

Referenced by rz_core_analysis_fcn().

◆ rz_core_analysis_esil_trace_start()

RZ_API bool rz_core_analysis_esil_trace_start ( RzCore core)

Start ESIL trace session.

Parameters
coreThe RzCore instance
Returns
false when an error occurs otherwise true

Definition at line 6746 of file canalysis.c.

6746  {
6747  RzAnalysisEsil *esil = core->analysis->esil;
6748  if (!esil) {
6749  RZ_LOG_ERROR("ESIL is not initialized. Use `aeim` first.\n");
6750  return false;
6751  }
6752  if (esil->trace) {
6753  RZ_LOG_ERROR("ESIL trace already started\n");
6754  return false;
6755  }
6756  esil->trace = rz_analysis_esil_trace_new(esil);
6757  if (!esil->trace) {
6758  return false;
6759  }
6760  rz_config_set_i(core->config, "dbg.trace", true);
6761  return true;
6762 }
RZ_API RzAnalysisEsilTrace * rz_analysis_esil_trace_new(RzAnalysisEsil *esil)
Definition: esil_trace.c:28
RzAnalysisEsilTrace * trace
Definition: rz_analysis.h:1077

References rz_core_t::analysis, rz_core_t::config, core_noretl::core, rz_analysis_t::esil, rz_analysis_esil_trace_new(), rz_config_set_i(), RZ_LOG_ERROR, and rz_analysis_esil_t::trace.

Referenced by rz_il_trace_start_handler().

◆ rz_core_analysis_esil_trace_stop()

RZ_API bool rz_core_analysis_esil_trace_stop ( RzCore core)

Stop ESIL trace session.

Parameters
coreThe RzCore instance
Returns
false when an error occurs otherwise true

Definition at line 6770 of file canalysis.c.

6770  {
6771  RzAnalysisEsil *esil = core->analysis->esil;
6772  if (!esil) {
6773  RZ_LOG_ERROR("ESIL is not initialized. Use `aeim` first.\n");
6774  return false;
6775  }
6776  if (!esil->trace) {
6777  RZ_LOG_ERROR("No ESIL trace started\n");
6778  return false;
6779  }
6781  esil->trace = NULL;
6782  rz_config_set_i(core->config, "dbg.trace", false);
6783  return true;
6784 }
RZ_API void rz_analysis_esil_trace_free(RzAnalysisEsilTrace *trace)
Definition: esil_trace.c:79

References rz_core_t::analysis, rz_core_t::config, core_noretl::core, rz_analysis_t::esil, NULL, rz_analysis_esil_trace_free(), rz_config_set_i(), RZ_LOG_ERROR, and rz_analysis_esil_t::trace.

Referenced by rz_il_trace_stop_handler().

◆ rz_core_analysis_everything()

RZ_API bool rz_core_analysis_everything ( RzCore core,
bool  experimental,
char *  dh_orig 
)

Runs all the steps of the deep analysis.

Returns true if all steps were finished and false if it was interrupted.

Parameters
coreRzCore reference
experimentalEnable more experimental analysis stages ("aaaa" command)
dh_origName of the debug handler, e.g. "esil"

Definition at line 5784 of file canalysis.c.

5784  {
5785  bool didAap = false;
5786  const char *notify = NULL;
5787  ut64 curseek = core->offset;
5788  bool cfg_debug = rz_config_get_b(core->config, "cfg.debug");
5789  bool plugin_supports_esil = core->analysis->cur->esil;
5790  if (rz_str_startswith(rz_config_get(core->config, "bin.lang"), "go")) {
5791  rz_core_notify_done(core, "Find function and symbol names from golang binaries");
5794  }
5795  }
5796  rz_core_task_yield(&core->tasks);
5797  if (!cfg_debug) {
5798  if (dh_orig && strcmp(dh_orig, "esil")) {
5799  rz_config_set(core->config, "dbg.backend", "esil");
5800  rz_core_task_yield(&core->tasks);
5801  }
5802  }
5803  int c = rz_config_get_i(core->config, "analysis.calls");
5804  rz_config_set_i(core->config, "analysis.calls", 1);
5805  ut64 t = rz_num_math(core->num, "$S");
5806  rz_core_seek(core, t, true);
5807  if (rz_cons_is_breaked()) {
5808  return false;
5809  }
5810 
5811  notify = "Analyze function calls";
5812  rz_core_notify_begin(core, "%s", notify);
5813  (void)rz_core_analysis_calls(core, false); // "aac"
5814  rz_core_seek(core, curseek, true);
5815  rz_core_notify_done(core, "%s", notify);
5816  rz_core_task_yield(&core->tasks);
5817  if (rz_cons_is_breaked()) {
5818  return false;
5819  }
5820 
5821  if (is_unknown_file(core)) {
5822  notify = "find and analyze function preludes";
5823  rz_core_notify_begin(core, "%s", notify);
5824  (void)rz_core_search_preludes(core, false); // "aap"
5825  didAap = true;
5826  rz_core_notify_done(core, "%s", notify);
5827  rz_core_task_yield(&core->tasks);
5828  if (rz_cons_is_breaked()) {
5829  return false;
5830  }
5831  }
5832 
5833  notify = "Analyze len bytes of instructions for references";
5834  rz_core_notify_begin(core, "%s", notify);
5835  (void)rz_core_analysis_refs(core, 0); // "aar"
5836  rz_core_notify_done(core, "%s", notify);
5837  rz_core_task_yield(&core->tasks);
5838  if (rz_cons_is_breaked()) {
5839  return false;
5840  }
5841 
5842  if (is_apple_target(core)) {
5843  notify = "Check for objc references";
5844  rz_core_notify_begin(core, "%s", notify);
5845  cmd_analysis_objc(core, true);
5846  rz_core_notify_done(core, "%s", notify);
5847  }
5848  rz_core_task_yield(&core->tasks);
5849 
5850  notify = "Check for classes";
5851  rz_core_notify_begin(core, "%s", notify);
5853  rz_core_notify_done(core, "%s", notify);
5854  rz_core_task_yield(&core->tasks);
5855 
5856  rz_config_set_i(core->config, "analysis.calls", c);
5857  rz_core_task_yield(&core->tasks);
5858  if (rz_cons_is_breaked()) {
5859  return false;
5860  }
5861 
5862  if (!rz_str_startswith(rz_config_get(core->config, "asm.arch"), "x86")) {
5864  rz_core_task_yield(&core->tasks);
5865  bool pcache = rz_config_get_b(core->config, "io.pcache");
5866  rz_config_set_b(core->config, "io.pcache", false);
5867  notify = "Emulate functions to find computed references";
5868  rz_core_notify_begin(core, "%s", notify);
5869  if (plugin_supports_esil) {
5871  }
5872  rz_core_notify_done(core, "%s", notify);
5873  rz_core_task_yield(&core->tasks);
5874  rz_config_set_b(core->config, "io.pcache", pcache);
5875  if (rz_cons_is_breaked()) {
5876  return false;
5877  }
5878  }
5879 
5880  if (rz_config_get_i(core->config, "analysis.autoname")) {
5881  notify = "Speculatively constructing a function name "
5882  "for fcn.* and sym.func.* functions (aan)";
5883  rz_core_notify_begin(core, "%s", notify);
5885  rz_core_notify_done(core, "%s", notify);
5886  rz_core_task_yield(&core->tasks);
5887  }
5888 
5889  if (core->analysis->opt.vars) {
5890  notify = "Analyze local variables and arguments";
5891  rz_core_notify_begin(core, "%s", notify);
5892  RzAnalysisFunction *fcni;
5893  RzListIter *iter;
5894  rz_list_foreach (core->analysis->fcns, iter, fcni) {
5895  if (rz_cons_is_breaked()) {
5896  break;
5897  }
5898  RzList *list = rz_analysis_var_list(core->analysis, fcni, 'r');
5899  if (!rz_list_empty(list)) {
5900  rz_list_free(list);
5901  continue;
5902  }
5903  // extract only reg based var here
5904  rz_core_recover_vars(core, fcni, true);
5905  rz_list_free(list);
5906  }
5907  rz_core_notify_done(core, "%s", notify);
5908  rz_core_task_yield(&core->tasks);
5909  }
5910 
5911  if (plugin_supports_esil) {
5912  notify = "Type matching analysis for all functions";
5913  rz_core_notify_begin(core, "%s", notify);
5915  rz_core_notify_done(core, "%s", notify);
5916  rz_core_task_yield(&core->tasks);
5917  }
5918 
5919  if (rz_config_get_b(core->config, "analysis.apply.signature")) {
5920  int n_applied = 0;
5921  rz_core_notify_begin(core, "Applying signatures from sigdb");
5922  rz_core_analysis_sigdb_apply(core, &n_applied, NULL);
5923  rz_core_notify_done(core, "Applied %d FLIRT signatures via sigdb", n_applied);
5924  rz_core_task_yield(&core->tasks);
5925  }
5926 
5927  notify = "Propagate noreturn information";
5928  rz_core_notify_begin(core, "%s", notify);
5930  rz_core_notify_done(core, "%s", notify);
5931  rz_core_task_yield(&core->tasks);
5932 
5933  // Apply DWARF function information
5934  Sdb *dwarf_sdb = sdb_ns(core->analysis->sdb, "dwarf", 0);
5935  if (dwarf_sdb) {
5936  notify = "Integrate dwarf function information.";
5937  rz_core_notify_begin(core, "%s", notify);
5938  rz_analysis_dwarf_integrate_functions(core->analysis, core->flags, dwarf_sdb);
5939  rz_core_notify_done(core, "%s", notify);
5940  }
5941 
5942  if (experimental) {
5943  if (!didAap) {
5944  notify = "Finding function preludes";
5945  rz_core_notify_begin(core, "%s", notify);
5946  (void)rz_core_search_preludes(core, false); // "aap"
5947  rz_core_notify_done(core, "%s", notify);
5948  rz_core_task_yield(&core->tasks);
5949  }
5950  notify = "Enable constraint types analysis for variables";
5951  rz_core_notify_begin(core, "%s", notify);
5952  rz_config_set(core->config, "analysis.types.constraint", "true");
5953  rz_core_notify_done(core, "%s", notify);
5954  } else {
5955  rz_core_notify_done(core, "Use -AA or aaaa to perform additional experimental analysis.");
5956  }
5957 
5958  rz_core_seek_undo(core);
5959  if (dh_orig) {
5960  rz_config_set(core->config, "dbg.backend", dh_orig);
5961  rz_core_task_yield(&core->tasks);
5962  }
5963 
5964  if (!is_unknown_file(core)) {
5966  }
5967 
5968  return true;
5969 }
RZ_API bool cmd_analysis_objc(RzCore *core, bool auto_analysis)
static bool is_unknown_file(RzCore *core)
Definition: canalysis.c:5758
static bool is_apple_target(RzCore *core)
Definition: canalysis.c:5765
RZ_API bool rz_analysis_add_device_peripheral_map(RzBinObject *o, RzAnalysis *analysis)
Maps the device peripherals as sections.
Definition: canalysis.c:6295
RZ_API void rz_core_analysis_autoname_all_fcns(RzCore *core)
Definition: canalysis.c:504
RZ_IPI void rz_core_analysis_value_pointers(RzCore *core, RzOutputMode mode)
Definition: canalysis.c:6502
RZ_IPI bool rz_core_analysis_types_propagation(RzCore *core)
Definition: canalysis.c:6325
RZ_API void rz_core_analysis_propagate_noreturn(RzCore *core, ut64 addr)
Definition: canalysis.c:5630
RZ_API bool rz_core_analysis_sigdb_apply(RZ_NONNULL RzCore *core, RZ_NULLABLE int *n_applied, RZ_NULLABLE const char *filter)
tries to apply the signatures in the flirt.sigdb.path
Definition: canalysis.c:6057
RZ_API bool rz_core_analysis_refs(RZ_NONNULL RzCore *core, size_t nbytes)
Analyze xrefs and prints the result.
Definition: canalysis.c:3272
RZ_IPI void rz_core_analysis_esil_references_all_functions(RzCore *core)
Definition: cil.c:290
RZ_API void rz_analysis_class_recover_all(RzAnalysis *analysis)
Definition: class.c:1321
RZ_API void rz_core_analysis_calls(RZ_NONNULL RzCore *core, bool imports_only)
RZ_API int rz_core_search_preludes(RzCore *core, bool log)
Definition: cmd_search.c:330
RZ_API RzConfigNode * rz_config_set_b(RzConfig *cfg, RZ_NONNULL const char *name, bool value)
Definition: config.c:201
RZ_API bool rz_core_analysis_recover_golang_functions(RzCore *core)
reads pclntab table in go binaries and recovers functions. Follows the code https://github....
Definition: golang.c:405
RZ_API void rz_core_analysis_resolve_golang_strings(RzCore *core)
Attempts to recover all golang string.
Definition: golang.c:1613
RZ_API void rz_analysis_dwarf_integrate_functions(RzAnalysis *analysis, RzFlag *flags, Sdb *dwarf_sdb)
Use parsed DWARF function info from Sdb in the function analysis XXX right now we only save parsed na...
RZ_API void rz_core_notify_begin(RZ_NONNULL RzCore *core, RZ_NONNULL const char *format,...)
Prints a message definining the beginning of a task.
Definition: core.c:33
RZ_API void rz_core_notify_done(RZ_NONNULL RzCore *core, RZ_NONNULL const char *format,...)
Prints a message definining the end of a task which succeeded.
Definition: core.c:60
RZ_API ut64 rz_num_math(RzNum *num, const char *str)
Definition: unum.c:456
RZ_API bool rz_core_seek_undo(RzCore *core)
Definition: seek.c:301
RZ_API bool rz_core_seek(RzCore *core, ut64 addr, bool rb)
Seek to addr.
Definition: seek.c:116
RzNum * num
Definition: rz_core.h:316
RZ_API RzList * rz_analysis_var_list(RzAnalysis *a, RzAnalysisFunction *fcn, int kind)
Definition: var.c:1154

References rz_core_t::analysis, rz_core_t::bin, c, cmd_analysis_objc(), rz_core_t::config, core_noretl::core, rz_analysis_t::cur, rz_bin_t::cur, rz_analysis_plugin_t::esil, rz_analysis_t::fcns, rz_core_t::flags, is_apple_target(), is_unknown_file(), list(), NULL, rz_core_t::num, rz_bin_file_t::o, rz_core_t::offset, rz_analysis_t::opt, rz_analysis_add_device_peripheral_map(), rz_analysis_class_recover_all(), rz_analysis_dwarf_integrate_functions(), rz_analysis_var_list(), rz_config_get(), rz_config_get_b(), rz_config_get_i(), rz_config_set(), rz_config_set_b(), rz_config_set_i(), rz_cons_is_breaked(), rz_core_analysis_autoname_all_fcns(), rz_core_analysis_calls(), rz_core_analysis_esil_references_all_functions(), rz_core_analysis_propagate_noreturn(), rz_core_analysis_recover_golang_functions(), rz_core_analysis_refs(), rz_core_analysis_resolve_golang_strings(), rz_core_analysis_sigdb_apply(), rz_core_analysis_types_propagation(), rz_core_analysis_value_pointers(), rz_core_notify_begin(), rz_core_notify_done(), rz_core_recover_vars(), rz_core_search_preludes(), rz_core_seek(), rz_core_seek_undo(), rz_core_task_yield(), rz_list_free(), rz_num_math(), RZ_OUTPUT_MODE_STANDARD, rz_str_startswith(), rz_analysis_t::sdb, sdb_ns(), rz_core_t::tasks, ut64(), UT64_MAX, and rz_analysis_options_t::vars.

Referenced by __program_cb(), core_perform_auto_analysis(), execute_command(), and rz_diff_graphs_files().

◆ rz_core_analysis_fcn()

RZ_API int rz_core_analysis_fcn ( RzCore core,
ut64  at,
ut64  from,
int  reftype,
int  depth 
)

Definition at line 2026 of file canalysis.c.

2026  {
2027  if (from == UT64_MAX && is_skippable_addr(core, at)) {
2028  RZ_LOG_DEBUG("invalid address for function 0x%08" PFMT64x "\n", at);
2029  return 0;
2030  }
2031 
2032  const bool use_esil = rz_config_get_i(core->config, "analysis.esil");
2033  RzAnalysisFunction *fcn;
2034 
2035  // update bits based on the core->offset otherwise we could have the
2036  // last value set and blow everything up
2037  rz_core_seek_arch_bits(core, at);
2038 
2039  if (core->io->va) {
2040  if (!rz_io_is_valid_offset(core->io, at, !core->analysis->opt.noncode)) {
2041  RZ_LOG_DEBUG("address not mapped or not executable at 0x%08" PFMT64x "\n", at);
2042  return false;
2043  }
2044  }
2045  if (use_esil) {
2046  return rz_core_analysis_esil_fcn(core, at, from, reftype, depth);
2047  }
2048 
2049  if ((from != UT64_MAX && !at) || at == UT64_MAX) {
2050  RZ_LOG_WARN("invalid address from 0x%08" PFMT64x "\n", from);
2051  return false;
2052  }
2053  if (depth < 0) {
2054  RZ_LOG_DEBUG("analysis depth reached\n");
2055  return false;
2056  }
2057  if (rz_cons_is_breaked()) {
2058  return false;
2059  }
2060  fcn = rz_analysis_get_fcn_in(core->analysis, at, 0);
2061  if (fcn) {
2062  if (fcn->addr == at) {
2063  // if the function was already analyzed as a "loc.",
2064  // convert it to function and rename it to "fcn.",
2065  // because we found a call to this address
2067  function_rename(core->flags, fcn);
2068  }
2069 
2070  return 0; // already analyzed function
2071  }
2072  if (rz_analysis_function_contains(fcn, from)) { // inner function
2074  if (l && !rz_list_empty(l)) {
2075  rz_list_free(l);
2076  return true;
2077  }
2078  rz_list_free(l);
2079 
2080  // we should analyze and add code ref otherwise aaa != aac
2081  if (from != UT64_MAX) {
2083  }
2084  return true;
2085  }
2086  }
2087  if (__core_analysis_fcn(core, at, from, reftype, depth - 1)) {
2088  // split function if overlaps
2089  if (fcn) {
2090  rz_analysis_function_resize(fcn, at - fcn->addr);
2091  }
2092  return true;
2093  }
2094  return false;
2095 }
static void function_rename(RzFlag *flags, RzAnalysisFunction *fcn)
Definition: canalysis.c:755
static int __core_analysis_fcn(RzCore *core, ut64 at, ut64 from, int reftype, int depth)
Definition: canalysis.c:813
RZ_API int rz_core_analysis_esil_fcn(RzCore *core, ut64 at, ut64 from, int reftype, int depth)
Definition: canalysis.c:1984
static bool is_skippable_addr(RzCore *core, ut64 addr)
Definition: canalysis.c:2010
RZ_API int rz_analysis_function_resize(RzAnalysisFunction *fcn, int newsize)
Definition: fcn.c:90
@ RZ_ANALYSIS_FCN_TYPE_LOC
Definition: rz_analysis.h:194
#define RZ_LOG_WARN(fmtstr,...)
Definition: rz_log.h:56

References __core_analysis_fcn(), rz_analysis_function_t::addr, rz_core_t::analysis, rz_core_t::config, rz_core_t::flags, from, function_rename(), rz_core_t::io, is_skippable_addr(), rz_analysis_options_t::noncode, rz_analysis_t::opt, PFMT64x, RZ_ANALYSIS_FCN_TYPE_LOC, rz_analysis_function_contains(), rz_analysis_function_resize(), rz_analysis_get_fcn_in(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_analysis_xrefs_get_to(), rz_analysis_xrefs_set(), rz_config_get_i(), rz_cons_is_breaked(), rz_core_analysis_esil_fcn(), rz_core_seek_arch_bits(), rz_io_is_valid_offset(), rz_list_free(), RZ_LOG_DEBUG, RZ_LOG_WARN, rz_analysis_function_t::type, UT64_MAX, and rz_io_t::va.

Referenced by __core_analysis_fcn(), __prelude_cb_hit(), _analysis_calls(), rz_analysis_analyze_fcn_refs(), rz_analysis_try_get_fcn(), rz_analyze_all_data_references_to_code_handler(), rz_cmd_analysis(), rz_core_analysis_all(), rz_core_analysis_esil(), rz_core_analysis_function_add(), and rz_core_analysis_function_until().

◆ rz_core_analysis_fcn_clean()

RZ_API int rz_core_analysis_fcn_clean ( RzCore core,
ut64  addr 
)

Definition at line 2099 of file canalysis.c.

2099  {
2100  RzAnalysisFunction *fcni;
2101  RzListIter *iter, *iter_tmp;
2102 
2103  if (!addr) {
2104  rz_list_purge(core->analysis->fcns);
2105  if (!(core->analysis->fcns = rz_list_new())) {
2106  return false;
2107  }
2108  } else {
2109  rz_list_foreach_safe (core->analysis->fcns, iter, iter_tmp, fcni) {
2110  if (rz_analysis_function_contains(fcni, addr)) {
2112  }
2113  }
2114  }
2115  return true;
2116 }
RZ_API bool rz_analysis_function_delete(RzAnalysisFunction *fcn)
Definition: function.c:180
RZ_API void rz_list_purge(RZ_NONNULL RzList *list)
Empties the list without freeing the list pointer.
Definition: list.c:120

References addr, rz_core_t::analysis, rz_analysis_t::fcns, rz_analysis_function_contains(), rz_analysis_function_delete(), rz_list_new(), and rz_list_purge().

◆ rz_core_analysis_fcn_get_calls()

RZ_API RzList* rz_core_analysis_fcn_get_calls ( RzCore core,
RzAnalysisFunction fcn 
)

Definition at line 2663 of file canalysis.c.

2663  {
2664  RzAnalysisXRef *xrefi;
2665  RzListIter *iter, *iter2;
2666 
2667  // get all references from this function
2669  // sanity check
2670  if (!rz_list_empty(xrefs)) {
2671  // iterate over all the references and remove these which aren't of type call
2672  rz_list_foreach_safe (xrefs, iter, iter2, xrefi) {
2673  if (xrefi->type != RZ_ANALYSIS_XREF_TYPE_CALL) {
2674  rz_list_delete(xrefs, iter);
2675  }
2676  }
2677  }
2678  return xrefs;
2679 }

References rz_analysis_function_get_xrefs_from(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_list_delete(), and rz_analysis_ref_t::type.

Referenced by function_list_print_to_table(), function_print_calls(), and rz_cmd_print().

◆ rz_core_analysis_fcn_merge()

RZ_API void rz_core_analysis_fcn_merge ( RzCore core,
ut64  addr,
ut64  addr2 
)

Definition at line 4042 of file canalysis.c.

4042  {
4043  RzListIter *iter;
4044  ut64 min = 0;
4045  ut64 max = 0;
4046  int first = 1;
4047  RzAnalysisBlock *bb;
4050  if (!f1 || !f2) {
4051  eprintf("Cannot find function\n");
4052  return;
4053  }
4054  if (f1 == f2) {
4055  eprintf("Cannot merge the same function\n");
4056  return;
4057  }
4058  // join all basic blocks from f1 into f2 if they are not
4059  // delete f2
4060  eprintf("Merge 0x%08" PFMT64x " into 0x%08" PFMT64x "\n", addr, addr2);
4061  rz_list_foreach (f1->bbs, iter, bb) {
4062  if (first) {
4063  min = bb->addr;
4064  max = bb->addr + bb->size;
4065  first = 0;
4066  } else {
4067  if (bb->addr < min) {
4068  min = bb->addr;
4069  }
4070  if (bb->addr + bb->size > max) {
4071  max = bb->addr + bb->size;
4072  }
4073  }
4074  }
4075  rz_list_foreach (f2->bbs, iter, bb) {
4076  if (first) {
4077  min = bb->addr;
4078  max = bb->addr + bb->size;
4079  first = 0;
4080  } else {
4081  if (bb->addr < min) {
4082  min = bb->addr;
4083  }
4084  if (bb->addr + bb->size > max) {
4085  max = bb->addr + bb->size;
4086  }
4087  }
4089  }
4090  // TODO: import data/code/refs
4092  // update size
4094 }
RZ_API void rz_analysis_function_add_block(RzAnalysisFunction *fcn, RzAnalysisBlock *bb)
Definition: function.c:264
RZ_API bool rz_analysis_function_relocate(RzAnalysisFunction *fcn, ut64 addr)
Definition: function.c:204
int max
Definition: enough.c:225
#define min(a, b)
Definition: qsort.h:83

References addr, rz_analysis_bb_t::addr, rz_core_t::analysis, eprintf, f1, autogen_x86imm::f2, max, min, PFMT64x, rz_analysis_function_add_block(), rz_analysis_function_delete(), rz_analysis_function_relocate(), rz_analysis_get_function_at(), RZ_MIN, rz_analysis_bb_t::size, and ut64().

Referenced by rz_analysis_functions_merge_handler(), and rz_core_visual_define().

◆ rz_core_analysis_fcn_name()

RZ_API char* rz_core_analysis_fcn_name ( RzCore core,
RzAnalysisFunction fcn 
)

Definition at line 2647 of file canalysis.c.

2647  {
2648  bool demangle = rz_config_get_i(core->config, "bin.demangle");
2649  const char *lang = demangle ? rz_config_get(core->config, "bin.lang") : NULL;
2650  bool keep_lib = rz_config_get_i(core->config, "bin.demangle.libs");
2651  char *name = strdup(fcn->name ? fcn->name : "");
2652  if (demangle) {
2653  char *tmp = rz_bin_demangle(core->bin->cur, lang, name, fcn->addr, keep_lib);
2654  if (tmp) {
2655  free(name);
2656  name = tmp;
2657  }
2658  }
2659  return name;
2660 }
RZ_API RZ_OWN char * rz_bin_demangle(RZ_NULLABLE RzBinFile *bf, RZ_NULLABLE const char *language, RZ_NULLABLE const char *symbol, ut64 vaddr, bool libs)
Demangles a symbol based on the language or the RzBinFile data.
Definition: bin.c:1295

References rz_analysis_function_t::addr, rz_core_t::bin, rz_core_t::config, rz_bin_t::cur, free(), name, rz_analysis_function_t::name, NULL, rz_bin_demangle(), rz_config_get(), rz_config_get_i(), strdup(), and autogen_x86imm::tmp.

Referenced by autocmplt_cmd_arg_fcn(), autocomplete_functions(), fcn_print_info(), function_list_print(), function_list_print_as_cmd(), function_print_to_json(), and rz_analysis_function_list_ascii_handler().

◆ rz_core_analysis_fcn_returns()

RZ_IPI void rz_core_analysis_fcn_returns ( RzCore core,
RzAnalysisFunction fcn 
)

Definition at line 328 of file canalysis.c.

328  {
329  RzListIter *iter;
331  ls_foreach (fcn->bbs, iter, b) {
332  if (b->jump == UT64_MAX) {
333  ut64 retaddr = rz_analysis_block_get_op_addr(b, b->ninstr - 1);
334  if (retaddr == UT64_MAX) {
335  break;
336  }
337 
338  rz_cons_printf("0x%08" PFMT64x "\n", retaddr);
339  }
340  }
341 }

References b, rz_analysis_function_t::bbs, ls_foreach, PFMT64x, rz_analysis_block_get_op_addr(), rz_cons_printf(), ut64(), and UT64_MAX.

Referenced by rz_analysis_function_returns_handler().

◆ rz_core_analysis_flag_every_function()

RZ_API void rz_core_analysis_flag_every_function ( RzCore core)

Definition at line 5202 of file canalysis.c.

5202  {
5203  RzListIter *iter;
5204  RzAnalysisFunction *fcn;
5205  rz_flag_space_push(core->flags, RZ_FLAGS_FS_FUNCTIONS);
5206  rz_list_foreach (core->analysis->fcns, iter, fcn) {
5207  rz_flag_set(core->flags, fcn->name,
5209  }
5210  rz_flag_space_pop(core->flags);
5211 }
RZ_API ut64 rz_analysis_function_size_from_entry(RzAnalysisFunction *fcn)
Definition: function.c:333

References rz_analysis_function_t::addr, rz_core_t::analysis, rz_analysis_t::fcns, rz_core_t::flags, rz_analysis_function_t::name, rz_analysis_function_size_from_entry(), rz_flag_set(), and RZ_FLAGS_FS_FUNCTIONS.

Referenced by core_perform_auto_analysis(), and rz_core_analysis_function_add().

◆ rz_core_analysis_function_add()

RZ_API bool rz_core_analysis_function_add ( RzCore core,
const char *  name,
ut64  addr,
bool  analyze_recursively 
)

XXX wrong in case of nopskip

Definition at line 5298 of file canalysis.c.

5298  {
5299  int depth = rz_config_get_i(core->config, "analysis.depth");
5300  RzAnalysisFunction *fcn = NULL;
5301 
5302  // rz_core_analysis_undefine (core, core->offset);
5304  fcn = rz_analysis_get_fcn_in(core->analysis, addr, 0);
5305  if (fcn) {
5306  /* ensure we use a proper name */
5308  if (core->analysis->opt.vars) {
5309  rz_core_recover_vars(core, fcn, true);
5310  }
5312  } else {
5313  RZ_LOG_DEBUG("Unable to analyze function at 0x%08" PFMT64x "\n", addr);
5314  }
5315  if (analyze_recursively) {
5316  fcn = rz_analysis_get_fcn_in(core->analysis, addr, 0);
5317  if (fcn) {
5318  RzAnalysisXRef *xref;
5319  RzListIter *iter;
5321  rz_list_foreach (xrefs, iter, xref) {
5322  if (xref->to == UT64_MAX) {
5323  // eprintf ("Warning: ignore 0x%08"PFMT64x" call 0x%08"PFMT64x"\n", ref->at, ref->addr);
5324  continue;
5325  }
5327  /* only follow code/call references */
5328  continue;
5329  }
5330  if (!rz_io_is_valid_offset(core->io, xref->to, !core->analysis->opt.noncode)) {
5331  continue;
5332  }
5333  rz_core_analysis_fcn(core, xref->to, fcn->addr, RZ_ANALYSIS_XREF_TYPE_CALL, depth);
5334  /* use recursivity here */
5336  if (f) {
5337  RzListIter *iter;
5338  RzAnalysisXRef *xref1;
5340  rz_list_foreach (xrefs1, iter, xref1) {
5341  if (!rz_io_is_valid_offset(core->io, xref1->to, !core->analysis->opt.noncode)) {
5342  continue;
5343  }
5344  if (xref1->type != RZ_ANALYSIS_XREF_TYPE_CODE && xref1->type != RZ_ANALYSIS_XREF_TYPE_CALL) {
5345  continue;
5346  }
5347  rz_core_analysis_fcn(core, xref1->to, f->addr, RZ_ANALYSIS_XREF_TYPE_CALL, depth);
5348  // recursively follow fcn->refs again and again
5349  }
5350  rz_list_free(xrefs1);
5351  } else {
5352  f = rz_analysis_get_fcn_in(core->analysis, fcn->addr, 0);
5353  if (f) {
5354  /* cut function */
5356  rz_core_analysis_fcn(core, xref->to, fcn->addr,
5358  f = rz_analysis_get_function_at(core->analysis, fcn->addr);
5359  }
5360  if (!f) {
5361  eprintf("af: Cannot find function at 0x%08" PFMT64x "\n", fcn->addr);
5362  rz_list_free(xrefs);
5363  return false;
5364  }
5365  }
5366  }
5367  rz_list_free(xrefs);
5368  if (core->analysis->opt.vars) {
5369  rz_core_recover_vars(core, fcn, true);
5370  }
5371  }
5372  }
5374  RZ_LOG_ERROR("af: Cannot find function at 0x%08" PFMT64x "\n", addr);
5375  return false;
5376  }
5379  return true;
5380 }
RZ_API void rz_core_analysis_flag_every_function(RzCore *core)
Definition: canalysis.c:5202
#define RZ_STR_ISNOTEMPTY(x)
Definition: rz_str.h:68
RZ_API void rz_analysis_fcn_vars_add_types(RzAnalysis *analysis, RZ_NONNULL RzAnalysisFunction *fcn)
Updates the types database for function arguments.
Definition: var.c:1383

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, rz_core_t::config, eprintf, f, rz_core_t::io, rz_analysis_function_t::name, rz_analysis_options_t::noncode, NULL, rz_analysis_t::opt, PFMT64x, rz_analysis_fcn_vars_add_types(), rz_analysis_function_get_xrefs_from(), rz_analysis_function_resize(), rz_analysis_get_fcn_in(), rz_analysis_get_function_at(), RZ_ANALYSIS_XREF_TYPE_CALL, RZ_ANALYSIS_XREF_TYPE_CODE, RZ_ANALYSIS_XREF_TYPE_NULL, rz_config_get_i(), rz_core_analysis_fcn(), rz_core_analysis_flag_every_function(), rz_core_analysis_function_rename(), rz_core_analysis_propagate_noreturn(), rz_core_recover_vars(), rz_io_is_valid_offset(), rz_list_free(), RZ_LOG_DEBUG, RZ_LOG_ERROR, RZ_STR_ISNOTEMPTY, rz_analysis_ref_t::to, rz_analysis_ref_t::type, UT64_MAX, and rz_analysis_options_t::vars.

Referenced by __function_cb(), agraph_refresh(), analyze_function_at_flag(), ds_control_flow_comments(), rz_analysis_function_add_recu_handler(), rz_analyze_all_consecutive_functions_in_section_handler(), rz_analyze_symbols_entries_handler(), rz_core_analysis_all(), rz_core_analysis_resolve_jumps(), rz_core_visual_analysis(), rz_core_visual_classes(), rz_core_visual_define(), rz_core_visual_trackflags(), and rz_diff_graphs_files().

◆ rz_core_analysis_function_autoname()

RZ_API RZ_OWN char* rz_core_analysis_function_autoname ( RZ_NONNULL RzCore core,
RZ_NONNULL RzAnalysisFunction fcn 
)

Suggest a name for the function.

Definition at line 545 of file canalysis.c.

545  {
546  rz_return_val_if_fail(core && fcn, NULL);
547 
548  RzAnalysisXRef *xref;
549  RzListIter *iter;
550  bool use_getopt = false;
551  bool use_isatty = false;
552  char *do_call = NULL;
554  rz_list_foreach (xrefs, iter, xref) {
555  RzFlagItem *f = rz_flag_get_i(core->flags, xref->to);
556  if (f && !blacklisted_word(f->name)) {
557  if (strstr(f->name, ".isatty")) {
558  use_isatty = 1;
559  }
560  if (strstr(f->name, ".getopt")) {
561  use_getopt = 1;
562  }
563  if (!strncmp(f->name, "method.", 7)) {
564  free(do_call);
565  do_call = strdup(f->name + 7);
566  break;
567  }
568  if (!strncmp(f->name, "str.", 4)) {
569  free(do_call);
570  do_call = strdup(f->name + 4);
571  break;
572  }
573  if (!strncmp(f->name, "sym.imp.", 8)) {
574  free(do_call);
575  do_call = strdup(f->name + 8);
576  break;
577  }
578  if (!strncmp(f->name, "reloc.", 6)) {
579  free(do_call);
580  do_call = strdup(f->name + 6);
581  break;
582  }
583  }
584  }
585  rz_list_free(xrefs);
586  // TODO: append counter if name already exists
587  if (use_getopt) {
588  RzFlagItem *item = rz_flag_get(core->flags, "main");
589  free(do_call);
590  // if referenced from entrypoint. this should be main
591  if (item && item->offset == fcn->addr) {
592  return strdup("main"); // main?
593  }
594  return strdup("parse_args"); // main?
595  }
596  if (use_isatty) {
597  char *ret = rz_str_newf("sub.setup_tty_%s_%" PFMT64x, do_call, fcn->addr);
598  free(do_call);
599  return ret;
600  }
601  if (do_call) {
602  char *ret = rz_str_newf("sub.%s_%" PFMT64x, do_call, fcn->addr);
603  free(do_call);
604  return ret;
605  }
606  return NULL;
607 }
static bool blacklisted_word(const char *name)
Definition: canalysis.c:526

References blacklisted_word(), f, free(), NULL, rz_flag_item_t::offset, PFMT64x, rz_analysis_function_get_xrefs_from(), rz_flag_get(), rz_flag_get_i(), rz_list_free(), rz_return_val_if_fail, rz_str_newf(), strdup(), and rz_analysis_ref_t::to.

Referenced by rz_analysis_function_autoname_handler(), and rz_core_analysis_autoname_all_fcns().

◆ rz_core_analysis_function_delete_var()

RZ_IPI bool rz_core_analysis_function_delete_var ( RzCore core,
RzAnalysisFunction fcn,
RzAnalysisVarKind  kind,
const char *  id 
)

Definition at line 6133 of file canalysis.c.

6133  {
6134  RzAnalysisVar *var = NULL;
6135  if (IS_DIGIT(*id)) {
6136  int delta = rz_num_math(core->num, id);
6137  var = rz_analysis_function_get_var(fcn, kind, delta);
6138  } else {
6139  var = rz_analysis_function_get_var_byname(fcn, id);
6140  }
6141  if (!var || var->kind != kind) {
6142  return false;
6143  }
6145  return true;
6146 }
#define IS_DIGIT(x)
Definition: rz_str_util.h:11
RzAnalysisVarKind kind
Definition: rz_analysis.h:728
RZ_API RZ_BORROW RzAnalysisVar * rz_analysis_function_get_var_byname(RzAnalysisFunction *fcn, const char *name)
Definition: var.c:247
RZ_API void rz_analysis_var_delete(RzAnalysisVar *var)
Definition: var.c:192

References core_noretl::core, delta, IS_DIGIT, rz_analysis_var_t::kind, NULL, rz_core_t::num, rz_analysis_function_get_var(), rz_analysis_function_get_var_byname(), rz_analysis_var_delete(), and rz_num_math().

Referenced by analysis_function_vars_del(), and rz_analysis_function_vars_del_handler().

◆ rz_core_analysis_function_rename()

RZ_API bool rz_core_analysis_function_rename ( RzCore core,
ut64  addr,
const char *  _name 
)

Definition at line 5270 of file canalysis.c.

5270  {
5271  rz_return_val_if_fail(core && _name, false);
5272  _name = rz_str_trim_head_ro(_name);
5273  char *name = getFunctionNamePrefix(core, addr, _name);
5274  // RzAnalysisFunction *fcn = rz_analysis_get_fcn_in (core->analysis, addr, RZ_ANALYSIS_FCN_TYPE_ANY);
5276  if (fcn) {
5277  RzFlagItem *flag = rz_flag_get(core->flags, fcn->name);
5278  if (flag && flag->space && strcmp(flag->space->name, RZ_FLAGS_FS_FUNCTIONS) == 0) {
5279  // Only flags in the functions fs should be renamed, e.g. we don't want to rename symbol flags.
5280  rz_flag_rename(core->flags, flag, name);
5281  } else {
5282  // No flag or not specific to the function, create a new one.
5283  rz_flag_space_push(core->flags, RZ_FLAGS_FS_FUNCTIONS);
5285  rz_flag_space_pop(core->flags);
5286  }
5288  if (core->analysis->cb.on_fcn_rename) {
5289  core->analysis->cb.on_fcn_rename(core->analysis, core, fcn, name);
5290  }
5291  free(name);
5292  return true;
5293  }
5294  free(name);
5295  return false;
5296 }
RZ_API bool rz_analysis_function_rename(RzAnalysisFunction *fcn, const char *name)
Definition: function.c:240
static char * getFunctionNamePrefix(RzCore *core, ut64 off, const char *name)
Definition: canalysis.c:57
RZ_API const char * rz_str_trim_head_ro(const char *str)
Definition: str_trim.c:86
int(* on_fcn_rename)(struct rz_analysis_t *, void *user, RzAnalysisFunction *fcn, const char *oldname)
Definition: rz_analysis.h:500
RzAnalysisCallbacks cb
Definition: rz_analysis.h:607
RzSpace * space
Definition: rz_flag.h:40
char * name
Definition: rz_spaces.h:29

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, rz_analysis_t::cb, rz_core_t::flags, free(), getFunctionNamePrefix(), rz_analysis_function_t::name, rz_space_t::name, rz_analysis_callbacks_t::on_fcn_rename, rz_analysis_function_rename(), rz_analysis_function_size_from_entry(), rz_analysis_get_function_at(), rz_flag_get(), rz_flag_rename(), rz_flag_set(), RZ_FLAGS_FS_FUNCTIONS, rz_return_val_if_fail, rz_str_trim_head_ro(), and rz_flag_item_t::space.

Referenced by rz_analysis_function_rename_handler(), rz_core_analysis_all(), rz_core_analysis_function_add(), rz_core_analysis_function_set_signature(), rz_core_analysis_rename(), and rz_core_visual_define().

◆ rz_core_analysis_function_set_signature()

RZ_IPI bool rz_core_analysis_function_set_signature ( RzCore core,
RzAnalysisFunction fcn,
const char *  newsig 
)

Definition at line 6380 of file canalysis.c.

6380  {
6381  bool res = false;
6382  char *fcnname = NULL;
6383  char *fcnstr = rz_str_newf("%s;", newsig);
6384  char *fcnstr_copy = strdup(fcnstr);
6385  char *fcnname_aux = strtok(fcnstr_copy, "(");
6386  if (!fcnname_aux) {
6387  goto err;
6388  }
6389  rz_str_trim_tail(fcnname_aux);
6390  const char *ls = rz_str_lchr(fcnname_aux, ' ');
6391  fcnname = strdup(ls ? ls : fcnname_aux);
6392  if (!fcnname) {
6393  goto err;
6394  }
6395  // TODO: move this into rz_analysis_function_set_type_str()
6396  if (strcmp(fcn->name, fcnname)) {
6397  (void)rz_core_analysis_function_rename(core, fcn->addr, fcnname);
6398  fcn = rz_analysis_get_fcn_in(core->analysis, fcn->addr, -1);
6399  }
6400  rz_analysis_function_set_type_str(core->analysis, fcn, fcnstr);
6401  res = true;
6402 err:
6403  free(fcnname);
6404  free(fcnstr_copy);
6405  free(fcnstr);
6406  return res;
6407 }
static bool err
Definition: armass.c:435
RZ_API bool rz_analysis_function_set_type_str(RzAnalysis *a, RZ_NONNULL RzAnalysisFunction *f, RZ_NONNULL const char *sig)
Parses the function type and sets it for the given function.
Definition: fcn.c:1985
RZ_API const char * rz_str_lchr(const char *str, char chr)
Definition: str.c:669
RZ_API RZ_BORROW char * rz_str_trim_tail(RZ_NONNULL char *str)
Removes whitespace characters (space, tab, newline etc.) from the end of a string and replaces them w...
Definition: str_trim.c:125

References rz_analysis_function_t::addr, rz_core_t::analysis, core_noretl::core, err, free(), rz_analysis_function_t::name, NULL, rz_analysis_function_set_type_str(), rz_analysis_get_fcn_in(), rz_core_analysis_function_rename(), rz_str_lchr(), rz_str_newf(), rz_str_trim_tail(), and strdup().

Referenced by rz_analysis_function_signature_handler(), and rz_core_analysis_function_signature_editor().

◆ rz_core_analysis_function_signature()

RZ_IPI char* rz_core_analysis_function_signature ( RzCore core,
RzOutputMode  mode,
char *  fcn_name 
)

Definition at line 5382 of file canalysis.c.

5382  {
5383  RzListIter *iter;
5385  RzAnalysisFunction *fcn;
5386  if (fcn_name) {
5387  fcn = rz_analysis_get_function_byname(core->analysis, fcn_name);
5388  } else {
5389  fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, 0);
5390  if (fcn) {
5391  fcn_name = fcn->name;
5392  }
5393  }
5394  if (!fcn) {
5395  return NULL;
5396  }
5397  char *signature = NULL;
5398 
5399  if (mode == RZ_OUTPUT_MODE_JSON) {
5400  PJ *j = pj_new();
5401  if (!j) {
5402  return NULL;
5403  }
5404  pj_a(j);
5405 
5406  char *key = NULL;
5407  if (fcn_name) {
5408  key = resolve_fcn_name(core->analysis, fcn_name);
5409  }
5410 
5411  if (key) {
5412  RzType *ret_type = rz_type_func_ret(core->analysis->typedb, key);
5413  char *ret_type_str = NULL;
5414  if (ret_type) {
5415  ret_type_str = rz_type_as_string(core->analysis->typedb, ret_type);
5416  }
5418  pj_o(j);
5419  pj_ks(j, "name", rz_str_get_null(key));
5420  if (ret_type_str) {
5421  pj_ks(j, "return", ret_type_str);
5422  }
5423  pj_k(j, "args");
5424  pj_a(j);
5425  if (nargs) {
5426  RzList *list = rz_core_get_func_args(core, fcn_name);
5427  rz_list_foreach (list, iter, arg) {
5428  char *type = rz_type_as_string(core->analysis->typedb, arg->orig_c_type);
5429  pj_o(j);
5430  pj_ks(j, "name", arg->name);
5431  pj_ks(j, "type", type);
5432  pj_end(j);
5433  free(type);
5434  }
5435  rz_list_free(list);
5436  }
5437  pj_end(j);
5438  pj_ki(j, "count", nargs);
5439  pj_end(j);
5440  free(ret_type_str);
5441  free(key);
5442  } else {
5443  pj_o(j);
5444  pj_ks(j, "name", rz_str_get_null(fcn_name));
5445  pj_k(j, "args");
5446  pj_a(j);
5447 
5448  RzAnalysisFcnVarsCache cache;
5449  rz_analysis_fcn_vars_cache_init(core->analysis, &cache, fcn);
5450  int nargs = 0;
5451  RzAnalysisVar *var;
5452  rz_list_foreach (cache.rvars, iter, var) {
5453  nargs++;
5454  pj_o(j);
5455  pj_ks(j, "name", var->name);
5456  char *vartype = rz_type_as_string(core->analysis->typedb, var->type);
5457  pj_ks(j, "type", vartype);
5458  pj_end(j);
5459  free(vartype);
5460  }
5461  rz_list_foreach (cache.bvars, iter, var) {
5462  if (var->delta <= 0) {
5463  continue;
5464  }
5465  nargs++;
5466  pj_o(j);
5467  pj_ks(j, "name", var->name);
5468  char *vartype = rz_type_as_string(core->analysis->typedb, var->type);
5469  pj_ks(j, "type", vartype);
5470  pj_end(j);
5471  free(vartype);
5472  }
5473  rz_list_foreach (cache.svars, iter, var) {
5474  if (!var->isarg) {
5475  continue;
5476  }
5477  nargs++;
5478  pj_o(j);
5479  pj_ks(j, "name", var->name);
5480  char *vartype = rz_type_as_string(core->analysis->typedb, var->type);
5481  pj_ks(j, "type", vartype);
5482  pj_end(j);
5483  free(vartype);
5484  }
5486 
5487  pj_end(j);
5488  pj_ki(j, "count", nargs);
5489  pj_end(j);
5490  }
5491  pj_end(j);
5492  signature = strdup(pj_string(j));
5493  pj_free(j);
5494  } else {
5495  signature = rz_analysis_fcn_format_sig(core->analysis, fcn, fcn_name, NULL, NULL, NULL);
5496  }
5497  return signature;
5498 }
static char * signature(RzBinFile *bf, bool json)
Definition: bin_pe.c:117
RZ_API RZ_OWN RzList * rz_core_get_func_args(RzCore *core, const char *fcn_name)
Definition: carg.c:276
RZ_API char * resolve_fcn_name(RzAnalysis *analysis, const char *func_name)
Definition: carg.c:86
RZ_API RzAnalysisFunction * rz_analysis_get_function_byname(RzAnalysis *a, const char *name)
Definition: fcn.c:1729
const char * name
Definition: sparc-opc.c:1838
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.
Definition: function.c:262
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.
Definition: function.c:215
RZ_API void rz_analysis_fcn_vars_cache_fini(RzAnalysisFcnVarsCache *cache)
Definition: var.c:1223
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)
Definition: var.c:1232
RZ_API void rz_analysis_fcn_vars_cache_init(RzAnalysis *analysis, RzAnalysisFcnVarsCache *cache, RzAnalysisFunction *fcn)
Definition: var.c:1209

References rz_core_t::analysis, arg(), rz_analysis_var_t::delta, free(), rz_analysis_var_t::isarg, key, list(), arg::name, rz_analysis_function_t::name, rz_analysis_var_t::name, cmd_descs_generate::nargs, NULL, rz_core_t::offset, pj_a(), pj_end(), pj_free(), pj_k(), pj_ki(), pj_ks(), pj_new(), pj_o(), pj_string(), resolve_fcn_name(), rz_analysis_fcn_format_sig(), rz_analysis_fcn_vars_cache_fini(), rz_analysis_fcn_vars_cache_init(), rz_analysis_get_fcn_in(), rz_analysis_get_function_byname(), rz_core_get_func_args(), rz_list_free(), RZ_OUTPUT_MODE_JSON, rz_str_get_null(), rz_type_as_string(), rz_type_func_args_count(), rz_type_func_ret(), signature(), strdup(), type, rz_analysis_var_t::type, and rz_analysis_t::typedb.

Referenced by agraph_update_title(), and function_print_to_json().

◆ rz_core_analysis_function_signature_editor()

RZ_IPI void rz_core_analysis_function_signature_editor ( RzCore core,
ut64  addr 
)

Definition at line 6409 of file canalysis.c.

6409  {
6411  if (!f) {
6412  eprintf("Cannot find function in 0x%08" PFMT64x "\n", core->offset);
6413  return;
6414  }
6415 
6417  char *data = rz_core_editor(core, NULL, sig);
6418  if (sig && data) {
6420  }
6421  free(sig);
6422  free(data);
6423 }
RZ_IPI bool rz_core_analysis_function_set_signature(RzCore *core, RzAnalysisFunction *fcn, const char *newsig)
Definition: canalysis.c:6380
RZ_API RZ_OWN char * rz_analysis_function_get_signature(RZ_NONNULL RzAnalysisFunction *function)
Definition: fcn.c:1895
RZ_API RZ_OWN char * rz_core_editor(const RzCore *core, RZ_NULLABLE const char *file, RZ_NULLABLE const char *str)
Definition: core.c:3214

References rz_core_t::analysis, core_noretl::core, eprintf, f, free(), NULL, rz_core_t::offset, PFMT64x, rz_analysis_function_get_signature(), rz_analysis_get_fcn_in(), rz_core_analysis_function_set_signature(), and rz_core_editor().

Referenced by rz_analysis_function_signature_editor_handler(), rz_core_visual_analysis(), and rz_core_visual_define().

◆ rz_core_analysis_function_strings_print()

RZ_API void rz_core_analysis_function_strings_print ( RZ_NONNULL RzCore core,
RZ_NONNULL RzAnalysisFunction fcn,
RZ_NULLABLE PJ pj 
)

Print all string flags referenced by the function.

Definition at line 612 of file canalysis.c.

612  {
613  rz_return_if_fail(core && fcn);
614 
615  RzAnalysisXRef *xref;
616  RzListIter *iter;
618  rz_list_foreach (xrefs, iter, xref) {
619  RzFlagItem *f = rz_flag_get_by_spaces(core->flags, xref->to, RZ_FLAGS_FS_STRINGS, NULL);
620  if (!f || !f->space || strcmp(f->space->name, RZ_FLAGS_FS_STRINGS)) {
621  continue;
622  }
623  if (pj) {
624  pj_o(pj);
625  pj_kn(pj, "addr", xref->from);
626  pj_kn(pj, "ref", xref->to);
627  pj_ks(pj, "flag", f->name);
628  pj_end(pj);
629  } else {
630  rz_cons_printf("0x%08" PFMT64x " 0x%08" PFMT64x " %s\n", xref->from, xref->to, f->name);
631  }
632  }
633  rz_list_free(xrefs);
634 }
RZ_API RzFlagItem * rz_flag_get_by_spaces(RzFlag *f, ut64 off,...)
Definition: flag.c:326

References f, rz_analysis_ref_t::from, NULL, PFMT64x, pj_end(), pj_kn(), pj_ks(), pj_o(), rz_analysis_function_get_xrefs_from(), rz_cons_printf(), rz_flag_get_by_spaces(), RZ_FLAGS_FS_STRINGS, rz_list_free(), rz_return_if_fail, and rz_analysis_ref_t::to.

Referenced by rz_analysis_function_strings_handler().

◆ rz_core_analysis_function_until()

RZ_IPI void rz_core_analysis_function_until ( RzCore core,
ut64  addr_end 
)

Definition at line 6425 of file canalysis.c.

6425  {
6426  rz_return_if_fail(core->offset <= addr_end);
6427  ut64 addr = core->offset;
6428  int depth = 1;
6429  ut64 a, b;
6430  const char *c;
6431  a = rz_config_get_i(core->config, "analysis.from");
6432  b = rz_config_get_i(core->config, "analysis.to");
6433  c = rz_config_get(core->config, "analysis.limits");
6434  rz_config_set_i(core->config, "analysis.from", addr);
6435  rz_config_set_i(core->config, "analysis.to", addr_end);
6436  rz_config_set(core->config, "analysis.limits", "true");
6437 
6439  if (fcn) {
6440  rz_analysis_function_resize(fcn, addr_end - addr);
6441  }
6444  fcn = rz_analysis_get_fcn_in(core->analysis, addr, 0);
6445  if (fcn) {
6446  rz_analysis_function_resize(fcn, addr_end - addr);
6447  }
6448  rz_config_set_i(core->config, "analysis.from", a);
6449  rz_config_set_i(core->config, "analysis.to", b);
6450  rz_config_set(core->config, "analysis.limits", c ? c : "");
6451 }

References a, addr, rz_core_t::analysis, b, c, rz_core_t::config, core_noretl::core, rz_core_t::offset, rz_analysis_function_resize(), rz_analysis_get_fcn_in(), RZ_ANALYSIS_XREF_TYPE_NULL, rz_config_get(), rz_config_get_i(), rz_config_set(), rz_config_set_i(), rz_core_analysis_fcn(), rz_return_if_fail, ut64(), and UT64_MAX.

Referenced by rz_analysis_function_until_handler().

◆ rz_core_analysis_get_stats()

RZ_API RZ_OWN RzCoreAnalysisStats* rz_core_analysis_get_stats ( RZ_NONNULL RzCore core,
ut64  from,
ut64  to,
ut64  step 
)

Generate statistics for a range of memory, e.g. for a colorful overview bar.

Let fullsz = to + 1 - from. If fullsz % step = 0, then the result will be fullsz / step blocks of size step. Otherwise, it will be fullsz / step blocks of size step and one additional block covering the rest.

Parameters
lowestaddress to consider
highestaddress to consider, inclusive. Must be greater than or equal to from.
sizeof a single block in the output

Definition at line 3722 of file canalysis.c.

3722  {
3723  rz_return_val_if_fail(core && to >= from && step, NULL);
3725  RzAnalysisBlock *B;
3726  RzBinSymbol *S;
3727  RzListIter *iter, *iter2;
3728  ut64 at;
3729  RzCoreAnalysisStats *as = RZ_NEW0(RzCoreAnalysisStats);
3730  if (!as) {
3731  return NULL;
3732  }
3733  as->from = from;
3734  as->to = to;
3735  as->step = step;
3736  rz_vector_init(&as->blocks, sizeof(RzCoreAnalysisStatsItem), NULL, NULL);
3737  size_t count = (to == UT64_MAX && from == 0) ? rz_num_2_pow_64_div(step) : (to + 1 - from) / step;
3738  if (from + count * step != to + 1) {
3739  count++;
3740  }
3741  if (!count || SZT_MUL_OVFCHK(count, sizeof(RzCoreAnalysisStatsItem))) {
3743  return NULL;
3744  }
3745  RzCoreAnalysisStatsItem *blocks = rz_vector_insert_range(&as->blocks, 0, NULL, count);
3746  if (!blocks) {
3748  return NULL;
3749  }
3750  memset(blocks, 0, count * sizeof(RzCoreAnalysisStatsItem));
3751  for (at = from; at < to;) {
3752  RzIOMap *map = rz_io_map_get(core->io, at);
3753  size_t piece = (at - from) / step;
3754  blocks[piece].perm = map ? map->perm : (core->io->desc ? core->io->desc->perm : 0);
3755  ut64 prev = at;
3756  at += step;
3757  if (at < prev) {
3758  break;
3759  }
3760  }
3761  // iter all flags
3762  struct block_flags_stat_t u = { .step = step, .from = from, .blocks = blocks };
3763  rz_flag_foreach_range(core->flags, from, to, block_flags_stat, &u);
3764  // iter all functions
3765  rz_list_foreach (core->analysis->fcns, iter, F) {
3766  if (F->addr < from || F->addr > to) {
3767  continue;
3768  }
3769  size_t piece = (F->addr - from) / step;
3770  blocks[piece].functions++;
3771  ut64 last_piece = RZ_MIN((F->addr + rz_analysis_function_linear_size(F) - 1) / step, count - 1);
3772  for (; piece <= last_piece; piece++) {
3773  blocks[piece].in_functions++;
3774  }
3775  // iter all basic blocks
3776  rz_list_foreach (F->bbs, iter2, B) {
3777  if (B->addr < from || B->addr > to) {
3778  continue;
3779  }
3780  piece = (B->addr - from) / step;
3781  blocks[piece].blocks++;
3782  }
3783  }
3784  // iter all symbols
3785  rz_list_foreach (rz_bin_get_symbols(core->bin), iter, S) {
3786  if (S->vaddr < from || S->vaddr > to) {
3787  continue;
3788  }
3789  size_t piece = (S->vaddr - from) / step;
3790  blocks[piece].symbols++;
3791  }
3793  if (metas) {
3794  void **it;
3795  rz_pvector_foreach (metas, it) {
3796  RzIntervalNode *node = *it;
3797  RzAnalysisMetaItem *mi = node->data;
3798  if (node->start < from || node->end > to) {
3799  continue;
3800  }
3801  size_t piece = (node->start - from) / step;
3802  switch (mi->type) {
3803  case RZ_META_TYPE_STRING:
3804  blocks[piece].strings++;
3805  break;
3806  case RZ_META_TYPE_COMMENT:
3807  blocks[piece].comments++;
3808  break;
3809  default:
3810  break;
3811  }
3812  }
3814  }
3815  return as;
3816 }
#define B(x)
Definition: arc.h:166
RZ_API void rz_core_analysis_stats_free(RzCoreAnalysisStats *s)
Definition: canalysis.c:3818
static bool block_flags_stat(RzFlagItem *fi, void *user)
Definition: canalysis.c:3703
static states step(struct re_guts *, sopno, sopno, states, int, states)
Definition: engine.c:888
RZ_API void rz_flag_foreach_range(RZ_NONNULL RzFlag *f, ut64 from, ut64 to, RzFlagItemCb cb, void *user)
Definition: flag.c:813
RZ_API RzPVector * rz_meta_get_all_intersect(RzAnalysis *a, ut64 start, ut64 size, RzAnalysisMetaType type)
Definition: meta.c:227
static ut64 rz_num_2_pow_64_div(ut64 divisor)
Definition: rz_num.h:167
RZ_API void * rz_vector_insert_range(RzVector *vec, size_t index, void *first, size_t count)
Definition: vector.c:167
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
Definition: vector.c:33
static struct Type metas[]
Definition: swift.c:39
#define F(x)
Definition: tricore.h:111
#define S
Definition: zip_err_str.c:9

References B, block_flags_stat(), blocks, count, rz_interval_node_t::data, rz_interval_node_t::end, F, from, map(), memset(), metas, mi, NULL, rz_analysis_function_linear_size(), rz_bin_get_symbols(), rz_core_analysis_stats_free(), rz_flag_foreach_range(), rz_io_map_get(), rz_meta_get_all_intersect(), RZ_META_TYPE_ANY, RZ_META_TYPE_COMMENT, RZ_META_TYPE_STRING, RZ_MIN, RZ_NEW0, rz_num_2_pow_64_div(), rz_pvector_foreach, rz_pvector_free(), rz_return_val_if_fail, rz_vector_init(), rz_vector_insert_range(), S, rz_interval_node_t::start, block_flags_stat_t::step, step(), to, ut64(), and UT64_MAX.

Referenced by analBars(), cmd_print_bars(), and cmd_print_blocks().

◆ rz_core_analysis_graph()

RZ_API bool rz_core_analysis_graph ( RzCore core,
ut64  addr,
int  opts 
)

Definition at line 2917 of file canalysis.c.

2917  {
2918  ut64 from = rz_config_get_i(core->config, "graph.from");
2919  ut64 to = rz_config_get_i(core->config, "graph.to");
2920  const char *font = rz_config_get(core->config, "graph.font");
2921  int is_html = rz_cons_singleton()->is_html;
2922  int is_json = opts & RZ_CORE_ANALYSIS_JSON;
2923  int is_json_format_disasm = opts & RZ_CORE_ANALYSIS_JSON_FORMAT_DISASM;
2924  int is_keva = opts & RZ_CORE_ANALYSIS_KEYVALUE;
2925  int is_star = opts & RZ_CORE_ANALYSIS_STAR;
2926  RzConfigHold *hc;
2927  RzAnalysisFunction *fcni;
2928  RzListIter *iter;
2929  int nodes = 0;
2930  PJ *pj = NULL;
2931 
2932  if (!addr) {
2933  addr = core->offset;
2934  }
2935  if (rz_list_empty(core->analysis->fcns)) {
2936  return false;
2937  }
2938  hc = rz_config_hold_new(core->config);
2939  if (!hc) {
2940  return false;
2941  }
2942 
2943  rz_config_hold_i(hc, "asm.lines", "asm.bytes", "asm.dwarf", NULL);
2944  // opts |= RZ_CORE_ANALYSIS_GRAPHBODY;
2945  rz_config_set_i(core->config, "asm.lines", 0);
2946  rz_config_set_i(core->config, "asm.dwarf", 0);
2947  if (!is_json_format_disasm) {
2948  rz_config_hold_i(hc, "asm.bytes", NULL);
2949  rz_config_set_i(core->config, "asm.bytes", 0);
2950  }
2951  if (!is_html && !is_json && !is_keva && !is_star) {
2952  const char *gv_edge = rz_config_get(core->config, "graph.gv.edge");
2953  const char *gv_node = rz_config_get(core->config, "graph.gv.node");
2954  const char *gv_spline = rz_config_get(core->config, "graph.gv.spline");
2955  if (!gv_edge || !*gv_edge) {
2956  gv_edge = "arrowhead=\"normal\"";
2957  }
2958  if (!gv_node || !*gv_node) {
2959  gv_node = "fillcolor=gray style=filled shape=box";
2960  }
2961  if (!gv_spline || !*gv_spline) {
2962  gv_spline = "splines=\"ortho\"";
2963  }
2964  rz_cons_printf("digraph code {\n"
2965  "\tgraph [bgcolor=azure fontsize=8 fontname=\"%s\" %s];\n"
2966  "\tnode [%s];\n"
2967  "\tedge [%s];\n",
2968  font, gv_spline, gv_node, gv_edge);
2969  }
2970  if (is_json) {
2971  pj = pj_new();
2972  if (!pj) {
2974  rz_config_hold_free(hc);
2975  return false;
2976  }
2977  pj_a(pj);
2978  }
2979  rz_list_foreach (core->analysis->fcns, iter, fcni) {
2981  (addr == UT64_MAX || rz_analysis_get_fcn_in(core->analysis, addr, 0) == fcni)) {
2982  if (addr == UT64_MAX && (from != UT64_MAX && to != UT64_MAX)) {
2983  if (fcni->addr < from || fcni->addr > to) {
2984  continue;
2985  }
2986  }
2987  nodes += core_analysis_graph_nodes(core, fcni, opts, pj);
2988  if (addr != UT64_MAX) {
2989  break;
2990  }
2991  }
2992  }
2993  if (!nodes) {
2994  if (!is_html && !is_json && !is_keva) {
2996  if (is_star) {
2997  char *name = get_title(fcn ? fcn->addr : addr);
2998  rz_cons_printf("agn %s;", name);
2999  } else {
3000  rz_cons_printf("\t\"0x%08" PFMT64x "\";\n", fcn ? fcn->addr : addr);
3001  }
3002  }
3003  }
3004  if (!is_keva && !is_html && !is_json && !is_star && !is_json_format_disasm) {
3005  rz_cons_printf("}\n");
3006  }
3007  if (is_json) {
3008  pj_end(pj);
3009  rz_cons_printf("%s\n", pj_string(pj));
3010  pj_free(pj);
3011  }
3013  rz_config_hold_free(hc);
3014  return true;
3015 }
static int core_analysis_graph_nodes(RzCore *core, RzAnalysisFunction *fcn, int opts, PJ *pj)
Definition: canalysis.c:1906
RZ_API void rz_config_hold_restore(RzConfigHold *h)
Restore whatever config options were previously saved in h.
Definition: hold.c:132

References addr, rz_analysis_function_t::addr, rz_core_t::analysis, rz_core_t::config, core_analysis_graph_nodes(), rz_analysis_t::fcns, from, get_title(), rz_cons_t::is_html, NULL, rz_core_t::offset, PFMT64x, pj_a(), pj_end(), pj_free(), pj_new(), pj_string(), RZ_ANALYSIS_FCN_TYPE_FCN, RZ_ANALYSIS_FCN_TYPE_LOC, RZ_ANALYSIS_FCN_TYPE_SYM, rz_analysis_get_fcn_in(), rz_config_get(), rz_config_get_i(), rz_config_hold_free(), rz_config_hold_i(), rz_config_hold_new(), rz_config_hold_restore(), rz_config_set_i(), rz_cons_printf(), rz_cons_singleton(), RZ_CORE_ANALYSIS_JSON, RZ_CORE_ANALYSIS_JSON_FORMAT_DISASM, RZ_CORE_ANALYSIS_KEYVALUE, RZ_CORE_ANALYSIS_STAR, to, rz_analysis_function_t::type, ut64(), and UT64_MAX.

Referenced by cmd_analysis_graph().

◆ rz_core_analysis_graph_to()

RZ_API RzList* rz_core_analysis_graph_to ( RzCore core,
ut64  addr,
int  n 
)

Definition at line 2895 of file canalysis.c.

2895  {
2896  int depth = rz_config_get_i(core->config, "analysis.graph_depth");
2897  RzList *path, *paths = rz_list_new();
2898  HtUP *avoid = ht_up_new0();
2899  while (n) {
2900  path = analysis_graph_to(core, addr, depth, avoid);
2901  if (path) {
2902  rz_list_append(paths, path);
2903  if (rz_list_length(path) >= 2) {
2905  ht_up_update(avoid, last->addr, last);
2906  n--;
2907  continue;
2908  }
2909  }
2910  // no more path found
2911  break;
2912  }
2913  ht_up_free(avoid);
2914  return paths;
2915 }
RZ_API RZ_BORROW void * rz_list_get_n(RZ_NONNULL const RzList *list, ut32 n)
Returns the N-th element of the list.
Definition: list.c:574

References addr, rz_analysis_bb_t::addr, analysis_graph_to(), rz_core_t::config, n, path, rz_config_get_i(), rz_list_append(), rz_list_get_n(), rz_list_length(), and rz_list_new().

◆ rz_core_analysis_hint_list_print()

RZ_API void rz_core_analysis_hint_list_print ( RzAnalysis a,
RzCmdStateOutput state 
)

Definition at line 1422 of file canalysis.c.

1422  {
1424  RBTree tree = NULL;
1425  // Collect all hints in the tree to sort them
1429  print_hint_tree(tree, state);
1431 }
bool print_arch_hint_cb(ut64 addr, RZ_NULLABLE const char *arch, void *user)
Definition: canalysis.c:1357
bool print_bits_hint_cb(ut64 addr, int bits, void *user)
Definition: canalysis.c:1369
static void print_hint_tree(RBTree tree, RzCmdStateOutput *state)
Definition: canalysis.c:1381
void hint_node_free(RBNode *node, void *user)
Definition: canalysis.c:1330
bool print_addr_hint_cb(ut64 addr, const RzVector *records, void *user)
Definition: canalysis.c:1345
RZ_API void rz_analysis_addr_hints_foreach(RzAnalysis *analysis, RzAnalysisAddrHintRecordsCb cb, void *user)
Definition: hint.c:426
RZ_API void rz_analysis_arch_hints_foreach(RzAnalysis *analysis, RzAnalysisArchHintCb cb, void *user)
Definition: hint.c:431
RZ_API void rz_analysis_bits_hints_foreach(RzAnalysis *analysis, RzAnalysisBitsHintCb cb, void *user)
Definition: hint.c:442
RZ_API void rz_rbtree_free(RZ_NULLABLE RBNode *root, RBNodeFree freefn, void *user)
Definition: rbtree.c:281

References a, hint_node_free(), NULL, print_addr_hint_cb(), print_arch_hint_cb(), print_bits_hint_cb(), print_hint_tree(), rz_analysis_addr_hints_foreach(), rz_analysis_arch_hints_foreach(), rz_analysis_bits_hints_foreach(), rz_rbtree_free(), and rz_return_if_fail.

Referenced by rz_analysis_hint_list_handler().

◆ rz_core_analysis_hint_print()

RZ_API void rz_core_analysis_hint_print ( RzAnalysis a,
ut64  addr,
RzCmdStateOutput state 
)

Definition at line 1433 of file canalysis.c.

1433  {
1435  RBTree tree = NULL;
1436  ut64 hint_addr = UT64_MAX;
1437  const char *arch = rz_analysis_hint_arch_at(a, addr, &hint_addr);
1438  if (hint_addr != UT64_MAX) {
1439  print_arch_hint_cb(hint_addr, arch, &tree);
1440  }
1441  int bits = rz_analysis_hint_bits_at(a, addr, &hint_addr);
1442  if (hint_addr != UT64_MAX) {
1443  print_bits_hint_cb(hint_addr, bits, &tree);
1444  }
1445  const RzVector *addr_hints = rz_analysis_addr_hints_at(a, addr);
1446  if (addr_hints) {
1447  print_addr_hint_cb(addr, addr_hints, &tree);
1448  }
1449  print_hint_tree(tree, state);
1451 }
RZ_API RZ_NULLABLE const RzVector * rz_analysis_addr_hints_at(RzAnalysis *analysis, ut64 addr)
Definition: hint.c:412
RZ_API int rz_analysis_hint_bits_at(RzAnalysis *analysis, ut64 addr, RZ_NULLABLE ut64 *hint_addr)
Definition: hint.c:397
RZ_API RZ_NULLABLE RZ_BORROW const char * rz_analysis_hint_arch_at(RzAnalysis *analysis, ut64 addr, RZ_NULLABLE ut64 *hint_addr)
Definition: hint.c:382

References a, addr, arch, bits(), hint_node_free(), NULL, print_addr_hint_cb(), print_arch_hint_cb(), print_bits_hint_cb(), print_hint_tree(), rz_analysis_addr_hints_at(), rz_analysis_hint_arch_at(), rz_analysis_hint_bits_at(), rz_rbtree_free(), rz_return_if_fail, ut64(), and UT64_MAX.

Referenced by rz_analysis_hint_list_at_handler().

◆ rz_core_analysis_hint_set_offset()

RZ_API bool rz_core_analysis_hint_set_offset ( RZ_NONNULL RzCore core,
RZ_NONNULL const char *  struct_member 
)

Set analysis hint for the first immediate of the instruction at current offset to struct_member.

Parameters
coreThe RzCore instance
struct_memberstruct.member

Definition at line 6947 of file canalysis.c.

6947  {
6948  rz_return_val_if_fail(core && struct_member, false);
6949  RzAnalysisOp op = { 0 };
6950  ut8 code[128] = { 0 };
6951  if (!rz_io_read_at(core->io, core->offset, code, sizeof(code))) {
6952  return false;
6953  }
6954  bool res = false;
6955  int ret = rz_analysis_op(core->analysis, &op, core->offset, code, sizeof(code), RZ_ANALYSIS_OP_MASK_VAL);
6956  if (ret < 1) {
6957  goto exit;
6958  }
6959  // HACK: Just convert only the first imm seen
6960  ut64 offimm = 0;
6961  for (int i = 0; i < 3; i++) {
6962  if (op.src[i]) {
6963  if (op.src[i]->imm) {
6964  offimm = op.src[i]->imm;
6965  } else if (op.src[i]->delta) {
6966  offimm = op.src[i]->delta;
6967  }
6968  }
6969  }
6970  if (!offimm && op.dst) {
6971  if (op.dst->imm) {
6972  offimm = op.dst->imm;
6973  } else if (op.dst->delta) {
6974  offimm = op.dst->delta;
6975  }
6976  }
6977  if (!offimm) {
6978  goto exit;
6979  }
6980  // TODO: Allow to select from multiple choices
6981  RzList *otypes = rz_type_db_get_by_offset(core->analysis->typedb, offimm);
6982  RzListIter *iter;
6983  RzTypePath *tpath;
6984  rz_list_foreach (otypes, iter, tpath) {
6985  // TODO: Support also arrays and pointers
6986  if (tpath->typ->kind == RZ_TYPE_KIND_IDENTIFIER) {
6987  if (!strcmp(struct_member, tpath->path)) {
6988  rz_analysis_hint_set_offset(core->analysis, core->offset, tpath->path);
6989  break;
6990  }
6991  }
6992  }
6993  rz_list_free(otypes);
6994  res = true;
6995 exit:
6997  return res;
6998 }
RZ_API void rz_analysis_hint_set_offset(RzAnalysis *a, ut64 addr, const char *typeoff)
Definition: hint.c:203
@ RZ_TYPE_KIND_IDENTIFIER
Definition: rz_type.h:128
RzType * typ
Definition: rz_type.h:175
char * path
Definition: rz_type.h:176
RzTypeKind kind
Definition: rz_type.h:155
RZ_API RZ_OWN RzList * rz_type_db_get_by_offset(const RzTypeDB *typedb, ut64 offset)
Returns the list of all structured types that have members matching the offset.
Definition: path.c:219

References rz_core_t::analysis, core_noretl::core, test-lz4-list::exit, i, rz_core_t::io, rz_type_t::kind, rz_core_t::offset, rz_type_path_t::path, rz_analysis_hint_set_offset(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_VAL, rz_io_read_at(), rz_list_free(), rz_return_val_if_fail, rz_type_db_get_by_offset(), RZ_TYPE_KIND_IDENTIFIER, rz_type_path_t::typ, rz_analysis_t::typedb, and ut64().

Referenced by rz_analysis_hint_set_offset_handler().

◆ rz_core_analysis_importxrefs()

RZ_API RzGraph* rz_core_analysis_importxrefs ( RzCore core)

Definition at line 2387 of file canalysis.c.

2387  {
2388  RzBinObject *obj = rz_bin_cur_object(core->bin);
2389  bool va = core->io->va || core->bin->is_debugger;
2390 
2391  RzListIter *iter;
2392  RzBinImport *imp;
2393  if (!obj) {
2394  return NULL;
2395  }
2396  RzGraph *graph = rz_graph_new();
2397  if (!graph) {
2398  return NULL;
2399  }
2400  rz_list_foreach (obj->imports, iter, imp) {
2402  ut64 addr = sym ? (va ? rz_bin_object_get_vaddr(obj, sym->paddr, sym->vaddr) : sym->paddr) : UT64_MAX;
2403  if (addr && addr != UT64_MAX) {
2404  add_single_addr_xrefs(core, addr, graph);
2405  } else {
2406  rz_graph_add_node_info(graph, imp->name, NULL, 0);
2407  }
2408  }
2409  return graph;
2410 }
RZ_API RzBinSymbol * rz_bin_object_get_symbol_of_import(RzBinObject *o, RzBinImport *imp)
Find the symbol that represents the given import This is necessary for example to determine the addre...
Definition: bobj.c:616
RzList * imports
Definition: rz_bin.h:268
int is_debugger
Definition: rz_bin.h:350

References add_single_addr_xrefs(), addr, rz_core_t::bin, rz_bin_object_t::imports, rz_core_t::io, rz_bin_t::is_debugger, rz_bin_import_t::name, NULL, rz_bin_symbol_t::paddr, rz_bin_cur_object(), rz_bin_object_get_symbol_of_import(), rz_bin_object_get_vaddr(), rz_graph_add_node_info(), rz_graph_new(), ut64(), UT64_MAX, rz_io_t::va, and rz_bin_symbol_t::vaddr.

Referenced by cmd_analysis_graph().

◆ rz_core_analysis_name()

RZ_API RZ_OWN RzCoreAnalysisName* rz_core_analysis_name ( RZ_NONNULL RzCore core,
ut64  addr 
)

Get information on whatever var/flag/function is used at addr.

Returns
RzAnalysisName

Definition at line 7203 of file canalysis.c.

7203  {
7204  rz_return_val_if_fail(core && core->analysis, NULL);
7205 
7206  ut8 buf[128];
7207  if (!rz_io_read_at(core->io, addr, buf, sizeof(buf))) {
7208  return NULL;
7209  }
7210 
7211  RzCoreAnalysisName *p = RZ_NEW0(RzCoreAnalysisName);
7212  if (!p) {
7213  return NULL;
7214  }
7215 
7216  RzAnalysisOp op;
7217  rz_analysis_op(core->analysis, &op, core->offset,
7218  buf, sizeof(buf), RZ_ANALYSIS_OP_MASK_BASIC);
7219  RzAnalysisVar *var = rz_analysis_get_used_function_var(core->analysis, op.addr);
7220  ut64 tgt_addr = op.jump != UT64_MAX ? op.jump : op.ptr;
7222 
7223  if (var) {
7224  p->type = RZ_CORE_ANALYSIS_NAME_TYPE_VAR;
7225  p->name = strdup(var->name);
7226  p->offset = op.addr;
7227  } else if (tgt_addr != UT64_MAX) {
7228  RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, tgt_addr);
7229  RzFlagItem *f = rz_flag_get_i(core->flags, tgt_addr);
7230  if (fcn) {
7231  p->type = RZ_CORE_ANALYSIS_NAME_TYPE_FUNCTION;
7232  p->name = strdup(fcn->name);
7233  p->offset = tgt_addr;
7234  } else if (f) {
7235  p->type = RZ_CORE_ANALYSIS_NAME_TYPE_FLAG;
7236  p->name = strdup(f->name);
7237  p->realname = strdup(f->realname);
7238  p->offset = tgt_addr;
7239  } else {
7240  p->type = RZ_CORE_ANALYSIS_NAME_TYPE_ADDRESS;
7241  p->offset = tgt_addr;
7242  }
7243  } else {
7245  return NULL;
7246  }
7247 
7248  return p;
7249 }
RZ_API void rz_core_analysis_name_free(RZ_NULLABLE RzCoreAnalysisName *p)
Definition: canalysis.c:7153
RZ_DEPRECATE RZ_API RzAnalysisVar * rz_analysis_get_used_function_var(RzAnalysis *analysis, ut64 addr)
Definition: var.c:398

References addr, rz_core_t::analysis, core_noretl::core, f, rz_core_t::flags, rz_core_t::io, rz_analysis_function_t::name, rz_analysis_var_t::name, NULL, rz_core_t::offset, op, p, rz_analysis_get_function_at(), rz_analysis_get_used_function_var(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, rz_core_analysis_name_free(), rz_flag_get_i(), rz_io_read_at(), RZ_NEW0, rz_return_val_if_fail, strdup(), ut64(), and UT64_MAX.

Referenced by core_analysis_name_print().

◆ rz_core_analysis_name_free()

RZ_API void rz_core_analysis_name_free ( RZ_NULLABLE RzCoreAnalysisName *  p)

Definition at line 7153 of file canalysis.c.

7153  {
7154  if (!p) {
7155  return;
7156  }
7157  free(p->name);
7158  free(p->realname);
7159  free(p);
7160 }

References free(), and p.

Referenced by core_analysis_name_print(), and rz_core_analysis_name().

◆ rz_core_analysis_name_type_to_str()

RZ_API RZ_BORROW const char* rz_core_analysis_name_type_to_str ( RzCoreAnalysisNameType  typ)

Convert typ to string (const char*)

Definition at line 7140 of file canalysis.c.

7140  {
7141  switch (typ) {
7142  case RZ_CORE_ANALYSIS_NAME_TYPE_VAR:
7143  case RZ_CORE_ANALYSIS_NAME_TYPE_FUNCTION:
7144  case RZ_CORE_ANALYSIS_NAME_TYPE_FLAG:
7145  case RZ_CORE_ANALYSIS_NAME_TYPE_ADDRESS:
7146  return RzCoreAnalysisNameTypeStrs[typ];
7147  default:
7149  return NULL;
7150  }
7151 }
static const char * RzCoreAnalysisNameTypeStrs[]
Definition: canalysis.c:7130

References NULL, rz_warn_if_reached, and RzCoreAnalysisNameTypeStrs.

Referenced by core_analysis_name_print().

◆ rz_core_analysis_op()

RZ_API RzAnalysisOp* rz_core_analysis_op ( RzCore core,
ut64  addr,
int  mask 
)

Definition at line 1033 of file canalysis.c.

1033  {
1034  int len;
1035  ut8 buf[32];
1036  ut8 *ptr;
1037 
1038  rz_return_val_if_fail(core, NULL);
1039  if (addr == UT64_MAX) {
1040  return NULL;
1041  }
1043  if (!op) {
1044  return NULL;
1045  }
1046  int delta = (addr - core->offset);
1047  int minopsz = 8;
1048  if (delta > 0 && delta + minopsz < core->blocksize && addr >= core->offset && addr + 16 < core->offset + core->blocksize) {
1049  ptr = core->block + delta;
1050  len = core->blocksize - delta;
1051  if (len < 1) {
1052  goto err_op;
1053  }
1054  } else {
1055  if (!rz_io_read_at(core->io, addr, buf, sizeof(buf))) {
1056  goto err_op;
1057  }
1058  ptr = buf;
1059  len = sizeof(buf);
1060  }
1061  if (rz_analysis_op(core->analysis, op, addr, ptr, len, mask) < 1) {
1062  goto err_op;
1063  }
1064  // TODO This code block must be deleted when all the analysis plugins support disasm
1065  if (!op->mnemonic && mask & RZ_ANALYSIS_OP_MASK_DISASM) {
1066  RzAsmOp asmop;
1067  RZ_LOG_DEBUG("Unimplemented RZ_ANALYSIS_OP_MASK_DISASM for current analysis.arch. Using the RzAsmOp as fallback for now.\n");
1068  rz_asm_set_pc(core->rasm, addr);
1069  rz_asm_op_init(&asmop);
1070  if (rz_asm_disassemble(core->rasm, &asmop, ptr, len) > 0) {
1071  op->mnemonic = strdup(rz_strbuf_get(&asmop.buf_asm));
1072  }
1073  rz_asm_op_fini(&asmop);
1074  }
1075  return op;
1076 err_op:
1078  return NULL;
1079 }
RZ_API void rz_asm_op_fini(RzAsmOp *op)
Definition: aop.c:21
RZ_API void rz_asm_op_init(RzAsmOp *op)
Definition: aop.c:15
@ RZ_ANALYSIS_OP_MASK_DISASM
Definition: rz_analysis.h:445
RZ_API char * rz_strbuf_get(RzStrBuf *sb)
Definition: strbuf.c:321
RzStrBuf buf_asm
Definition: rz_asm.h:72
static int blocksize
Definition: visual.c:15

References addr, rz_core_t::analysis, rz_core_t::block, blocksize, rz_core_t::blocksize, rz_asm_op_t::buf_asm, delta, rz_core_t::io, len, mask, NULL, rz_core_t::offset, op, rz_core_t::rasm, rz_analysis_op(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_DISASM, rz_asm_disassemble(), rz_asm_op_fini(), rz_asm_op_init(), rz_asm_set_pc(), rz_io_read_at(), RZ_LOG_DEBUG, RZ_NEW0, rz_return_val_if_fail, rz_strbuf_get(), strdup(), and UT64_MAX.

Referenced by __cursor_down(), analBars(), analPaths(), analysis_block_cb(), analysis_function_vars_getsetref(), cmd_analysis_esil(), disasm_until_ret(), disassemble_till_return_is_found(), disassembly_as_table(), ds_pre_emulation(), get_src_regname(), handle_stack_canary(), nextOpcode(), op_cache_get(), propagate_types_among_used_variables(), rz_cmd_debug_traces_esil_i_handler(), rz_cmd_print(), rz_core_analysis_continue_until_call(), rz_core_analysis_continue_until_syscall(), rz_core_analysis_cycles(), rz_core_analysis_esil_fcn(), rz_core_analysis_esil_step_over(), rz_core_analysis_var_rename(), rz_core_get_stacksz(), rz_core_print_func_args(), rz_core_visual_cmd(), rz_core_visual_define(), and update_stat_for_op().

◆ rz_core_analysis_paths()

RZ_API void rz_core_analysis_paths ( RzCore core,
ut64  from,
ut64  to,
bool  followCalls,
int  followDepth,
bool  is_json 
)

Definition at line 5121 of file canalysis.c.

5121  {
5124  PJ *pj = NULL;
5125  if (!b0) {
5126  eprintf("Cannot find basic block for 0x%08" PFMT64x "\n", from);
5127  return;
5128  }
5129  if (!b1) {
5130  eprintf("Cannot find basic block for 0x%08" PFMT64x "\n", to);
5131  return;
5132  }
5133  RzCoreAnalPaths rcap = { 0 };
5134  rcap.visited = ht_uu_new0();
5135  rcap.path = rz_list_new();
5136  rcap.core = core;
5137  rcap.from = from;
5138  rcap.fromBB = b0;
5139  rcap.to = to;
5140  rcap.toBB = b1;
5141  rcap.cur = b0;
5142  rcap.count = rz_config_get_i(core->config, "search.maxhits");
5143  ;
5144  rcap.followCalls = followCalls;
5145  rcap.followDepth = followDepth;
5146 
5147  // Initialize a PJ object for json mode
5148  if (is_json) {
5149  pj = pj_new();
5150  pj_a(pj);
5151  }
5152 
5153  analPaths(&rcap, pj);
5154 
5155  if (is_json) {
5156  pj_end(pj);
5157  rz_cons_printf("%s", pj_string(pj));
5158  }
5159 
5160  if (pj) {
5161  pj_free(pj);
5162  }
5163 
5164  ht_uu_free(rcap.visited);
5165  rz_list_free(rcap.path);
5166 }
RzList * path
Definition: canalysis.c:5025
RzAnalysisBlock * cur
Definition: canalysis.c:5031
RzAnalysisBlock * toBB
Definition: canalysis.c:5030
RzAnalysisBlock * fromBB
Definition: canalysis.c:5028
RzCore * core
Definition: canalysis.c:5026

References analPaths(), rz_core_t::analysis, b1, rz_core_t::config, RzCoreAnalPaths::core, RzCoreAnalPaths::count, RzCoreAnalPaths::cur, eprintf, RzCoreAnalPaths::followCalls, RzCoreAnalPaths::followDepth, RzCoreAnalPaths::from, from, RzCoreAnalPaths::fromBB, NULL, RzCoreAnalPaths::path, PFMT64x, pj_a(), pj_end(), pj_free(), pj_new(), pj_string(), rz_analysis_find_most_relevant_block_in(), rz_config_get_i(), rz_cons_printf(), rz_list_free(), rz_list_new(), RzCoreAnalPaths::to, to, RzCoreAnalPaths::toBB, and RzCoreAnalPaths::visited.

Referenced by rz_cmd_search().

◆ rz_core_analysis_propagate_noreturn()

RZ_API void rz_core_analysis_propagate_noreturn ( RzCore core,
ut64  addr 
)

Definition at line 5630 of file canalysis.c.

5630  {
5631  RzList *todo = rz_list_newf(free);
5632  if (!todo) {
5633  return;
5634  }
5635 
5636  HtUU *done = ht_uu_new0();
5637  if (!done) {
5638  rz_list_free(todo);
5639  return;
5640  }
5641 
5642  RzAnalysisFunction *request_fcn = NULL;
5643  if (addr != UT64_MAX) {
5644  request_fcn = rz_analysis_get_function_at(core->analysis, addr);
5645  if (!request_fcn) {
5646  rz_list_free(todo);
5647  ht_uu_free(done);
5648  return;
5649  }
5650  }
5651 
5652  // At first we propagate all noreturn functions that are imports or symbols
5653  // via the relocations
5655 
5656  // find known noreturn functions to propagate
5657  RzListIter *iter;
5659  rz_list_foreach (core->analysis->fcns, iter, f) {
5660  if (f->is_noreturn) {
5661  ut64 *n = ut64_new(f->addr);
5662  rz_list_append(todo, n);
5663  }
5664  }
5665  while (!rz_list_empty(todo)) {
5666  ut64 *paddr = (ut64 *)rz_list_pop(todo);
5667  ut64 noret_addr = *paddr;
5668  free(paddr);
5669  if (rz_cons_is_breaked()) {
5670  break;
5671  }
5672  RzList *xrefs = rz_analysis_xrefs_get_to(core->analysis, noret_addr);
5673  RzAnalysisXRef *xref;
5674  rz_list_foreach (xrefs, iter, xref) {
5676  if (!xrefop) {
5677  eprintf("Cannot analyze opcode at 0x%08" PFMT64x "\n", xref->from);
5678  continue;
5679  }
5680  ut64 call_addr = xref->from;
5681  ut64 chop_addr = call_addr + xrefop->size;
5682  rz_analysis_op_free(xrefop);
5683  if (xref->type != RZ_ANALYSIS_XREF_TYPE_CALL) {
5684  continue;
5685  }
5686 
5687  // Find the block that has an instruction at exactly the xref addr
5688  RzAnalysisBlock *block = find_block_at_xref_addr(core, call_addr);
5689  if (!block) {
5690  continue;
5691  }
5692 
5693  RzList *block_fcns = rz_list_clone(block->fcns);
5694  if (request_fcn) {
5695  // specific function requested, check if it contains the bb
5696  if (!rz_list_contains(block->fcns, request_fcn)) {
5697  goto kontinue;
5698  }
5699  } else {
5700  // rz_analysis_block_chop_noreturn() might free the block!
5701  block = rz_analysis_block_chop_noreturn(block, chop_addr);
5702  }
5703 
5704  RzListIter *fit;
5705  rz_list_foreach (block_fcns, fit, f) {
5706  bool found = ht_uu_find(done, f->addr, NULL) != 0;
5707  if (f->addr && !found && analyze_noreturn_function(core, f)) {
5708  f->is_noreturn = true;
5709  rz_analysis_noreturn_add(core->analysis, NULL, f->addr);
5710  ut64 *n = malloc(sizeof(ut64));
5711  *n = f->addr;
5712  rz_list_append(todo, n);
5713  ht_uu_insert(done, *n, 1);
5714  }
5715  }
5716  kontinue:
5717  if (block) {
5718  rz_analysis_block_unref(block);
5719  }
5720  rz_list_free(block_fcns);
5721  }
5722  rz_list_free(xrefs);
5723  }
5724  rz_list_free(todo);
5725  ht_uu_free(done);
5726 }
RZ_API void rz_analysis_block_unref(RzAnalysisBlock *bb)
Definition: block.c:370
RZ_API void rz_core_analysis_propagate_noreturn_relocs(RzCore *core, ut64 addr)
Definition: canalysis.c:5610
struct tab * done
Definition: enough.c:233
RZ_API RZ_BORROW RzListIter * rz_list_contains(RZ_NONNULL const RzList *list, RZ_NONNULL const void *ptr)
Returns the RzListIter of the given pointer, if found.
Definition: list.c:592
@ RZ_ANALYSIS_OP_MASK_ALL
Definition: rz_analysis.h:447

References addr, rz_core_t::analysis, analyze_noreturn_function(), core_noretl::core, done, eprintf, f, rz_analysis_t::fcns, rz_analysis_bb_t::fcns, find_block_at_xref_addr(), found, free(), rz_analysis_ref_t::from, malloc(), n, NULL, PFMT64x, rz_analysis_block_chop_noreturn(), rz_analysis_block_unref(), rz_analysis_get_function_at(), rz_analysis_noreturn_add(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_ALL, RZ_ANALYSIS_XREF_TYPE_CALL, rz_analysis_xrefs_get_to(), rz_cons_is_breaked(), rz_core_analysis_propagate_noreturn_relocs(), rz_core_op_analysis(), rz_list_append(), rz_list_clone(), rz_list_contains(), rz_list_free(), rz_list_newf(), rz_list_pop(), rz_analysis_op_t::size, core_noretl::todo, rz_analysis_ref_t::type, ut64(), and UT64_MAX.

Referenced by rz_autoname_all_functions_noreturn_handler(), rz_core_analysis_everything(), and rz_core_analysis_function_add().

◆ rz_core_analysis_propagate_noreturn_relocs()

RZ_API void rz_core_analysis_propagate_noreturn_relocs ( RzCore core,
ut64  addr 
)

Definition at line 5610 of file canalysis.c.

5610  {
5611  // Processing every reference calls rz_analysis_op() which sometimes changes the
5612  // state of `asm.bits` variable, thus we save it to restore after the processing
5613  // is finished.
5614  int bits1 = core->analysis->bits;
5615  int bits2 = core->rasm->bits;
5616  // find known noreturn functions to propagate
5618  // List of the potentially noreturn functions
5619  SetU *todo = set_u_new();
5620  struct core_noretl u = { core, noretl, todo };
5621  ht_up_foreach(core->analysis->ht_xrefs_to, process_refs_cb, &u);
5623  core->analysis->bits = bits1;
5624  core->rasm->bits = bits2;
5625  // For every function in todo list analyze if it's potentially become noreturn
5626  ht_up_foreach(todo, reanalyze_fcns_cb, core);
5627  set_u_free(todo);
5628 }
RZ_API RzList * rz_analysis_noreturn_functions(RzAnalysis *analysis)
Definition: analysis.c:623
static bool reanalyze_fcns_cb(void *u, const ut64 k, const void *v)
Definition: canalysis.c:5600
static bool process_refs_cb(void *u, const ut64 k, const void *v)
Definition: canalysis.c:5594
RZ_API SetU * set_u_new(void)
Definition: set.c:30
RZ_API void set_u_free(SetU *s)
Definition: set.c:46
HtUP * ht_xrefs_to
Definition: rz_analysis.h:592

References rz_core_t::analysis, rz_analysis_t::bits, rz_asm_t::bits, core_noretl::core, rz_analysis_t::ht_xrefs_to, core_noretl::noretl, process_refs_cb(), rz_core_t::rasm, reanalyze_fcns_cb(), rz_analysis_noreturn_functions(), rz_list_free(), set_u_free(), set_u_new(), and core_noretl::todo.

Referenced by rz_core_analysis_propagate_noreturn().

◆ rz_core_analysis_refs()

RZ_API bool rz_core_analysis_refs ( RZ_NONNULL RzCore core,
size_t  nbytes 
)

Analyze xrefs and prints the result.

Parameters
[in]coreThe RzCore to use
[in]nbytesSets a custom boundary from current offset for N bytes (set it to 0 to use the maps)
Returns
False on failure, otherwise true

Definition at line 3272 of file canalysis.c.

3272  {
3273  rz_return_val_if_fail(core, false);
3274 
3275  bool cfg_debug = rz_config_get_b(core->config, "cfg.debug");
3276  ut64 from = 0, to = 0;
3277 
3278  if (nbytes) {
3279  from = core->offset;
3280  to = core->offset + nbytes;
3282  } else if (cfg_debug) {
3283  // get boundaries of current memory map, section or io map
3284  RzDebugMap *map = rz_debug_map_get(core->dbg, core->offset);
3285  if (!map) {
3286  RZ_LOG_ERROR("Cannot find debug map boundaries at current offset\n");
3287  return false;
3288  }
3289  from = map->addr;
3290  to = map->addr_end;
3292  }
3293 
3294  RzList *list = rz_core_get_boundaries_prot(core, RZ_PERM_X, NULL, "analysis");
3295  RzListIter *iter;
3296  RzIOMap *map;
3297  if (!list) {
3298  RZ_LOG_ERROR("cannot find maps with exec permisions\n");
3299  return false;
3300  }
3301 
3302  rz_list_foreach (list, iter, map) {
3303  from = map->itv.addr;
3304  to = rz_itv_end(map->itv);
3305  if (rz_cons_is_breaked()) {
3306  break;
3307  }
3309  }
3310  rz_list_free(list);
3311  return true;
3312 }
static bool core_search_for_xrefs_in_boundaries(RzCore *core, ut64 from, ut64 to)
Definition: canalysis.c:3228
RZ_API RZ_OWN RzList * rz_core_get_boundaries_prot(RzCore *core, int perm, const char *mode, const char *prefix)
Definition: cmd_search.c:577
static static sync static getppid static getegid const char static filename char static len const char char static bufsiz static mask static vfork const void static prot static getpgrp const char static swapflags static arg static fd static protocol static who struct sockaddr static addrlen static backlog struct timeval struct timezone static tz const struct iovec static count static mode const void const struct sockaddr static tolen const char static pathname void static offset struct stat static buf void nbytes
Definition: sflib.h:113
static ut64 rz_itv_end(RzInterval itv)
Definition: rz_itv.h:42

References core_search_for_xrefs_in_boundaries(), from, list(), map(), nbytes, NULL, rz_config_get_b(), rz_cons_is_breaked(), rz_core_get_boundaries_prot(), rz_debug_map_get(), rz_itv_end(), rz_list_free(), RZ_LOG_ERROR, RZ_PERM_X, rz_return_val_if_fail, to, and ut64().

Referenced by __references_cb(), objc_analyze(), rz_analyze_xrefs_section_bytes_handler(), and rz_core_analysis_everything().

◆ rz_core_analysis_rename()

RZ_API bool rz_core_analysis_rename ( RZ_NONNULL RzCore core,
RZ_NONNULL const char *  name,
ut64  addr 
)

Rename whatever var/flag/function is used at addr to name.

Returns
success?

Definition at line 7166 of file canalysis.c.

7166  {
7167  rz_return_val_if_fail(core && core->analysis && RZ_STR_ISNOTEMPTY(name), false);
7168 
7169  ut8 buf[128];
7170  if (!rz_io_read_at(core->io, addr, buf, sizeof(buf))) {
7171  return false;
7172  }
7173 
7174  RzAnalysisOp op;
7175  rz_analysis_op(core->analysis, &op, core->offset,
7176  buf, sizeof(buf), RZ_ANALYSIS_OP_MASK_BASIC);
7177  RzAnalysisVar *var = rz_analysis_get_used_function_var(core->analysis, op.addr);
7178  ut64 tgt_addr = op.jump != UT64_MAX ? op.jump : op.ptr;
7180 
7181  bool result = false;
7182  if (var) {
7183  result = rz_analysis_var_rename(var, name, true);
7184  } else if (tgt_addr != UT64_MAX) {
7185  RzAnalysisFunction *fcn = rz_analysis_get_function_at(core->analysis, tgt_addr);
7186  RzFlagItem *f = rz_flag_get_i(core->flags, tgt_addr);
7187  if (fcn) {
7188  result = rz_core_analysis_function_rename(core, tgt_addr, name);
7189  } else if (f) {
7190  result = rz_flag_rename(core->flags, f, name);
7191  } else {
7192  result = rz_flag_set(core->flags, name, tgt_addr, 1);
7193  }
7194  }
7195 
7196  return result;
7197 }
RZ_API bool rz_analysis_var_rename(RzAnalysisVar *var, const char *new_name, bool verbose)
Definition: var.c:348

References addr, rz_core_t::analysis, core_noretl::core, f, rz_core_t::flags, rz_core_t::io, rz_core_t::offset, op, rz_analysis_get_function_at(), rz_analysis_get_used_function_var(), rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, rz_analysis_var_rename(), rz_core_analysis_function_rename(), rz_flag_get_i(), rz_flag_rename(), rz_flag_set(), rz_io_read_at(), rz_return_val_if_fail, RZ_STR_ISNOTEMPTY, ut64(), and UT64_MAX.

Referenced by rz_analyse_name_handler().

◆ rz_core_analysis_resolve_jumps()

RZ_API void rz_core_analysis_resolve_jumps ( RZ_NONNULL RzCore core)

Resolves any unresolved jump.

Parameters
[in]coreThe RzCore to use

Definition at line 3242 of file canalysis.c.

3242  {
3243  RzListIter *iter;
3244  RzAnalysisXRef *xref;
3245  RzList *xrefs = rz_analysis_xrefs_list(core->analysis);
3246  bool analyze_recursively = rz_config_get_b(core->config, "analysis.calls");
3247 
3248  rz_list_foreach (xrefs, iter, xref) {
3249  if (xref->type != RZ_ANALYSIS_XREF_TYPE_CALL) {
3250  continue;
3251  }
3252 
3253  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, xref->from, -1);
3254  if (fcn) {
3255  continue;
3256  }
3257 
3258  rz_core_analysis_function_add(core, NULL, xref->from, analyze_recursively);
3259  }
3260 
3261  rz_list_free(xrefs);
3262 }
RZ_API RZ_OWN RzList * rz_analysis_xrefs_list(RzAnalysis *analysis)
Get list of all xrefs.
Definition: xrefs.c:206

References rz_analysis_ref_t::from, NULL, rz_analysis_get_fcn_in(), RZ_ANALYSIS_XREF_TYPE_CALL, rz_analysis_xrefs_list(), rz_config_get_b(), rz_core_analysis_function_add(), rz_list_free(), and rz_analysis_ref_t::type.

Referenced by rz_analyze_all_unresolved_jumps_handler().

◆ rz_core_analysis_search()

RZ_API int rz_core_analysis_search ( RzCore core,
ut64  from,
ut64  to,
ut64  ref,
int  mode 
)

Definition at line 3071 of file canalysis.c.

3071  {
3072  ut8 *buf = (ut8 *)malloc(core->blocksize);
3073  if (!buf) {
3074  return -1;
3075  }
3076  int ptrdepth = rz_config_get_i(core->config, "analysis.ptrdepth");
3077  int i, count = 0;
3079  ut64 at;
3080  char bckwrds, do_bckwrd_srch;
3081  int arch = -1;
3082  if (core->rasm->bits == 64) {
3083  // speedup search
3084  if (!strncmp(core->rasm->cur->name, "arm", 3)) {
3085  arch = RZ_ARCH_ARM64;
3086  }
3087  }
3088  // TODO: get current section range here
3089  // ???
3090  // XXX must read bytes correctly
3091  do_bckwrd_srch = bckwrds = core->search->bckwrds;
3092  if (core->file) {
3093  rz_io_use_fd(core->io, core->file->fd);
3094  }
3095  if (!ref) {
3096  eprintf("Null reference search is not supported\n");
3097  free(buf);
3098  return -1;
3099  }
3101  if (core->blocksize > OPSZ) {
3102  if (bckwrds) {
3103  if (from + core->blocksize > to) {
3104  at = from;
3105  do_bckwrd_srch = false;
3106  } else {
3107  at = to - core->blocksize;
3108  }
3109  } else {
3110  at = from;
3111  }
3112  while ((!bckwrds && at < to) || bckwrds) {
3113  eprintf("\r[0x%08" PFMT64x "-0x%08" PFMT64x "] ", at, to);
3114  if (rz_cons_is_breaked()) {
3115  break;
3116  }
3117  // TODO: this can be probably enhanced
3118  if (!rz_io_read_at(core->io, at, buf, core->blocksize)) {
3119  eprintf("Failed to read at 0x%08" PFMT64x "\n", at);
3120  break;
3121  }
3122  for (i = bckwrds ? (core->blocksize - OPSZ - 1) : 0;
3123  (!bckwrds && i < core->blocksize - OPSZ) ||
3124  (bckwrds && i > 0);
3125  bckwrds ? i-- : i++) {
3126  // TODO: honor analysis.align
3127  if (rz_cons_is_breaked()) {
3128  break;
3129  }
3130  switch (mode) {
3131  case 'c':
3132  (void)opiscall(core, &op, at + i, buf + i, core->blocksize - i, arch);
3133  if (op.size < 1) {
3134  op.size = 1;
3135  }
3136  break;
3137  case 'r':
3138  case 'w':
3139  case 'x': {
3140  rz_analysis_op(core->analysis, &op, at + i, buf + i, core->blocksize - i, RZ_ANALYSIS_OP_MASK_BASIC);
3141  int mask = mode == 'r' ? 1 : mode == 'w' ? 2
3142  : mode == 'x' ? 4
3143  : 0;
3144  if (op.direction == mask) {
3145  i += op.size;
3146  }
3148  continue;
3149  } break;
3150  default:
3151  if (rz_analysis_op(core->analysis, &op, at + i, buf + i, core->blocksize - i, RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
3153  continue;
3154  }
3155  }
3156  switch (op.type) {
3161  if (op.jump != UT64_MAX &&
3162  core_analysis_followptr(core, RZ_ANALYSIS_XREF_TYPE_CALL, at + i, op.jump, ref, true, 0)) {
3163  count++;
3164  }
3165  break;
3172  if (op.ptr != UT64_MAX &&
3173  core_analysis_followptr(core, RZ_ANALYSIS_XREF_TYPE_CODE, at + i, op.ptr, ref, true, 1)) {
3174  count++;
3175  }
3176  break;
3182  if (op.ptr != UT64_MAX &&
3183  core_analysis_followptr(core, RZ_ANALYSIS_XREF_TYPE_CALL, at + i, op.ptr, ref, true, 1)) {
3184  count++;
3185  }
3186  break;
3187  default: {
3188  if (rz_analysis_op(core->analysis, &op, at + i, buf + i, core->blocksize - i, RZ_ANALYSIS_OP_MASK_BASIC) < 1) {
3190  continue;
3191  }
3192  }
3193  if (op.ptr != UT64_MAX &&
3194  core_analysis_followptr(core, RZ_ANALYSIS_XREF_TYPE_DATA, at + i, op.ptr, ref, false, ptrdepth)) {
3195  count++;
3196  }
3197  break;
3198  }
3199  if (op.size < 1) {
3200  op.size = 1;
3201  }
3202  i += op.size - 1;
3204  }
3205  if (bckwrds) {
3206  if (!do_bckwrd_srch) {
3207  break;
3208  }
3209  if (at > from + core->blocksize - OPSZ) {
3210  at -= core->blocksize;
3211  } else {
3212  do_bckwrd_srch = false;
3213  at = from;
3214  }
3215  } else {
3216  at += core->blocksize - OPSZ;
3217  }
3218  }
3219  } else {
3220  eprintf("error: block size too small\n");
3221  }
3223  free(buf);
3225  return count;
3226 }
#define OPSZ
Definition: canalysis.c:3070
static bool opiscall(RzCore *core, RzAnalysisOp *aop, ut64 addr, const ut8 *buf, int len, int arch)
Definition: canalysis.c:3039
@ RZ_ANALYSIS_OP_TYPE_IJMP
Definition: rz_analysis.h:371
@ RZ_ANALYSIS_OP_TYPE_IRJMP
Definition: rz_analysis.h:372
RZ_API bool rz_io_use_fd(RzIO *io, int fd)
Definition: io_fd.c:118
RzSearch * search
Definition: rz_core.h:331
RzCoreFile * file
Definition: rz_core.h:314
char bckwrds
Definition: rz_search.h:74

References rz_core_t::analysis, arch, rz_search_t::bckwrds, rz_asm_t::bits, blocksize, rz_core_t::blocksize, rz_core_t::config, core_analysis_followptr(), count, rz_asm_t::cur, eprintf, rz_core_file_t::fd, rz_core_t::file, free(), from, i, rz_core_t::io, malloc(), mask, NULL, opiscall(), OPSZ, PFMT64x, rz_core_t::rasm, rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_ICALL, RZ_ANALYSIS_OP_TYPE_IJMP, RZ_ANALYSIS_OP_TYPE_IRCALL, RZ_ANALYSIS_OP_TYPE_IRJMP, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_MJMP, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_RJMP, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UCCALL, RZ_ANALYSIS_OP_TYPE_UCJMP, RZ_ANALYSIS_OP_TYPE_UJMP, RZ_ANALYSIS_XREF_TYPE_CALL, RZ_ANALYSIS_XREF_TYPE_CODE, RZ_ANALYSIS_XREF_TYPE_DATA, RZ_ARCH_ARM64, rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), RZ_EMPTY, rz_io_read_at(), rz_io_use_fd(), rz_core_t::search, to, ut64(), and UT64_MAX.

Referenced by rz_cmd_search().

◆ rz_core_analysis_search_xrefs()

RZ_API int rz_core_analysis_search_xrefs ( RZ_NONNULL RzCore core,
ut64  from,
ut64  to 
)

Searches for xrefs in the range of the paramters 'from' and 'to'.

Parameters
coreThe Rizin core.
fromStart of search interval.
toEnd of search interval.
Returns
int Number of found xrefs. -1 in case of failure.

Definition at line 3380 of file canalysis.c.

3380  {
3381  rz_return_val_if_fail(core, -1);
3382 
3383  bool cfg_debug = rz_config_get_b(core->config, "cfg.debug");
3384  bool decode_str = rz_config_get_i(core->config, "analysis.strings");
3385  ut64 at;
3386  int count = 0;
3387  const int bsz = 8096;
3388  RzAnalysisOp op = { 0 };
3389 
3390  if (from == to) {
3391  return -1;
3392  } else if (from > to) {
3393  RZ_LOG_ERROR("Invalid range (0x%" PFMT64x " >= 0x%" PFMT64x ")\n", from, to);
3394  return -1;
3395  } else if (core->blocksize <= OPSZ) {
3396  RZ_LOG_ERROR("block size is too small (blocksize <= %u)\n", OPSZ);
3397  return -1;
3398  }
3399 
3400  ut8 *buf = malloc(bsz);
3401  if (!buf) {
3402  RZ_LOG_ERROR("cannot allocate a block\n");
3403  return -1;
3404  }
3405 
3406  ut8 *block = malloc(bsz);
3407  if (!block) {
3408  RZ_LOG_ERROR("cannot allocate a temp block\n");
3409  free(buf);
3410  return -1;
3411  }
3412 
3414 
3415  at = from;
3416  st64 asm_sub_varmin = rz_config_get_i(core->config, "asm.sub.varmin");
3417  while (at < to && !rz_cons_is_breaked()) {
3418  int i = 0, ret = bsz;
3419  if (!rz_io_is_valid_offset(core->io, at, RZ_PERM_X)) {
3420  break;
3421  }
3422  (void)rz_io_read_at(core->io, at, buf, bsz);
3423  memset(block, -1, bsz);
3424  if (!memcmp(buf, block, bsz)) {
3425  at += ret;
3426  continue;
3427  }
3428  memset(block, 0, bsz);
3429  if (!memcmp(buf, block, bsz)) {
3430  at += ret;
3431  continue;
3432  }
3433  while (i < bsz && !rz_cons_is_breaked()) {
3434  ret = rz_analysis_op(core->analysis, &op, at + i, buf + i, bsz - i, RZ_ANALYSIS_OP_MASK_BASIC | RZ_ANALYSIS_OP_MASK_HINT);
3435  ret = ret > 0 ? ret : 1;
3436  i += ret;
3437  if (ret <= 0 || i > bsz) {
3438  break;
3439  }
3440  // find references
3441  if ((st64)op.val > asm_sub_varmin && op.val != UT64_MAX && op.val != UT32_MAX) {
3442  if (is_valid_xref(core, op.val, RZ_ANALYSIS_XREF_TYPE_DATA, cfg_debug)) {
3443  set_new_xref(core, op.addr, op.val, RZ_ANALYSIS_XREF_TYPE_DATA, decode_str);
3444  count++;
3445  }
3446  }
3447  for (ut8 i = 0; i < 6; ++i) {
3448  st64 aval = op.analysis_vals[i].imm;
3449  if (aval > asm_sub_varmin && aval != UT64_MAX && aval != UT32_MAX) {
3450  if (is_valid_xref(core, aval, RZ_ANALYSIS_XREF_TYPE_DATA, cfg_debug)) {
3451  set_new_xref(core, op.addr, aval, RZ_ANALYSIS_XREF_TYPE_DATA, decode_str);
3452  count++;
3453  }
3454  }
3455  }
3456  // find references
3457  if (op.ptr && op.ptr != UT64_MAX && op.ptr != UT32_MAX) {
3458  if (is_valid_xref(core, op.ptr, RZ_ANALYSIS_XREF_TYPE_DATA, cfg_debug)) {
3459  set_new_xref(core, op.addr, op.ptr, RZ_ANALYSIS_XREF_TYPE_DATA, decode_str);
3460  count++;
3461  }
3462  }
3463  // find references
3464  if (op.addr > 512 && op.disp > 512 && op.disp && op.disp != UT64_MAX) {
3465  if (is_valid_xref(core, op.disp, RZ_ANALYSIS_XREF_TYPE_DATA, cfg_debug)) {
3466  set_new_xref(core, op.addr, op.disp, RZ_ANALYSIS_XREF_TYPE_DATA, decode_str);
3467  count++;
3468  }
3469  }
3470  switch (op.type) {
3472  if (is_valid_xref(core, op.jump, RZ_ANALYSIS_XREF_TYPE_CODE, cfg_debug)) {
3473  set_new_xref(core, op.addr, op.jump, RZ_ANALYSIS_XREF_TYPE_CODE, decode_str);
3474  count++;
3475  }
3476  break;
3478  if (rz_config_get_b(core->config, "analysis.jmp.cref") &&
3479  is_valid_xref(core, op.jump, RZ_ANALYSIS_XREF_TYPE_CODE, cfg_debug)) {
3480  set_new_xref(core, op.addr, op.jump, RZ_ANALYSIS_XREF_TYPE_CODE, decode_str);
3481  count++;
3482  }
3483  break;
3486  if (is_valid_xref(core, op.jump, RZ_ANALYSIS_XREF_TYPE_CALL, cfg_debug)) {
3487  set_new_xref(core, op.addr, op.jump, RZ_ANALYSIS_XREF_TYPE_CALL, decode_str);
3488  count++;
3489  }
3490  break;
3497  count++;
3498  if (is_valid_xref(core, op.ptr, RZ_ANALYSIS_XREF_TYPE_CODE, cfg_debug)) {
3499  set_new_xref(core, op.addr, op.ptr, RZ_ANALYSIS_XREF_TYPE_CODE, decode_str);
3500  count++;
3501  }
3502  break;
3508  if (is_valid_xref(core, op.ptr, RZ_ANALYSIS_XREF_TYPE_CALL, cfg_debug)) {
3509  set_new_xref(core, op.addr, op.ptr, RZ_ANALYSIS_XREF_TYPE_CALL, decode_str);
3510  count++;
3511  }
3512  break;
3513  default:
3514  break;
3515  }
3517  }
3518  at += bsz;
3520  }
3522  free(buf);
3523  free(block);
3524  return count;
3525 }
static bool is_valid_xref(RzCore *core, ut64 xref_to, RzAnalysisXRefType type, int cfg_debug)
Validates a xref. Mainly checks if it points out of the memory map.
Definition: canalysis.c:3324
static void set_new_xref(RzCore *core, ut64 xref_from, ut64 xref_to, RzAnalysisXRefType type, bool decode_str)
Sets a new xref according to the given to and from addresses.
Definition: canalysis.c:3349

References count, free(), from, i, is_valid_xref(), malloc(), memset(), NULL, OPSZ, PFMT64x, rz_analysis_op(), rz_analysis_op_fini(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_OP_MASK_HINT, RZ_ANALYSIS_OP_TYPE_CALL, RZ_ANALYSIS_OP_TYPE_CCALL, RZ_ANALYSIS_OP_TYPE_CJMP, RZ_ANALYSIS_OP_TYPE_ICALL, RZ_ANALYSIS_OP_TYPE_IJMP, RZ_ANALYSIS_OP_TYPE_IRCALL, RZ_ANALYSIS_OP_TYPE_IRJMP, RZ_ANALYSIS_OP_TYPE_JMP, RZ_ANALYSIS_OP_TYPE_MJMP, RZ_ANALYSIS_OP_TYPE_RCALL, RZ_ANALYSIS_OP_TYPE_RJMP, RZ_ANALYSIS_OP_TYPE_UCALL, RZ_ANALYSIS_OP_TYPE_UCCALL, RZ_ANALYSIS_OP_TYPE_UCJMP, RZ_ANALYSIS_OP_TYPE_UJMP, RZ_ANALYSIS_XREF_TYPE_CALL, RZ_ANALYSIS_XREF_TYPE_CODE, RZ_ANALYSIS_XREF_TYPE_DATA, rz_config_get_b(), rz_config_get_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_io_is_valid_offset(), rz_io_read_at(), RZ_LOG_ERROR, RZ_PERM_X, rz_return_val_if_fail, set_new_xref(), st64, to, UT32_MAX, ut64(), and UT64_MAX.

Referenced by core_search_for_xrefs_in_boundaries().

◆ rz_core_analysis_sigdb_apply()

RZ_API bool rz_core_analysis_sigdb_apply ( RZ_NONNULL RzCore core,
RZ_NULLABLE int n_applied,
RZ_NULLABLE const char *  filter 
)

tries to apply the signatures in the flirt.sigdb.path

Parameters
coreThe RzCore instance
n_appliedReturns the number of successfully applied signatures
filterFilters the signatures found following the user input
Returns
fail when an error occurs otherwise true

Definition at line 6057 of file canalysis.c.

6057  {
6058  rz_return_val_if_fail(core, false);
6059  const char *bin = NULL;
6060  const char *arch = NULL;
6061  ut64 bits = 32;
6062  RzSigDBEntry *sig = NULL;
6063  RzList *sigdb = NULL;
6064  RzListIter *iter = NULL;
6065  RzBinObject *obj = NULL;
6066 
6067  int n_flags_new, n_flags_old;
6068  ut8 arch_id = RZ_FLIRT_SIG_ARCH_ANY;
6069 
6070  if (RZ_STR_ISEMPTY(filter)) {
6071  obj = core->bin ? rz_bin_cur_object(core->bin) : NULL;
6072  if ((!obj || !obj->plugin)) {
6073  RZ_LOG_INFO("Cannot apply signatures due unknown bin type\n");
6074  return false;
6075  } else if (!strcmp(obj->plugin->name, "elf64")) {
6076  bin = "elf";
6077  } else if (!strcmp(obj->plugin->name, "pe64")) {
6078  bin = "pe";
6079  } else {
6080  bin = obj->plugin->name;
6081  }
6082  }
6083 
6084  arch = rz_config_get(core->config, "asm.arch");
6085  bits = rz_config_get_i(core->config, "asm.bits");
6087  if (RZ_STR_ISEMPTY(filter) && arch_id >= RZ_FLIRT_SIG_ARCH_ANY) {
6088  RZ_LOG_INFO("Cannot apply signatures due unknown arch (%s)\n", arch);
6089  return false;
6090  }
6091 
6092  sigdb = rz_core_analysis_sigdb_list(core, false);
6093  if (!sigdb) {
6094  return false;
6095  }
6096 
6097  n_flags_old = rz_flag_count(core->flags, "flirt");
6098  rz_list_foreach (sigdb, iter, sig) {
6099  if (rz_cons_is_breaked()) {
6100  break;
6101  }
6102  if (RZ_STR_ISEMPTY(filter)) {
6103  // apply signatures automatically based on bin, arch and bits
6104  if (strcmp(bin, sig->bin_name) || strcmp(arch, sig->arch_name) || bits != sig->arch_bits) {
6105  continue;
6106  } else if (strstr(sig->base_name, "c++") &&
6107  obj->lang != RZ_BIN_LANGUAGE_CXX &&
6108  obj->lang != RZ_BIN_LANGUAGE_RUST) {
6109  // C++ libs can create many false positives, especially on C binaries.
6110  // So their usage is limited to C++ and RUST lang
6111  continue;
6112  }
6113  RZ_LOG_INFO("Applying %s signature file\n", sig->short_path);
6114  } else {
6115  // apply signatures based on filter value
6116  if (!strstr(sig->short_path, filter)) {
6117  continue;
6118  }
6119  rz_cons_printf("Applying %s/%s/%u/%s signature file\n",
6120  sig->bin_name, sig->arch_name, sig->arch_bits, sig->base_name);
6121  }
6122  rz_sign_flirt_apply(core->analysis, sig->file_path, arch_id);
6123  }
6124  rz_list_free(sigdb);
6125  n_flags_new = rz_flag_count(core->flags, "flirt");
6126 
6127  if (n_applied) {
6128  *n_applied = n_flags_new - n_flags_old;
6129  }
6130  return true;
6131 }
RZ_API RZ_OWN RzList * rz_core_analysis_sigdb_list(RZ_NONNULL RzCore *core, bool with_details)
Returns all the signatures found in the default path.
Definition: canalysis.c:5994
RZ_API ut8 rz_core_flirt_arch_from_name(RZ_NONNULL const char *arch)
Returns the FLIRT arch id from a given arch name Returns RZ_FLIRT_SIG_ARCH_ANY if name is not found.
Definition: csign.c:148
RZ_API int rz_flag_count(RzFlag *f, const char *glob)
Definition: flag.c:776
@ RZ_BIN_LANGUAGE_RUST
Definition: rz_bin.h:155
@ RZ_BIN_LANGUAGE_CXX
Definition: rz_bin.h:150
RZ_API bool rz_sign_flirt_apply(RZ_NONNULL RzAnalysis *analysis, RZ_NONNULL const char *flirt_file, ut8 expected_arch)
Parses the FLIRT file and applies the signatures.
Definition: flirt.c:1289
@ RZ_FLIRT_SIG_ARCH_ANY
Definition: rz_flirt.h:99
Definition: malloc.c:26
RzBinLanguage lang
Definition: rz_bin.h:290
Definition: rz_flirt.h:240
char * arch_name
RzAsmPlugin name.
Definition: rz_flirt.h:242
char * bin_name
RzBinPlugin name (elf64 and pe64 are named as elf and pe)
Definition: rz_flirt.h:241
const char * base_name
basename of file
Definition: rz_flirt.h:244
const char * short_path
Short path without sigdb path.
Definition: rz_flirt.h:245
char * file_path
full path to the signature file
Definition: rz_flirt.h:246
ut32 arch_bits
Architecture bits.
Definition: rz_flirt.h:243

References rz_core_t::analysis, arch, rz_signature_database_entry_t::arch_bits, rz_signature_database_entry_t::arch_name, rz_signature_database_entry_t::base_name, rz_core_t::bin, rz_signature_database_entry_t::bin_name, bits(), rz_core_t::config, core_noretl::core, rz_signature_database_entry_t::file_path, rz_core_t::flags, rz_bin_object_t::lang, rz_bin_plugin_t::name, NULL, rz_bin_object_t::plugin, rz_bin_cur_object(), RZ_BIN_LANGUAGE_CXX, RZ_BIN_LANGUAGE_RUST, rz_config_get(), rz_config_get_i(), rz_cons_is_breaked(), rz_cons_printf(), rz_core_analysis_sigdb_list(), rz_core_flirt_arch_from_name(), rz_flag_count(), RZ_FLIRT_SIG_ARCH_ANY, rz_list_free(), RZ_LOG_INFO, rz_return_val_if_fail, rz_sign_flirt_apply(), RZ_STR_ISEMPTY, rz_signature_database_entry_t::short_path, and ut64().

Referenced by rz_apply_signatures_from_sigdb_handler(), and rz_core_analysis_everything().

◆ rz_core_analysis_sigdb_list()

RZ_API RZ_OWN RzList* rz_core_analysis_sigdb_list ( RZ_NONNULL RzCore core,
bool  with_details 
)

Returns all the signatures found in the default path.

Scans for signature in the following paths:

  • home path + RZ_SIGDB
  • system install prefix path + RZ_SIGDB
  • flirt.sigdb.path user custom sigdb path
Parameters
coreThe RzCore to use.
[in]with_detailsThe reads the signature details and sets them in RzSigDBEntry
Returns
On success a RzList containing RzSigDBEntry entries, otherwise NULL.

Definition at line 5994 of file canalysis.c.

5994  {
5995  rz_return_val_if_fail(core, NULL);
5996 
5997  RzSigDb *sigs = rz_sign_sigdb_new();
5998  if (!sigs) {
5999  return NULL;
6000  }
6001 
6002  if (rz_config_get_b(core->config, "flirt.sigdb.load.home")) {
6003  char *home_sigdb = rz_path_home_prefix(RZ_SIGDB);
6004  analysis_sigdb_add(sigs, home_sigdb, with_details);
6005  free(home_sigdb);
6006  }
6007 
6008  if (rz_config_get_b(core->config, "flirt.sigdb.load.system")) {
6009  char *system_sigdb = rz_path_system(RZ_SIGDB);
6010  analysis_sigdb_add(sigs, system_sigdb, with_details);
6011  free(system_sigdb);
6012  }
6013 
6014  const char *user_sigdb = rz_config_get(core->config, "flirt.sigdb.path");
6015  analysis_sigdb_add(sigs, user_sigdb, with_details);
6016 
6017  return rz_sign_sigdb_list(sigs);
6018 }
static void analysis_sigdb_add(RzSigDb *sigs, const char *path, bool with_details)
Definition: canalysis.c:5971
RZ_API RZ_OWN RzSigDb * rz_sign_sigdb_new(void)
Create a new empty RzSigDb instance.
Definition: sigdb.c:260
RZ_API RZ_OWN RzList * rz_sign_sigdb_list(RZ_NONNULL const RzSigDb *db)
Return the signature database as a list of entries.
Definition: sigdb.c:294
#define RZ_SIGDB
Definition: rz_userconf.h:75

References analysis_sigdb_add(), rz_core_t::config, core_noretl::core, free(), NULL, rz_config_get(), rz_config_get_b(), rz_path_home_prefix(), rz_path_system(), rz_return_val_if_fail, RZ_SIGDB, rz_sign_sigdb_list(), and rz_sign_sigdb_new().

Referenced by rz_core_analysis_sigdb_apply(), and rz_core_analysis_sigdb_print().

◆ rz_core_analysis_sigdb_print()

RZ_API void rz_core_analysis_sigdb_print ( RZ_NONNULL RzCore core,
RZ_NONNULL RzTable table 
)

Adds all the signatures to a RzTable structure.

Parameters
[in]coreThe RzCore to use
[in]tableThe RzTable to use

Definition at line 6026 of file canalysis.c.

6026  {
6027  rz_return_if_fail(core && table);
6028 
6029  RzList *sigdb = rz_core_analysis_sigdb_list(core, true);
6030  if (!sigdb) {
6031  return;
6032  }
6033 
6034  rz_table_set_columnsf(table, "ssnsns", "bin", "arch", "bits", "name", "modules", "details");
6035 
6036  RzSigDBEntry *sig = NULL;
6037  RzListIter *iter = NULL;
6038  ut64 bits, nmods;
6039 
6040  rz_list_foreach (sigdb, iter, sig) {
6041  bits = sig->arch_bits;
6042  nmods = sig->n_modules;
6043  rz_table_add_rowf(table, "ssnsns", sig->bin_name, sig->arch_name, bits, sig->base_name, nmods, sig->details);
6044  }
6045 
6046  rz_list_free(sigdb);
6047 }
RZ_API void rz_table_set_columnsf(RzTable *t, const char *fmt,...)
Specify the types and names of the referenced table.
Definition: table.c:234
char * details
signature name / description (only for .sig files)
Definition: rz_flirt.h:247
ut32 n_modules
signature number of modules
Definition: rz_flirt.h:248

References rz_signature_database_entry_t::arch_bits, rz_signature_database_entry_t::arch_name, rz_signature_database_entry_t::base_name, rz_signature_database_entry_t::bin_name, bits(), core_noretl::core, rz_signature_database_entry_t::details, rz_signature_database_entry_t::n_modules, NULL, rz_core_analysis_sigdb_list(), rz_list_free(), rz_return_if_fail, rz_table_add_rowf(), rz_table_set_columnsf(), and ut64().

Referenced by rz_list_signatures_in_sigdb_handler().

◆ rz_core_analysis_stats_free()

RZ_API void rz_core_analysis_stats_free ( RzCoreAnalysisStats *  s)

Definition at line 3818 of file canalysis.c.

3818  {
3819  if (!s) {
3820  return;
3821  }
3822  rz_vector_fini(&s->blocks);
3823  free(s);
3824 }
RZ_API void rz_vector_fini(RzVector *vec)
Definition: vector.c:61

References free(), rz_vector_fini(), and s.

Referenced by analBars(), cmd_print_bars(), cmd_print_blocks(), and rz_core_analysis_get_stats().

◆ rz_core_analysis_stats_get_block_from()

RZ_API ut64 rz_core_analysis_stats_get_block_from ( RZ_NONNULL const RzCoreAnalysisStats *  s,
size_t  i 
)

Get the lowest address that the i-th block in s covers (inclusive)

Definition at line 3829 of file canalysis.c.

3829  {
3831  return s->from + s->step * i;
3832 }

References i, rz_return_val_if_fail, and s.

Referenced by cmd_print_blocks(), and rz_core_analysis_stats_get_block_to().

◆ rz_core_analysis_stats_get_block_to()

RZ_API ut64 rz_core_analysis_stats_get_block_to ( RZ_NONNULL const RzCoreAnalysisStats *  s,
size_t  i 
)

Get the highest address that the i-th block in s covers (inclusive)

Definition at line 3837 of file canalysis.c.

3837  {
3839  size_t count = rz_vector_len(&s->blocks);
3841  if (i + 1 == count) {
3842  return s->to;
3843  }
3844  return rz_core_analysis_stats_get_block_from(s, i + 1) - 1;
3845 }
RZ_API ut64 rz_core_analysis_stats_get_block_from(RZ_NONNULL const RzCoreAnalysisStats *s, size_t i)
Definition: canalysis.c:3829
static size_t rz_vector_len(const RzVector *vec)
Definition: rz_vector.h:82

References count, i, rz_core_analysis_stats_get_block_from(), rz_return_val_if_fail, rz_vector_len(), and s.

Referenced by cmd_print_blocks().

◆ rz_core_analysis_type_init()

RZ_API void rz_core_analysis_type_init ( RzCore core)

Definition at line 6610 of file canalysis.c.

6610  {
6611  rz_return_if_fail(core && core->analysis);
6612  int bits = core->rasm->bits;
6613  const char *analysis_arch = rz_config_get(core->config, "analysis.arch");
6614  const char *os = rz_config_get(core->config, "asm.os");
6615 
6616  char *types_dir = rz_path_system(RZ_SDB_TYPES);
6617  rz_type_db_init(core->analysis->typedb, types_dir, analysis_arch, bits, os);
6618  free(types_dir);
6619 }
RZ_API void rz_type_db_init(RzTypeDB *typedb, const char *types_dir, const char *arch, int bits, const char *os)
Initializes the types database for specified arch, bits, OS.
Definition: type.c:253

References rz_core_t::analysis, rz_asm_t::bits, bits(), rz_core_t::config, core_noretl::core, free(), rz_core_t::rasm, rz_config_get(), rz_path_system(), rz_return_if_fail, RZ_SDB_TYPES, rz_type_db_init(), and rz_analysis_t::typedb.

Referenced by cb_asmarch(), rz_core_bin_apply_config(), and rz_core_init().

◆ rz_core_analysis_types_propagation()

RZ_IPI bool rz_core_analysis_types_propagation ( RzCore core)

Definition at line 6325 of file canalysis.c.

6325  {
6326  RzListIter *it;
6327  RzAnalysisFunction *fcn;
6328  ut64 seek;
6329  if (rz_config_get_b(core->config, "cfg.debug")) {
6330  eprintf("TOFIX: aaft can't run in debugger mode.\n");
6331  return false;
6332  }
6333  RzConfigHold *hold = rz_config_hold_new(core->config);
6334  rz_config_hold_i(hold, "io.va", "io.pcache.write", NULL);
6335  bool io_cache = rz_config_get_b(core->config, "io.pcache.write");
6336  if (!io_cache) {
6337  // XXX. we shouldnt need this, but it breaks 'rizin -c aaa -w ls'
6338  rz_config_set_b(core->config, "io.pcache.write", true);
6339  }
6340  const bool delete_regs = !rz_flag_space_count(core->flags, RZ_FLAGS_FS_REGISTERS);
6341  seek = core->offset;
6342  rz_reg_arena_push(core->analysis->reg);
6346  ut8 *saved_arena = rz_reg_arena_peek(core->analysis->reg);
6347 
6348  // loop count of rz_core_analysis_type_match
6349  // TODO : figure out the reason to hold a `LOOP COUNT` in type_match
6350  // HtUU <addr->loop_count>
6351  HtUU *loop_table = ht_uu_new0();
6352 
6353  // Iterating Reverse so that we get function in top-bottom call order
6354  rz_list_foreach_prev(core->analysis->fcns, it, fcn) {
6355  int ret = rz_core_seek(core, fcn->addr, true);
6356  if (!ret) {
6357  continue;
6358  }
6359  rz_reg_arena_poke(core->analysis->reg, saved_arena);
6360  rz_analysis_esil_set_pc(core->analysis->esil, fcn->addr);
6361  rz_core_analysis_type_match(core, fcn, loop_table);
6362  if (rz_cons_is_breaked()) {
6363  break;
6364  }
6366  }
6367  if (delete_regs) {
6369  }
6370  rz_core_seek(core, seek, true);
6371  rz_reg_arena_pop(core->analysis->reg);
6373  rz_config_hold_restore(hold);
6374  rz_config_hold_free(hold);
6375  free(saved_arena);
6376  ht_uu_free(loop_table);
6377  return true;
6378 }
RZ_API void rz_core_analysis_type_match(RzCore *core, RzAnalysisFunction *fcn, HtUU *loop_table)
Definition: analysis_tp.c:816
RZ_API ut8 * rz_reg_arena_peek(RzReg *reg)
Definition: arena.c:280
RZ_API void rz_reg_arena_zero(RzReg *reg, RzRegisterType type)
Definition: arena.c:261
RZ_API void rz_reg_arena_poke(RzReg *reg, const ut8 *ret)
Definition: arena.c:293
RZ_IPI void rz_core_analysis_esil_init(RzCore *core)
Definition: cil.c:43
RZ_API void rz_core_analysis_esil_init_mem_del(RZ_NONNULL RzCore *core, RZ_NULLABLE const char *name, ut64 addr, ut32 size)
Remove ESIL VM stack.
Definition: cil.c:241
RZ_API void rz_core_debug_clear_register_flags(RzCore *core)
Definition: cmd_debug.c:1449
#define RZ_FLAGS_FS_REGISTERS
Definition: rz_core.h:61
@ RZ_REG_TYPE_ANY
Definition: rz_reg.h:35
static int seek(char *argv[])

References rz_analysis_function_t::addr, rz_core_t::analysis, rz_core_t::config, core_noretl::core, eprintf, rz_analysis_t::esil, rz_analysis_t::fcns, rz_core_t::flags, free(), NULL, rz_core_t::offset, rz_analysis_t::reg, rz_analysis_esil_set_pc(), rz_analysis_fcn_vars_add_types(), rz_config_get_b(), rz_config_hold_free(), rz_config_hold_i(), rz_config_hold_new(), rz_config_hold_restore(), rz_config_set_b(), rz_cons_is_breaked(), rz_core_analysis_esil_init(), rz_core_analysis_esil_init_mem(), rz_core_analysis_esil_init_mem_del(), rz_core_analysis_type_match(), rz_core_debug_clear_register_flags(), rz_core_seek(), RZ_FLAGS_FS_REGISTERS, rz_reg_arena_peek(), rz_reg_arena_poke(), rz_reg_arena_pop(), rz_reg_arena_push(), rz_reg_arena_zero(), RZ_REG_TYPE_ANY, seek(), UT32_MAX, ut64(), and UT64_MAX.

Referenced by rz_analyze_recursively_all_function_types_handler(), and rz_core_analysis_everything().

◆ rz_core_analysis_undefine()

RZ_API void rz_core_analysis_undefine ( RzCore core,
ut64  off 
)

Definition at line 4028 of file canalysis.c.

4028  {
4030  if (f) {
4031  if (!strncmp(f->name, "fcn.", 4)) {
4032  rz_flag_unset_name(core->flags, f->name);
4033  }
4035  }
4038 }
RZ_API ut64 rz_analysis_function_min_addr(RzAnalysisFunction *fcn)
Definition: function.c:323
RZ_API int rz_analysis_fcn_del(RzAnalysis *a, ut64 addr)
Definition: fcn.c:1675
RZ_API int rz_analysis_fcn_del_locs(RzAnalysis *analysis, ut64 addr)
Definition: fcn.c:1657
RZ_API bool rz_flag_unset_name(RzFlag *f, const char *name)
Definition: flag.c:670
RZ_API void rz_meta_del(RzAnalysis *a, RzAnalysisMetaType type, ut64 addr, ut64 size)
Definition: meta.c:187

References rz_core_t::analysis, f, rz_core_t::flags, off, rz_analysis_fcn_del(), rz_analysis_fcn_del_locs(), rz_analysis_function_linear_size(), rz_analysis_function_min_addr(), rz_analysis_get_fcn_in(), rz_flag_unset_name(), rz_meta_del(), and RZ_META_TYPE_ANY.

Referenced by rz_analysis_function_del_all_handler(), rz_analysis_function_del_handler(), rz_core_visual_analysis(), and rz_core_visual_define().

◆ rz_core_analysis_value_pointers()

RZ_IPI void rz_core_analysis_value_pointers ( RzCore core,
RzOutputMode  mode 
)

Definition at line 6502 of file canalysis.c.

6502  {
6503  ut64 o_align = rz_config_get_i(core->config, "search.align");
6504  const char *analysisin = rz_config_get(core->config, "analysis.in");
6505  char *tmp = strdup(analysisin);
6506  bool is_debug = rz_config_get_b(core->config, "cfg.debug");
6508  rz_config_set_i(core->config, "search.align", archAlign);
6509  rz_config_set(core->config, "analysis.in", "io.maps.x");
6510  rz_core_notify_done(core, "Finding xrefs in noncode section with analysis.in=io.maps");
6511 
6512  int vsize = 4; // 32bit dword
6513  if (core->rasm->bits == 64) {
6514  vsize = 8;
6515  }
6516 
6517  // body
6518  rz_core_notify_done(core, "Analyze value pointers (aav)");
6520  if (is_debug) {
6521  RzList *list = rz_core_get_boundaries_prot(core, 0, "dbg.map", "analysis");
6522  RzListIter *iter;
6523  RzIOMap *map;
6524  if (!list) {
6525  goto beach;
6526  }
6527  rz_list_foreach (list, iter, map) {
6528  if (rz_cons_is_breaked()) {
6529  break;
6530  }
6531  rz_core_notify_done(core, "from 0x%" PFMT64x " to 0x%" PFMT64x " (aav)", map->itv.addr, rz_itv_end(map->itv));
6532  (void)rz_core_search_value_in_range(core, map->itv,
6533  map->itv.addr, rz_itv_end(map->itv), vsize, _CbInRangeAav, (void *)&mode);
6534  }
6535  rz_list_free(list);
6536  } else {
6537  RzList *list = rz_core_get_boundaries_prot(core, 0, NULL, "analysis");
6538  if (!list) {
6539  goto beach;
6540  }
6541  RzListIter *iter, *iter2;
6542  RzIOMap *map, *map2;
6543  ut64 from = UT64_MAX;
6544  ut64 to = UT64_MAX;
6545  // find values pointing to non-executable regions
6546  rz_list_foreach (list, iter2, map2) {
6547  if (rz_cons_is_breaked()) {
6548  break;
6549  }
6550  // TODO: Reduce multiple hits for same addr
6551  from = rz_itv_begin(map2->itv);
6552  to = rz_itv_end(map2->itv);
6553  if ((to - from) > MAX_SCAN_SIZE) {
6554  rz_core_notify_done(core, "Skipping large region (from 0x%08" PFMT64x " to 0x%08" PFMT64x ")", from, to);
6555  continue;
6556  }
6557  rz_core_notify_done(core, "Value from 0x%08" PFMT64x " to 0x%08" PFMT64x " (aav)", from, to);
6558  rz_list_foreach (list, iter, map) {
6559  ut64 begin = map->itv.addr;
6560  ut64 end = rz_itv_end(map->itv);
6561  if (rz_cons_is_breaked()) {
6562  break;
6563  }
6564  if (end - begin > UT32_MAX) {
6565  rz_core_notify_done(core, "Skipping huge range");
6566  continue;
6567  }
6568  rz_core_notify_done(core, "0x%08" PFMT64x "-0x%08" PFMT64x " in 0x%" PFMT64x "-0x%" PFMT64x " (aav)", from, to, begin, end);
6569  (void)rz_core_search_value_in_range(core, map->itv, from, to, vsize, _CbInRangeAav, (void *)&mode);
6570  }
6571  }
6572  rz_list_free(list);
6573  }
6574 beach:
6576  // end
6577  rz_config_set(core->config, "analysis.in", tmp);
6578  free(tmp);
6579  rz_config_set_i(core->config, "search.align", o_align);
6580 }
static void _CbInRangeAav(RzCore *core, ut64 from, ut64 to, int vsize, void *user)
Definition: canalysis.c:6461
RZ_API int rz_core_search_value_in_range(RzCore *core, RzInterval search_itv, ut64 vmin, ut64 vmax, int vsize, inRangeCb cb, void *cb_user)
Definition: canalysis.c:4895
static ut64 rz_itv_begin(RzInterval itv)
Definition: rz_itv.h:34
RzInterval itv
Definition: rz_io.h:149

References _CbInRangeAav(), rz_core_t::analysis, rz_asm_t::bits, rz_core_t::config, core_noretl::core, test_evm::end, free(), from, rz_io_map_t::itv, list(), map(), MAX_SCAN_SIZE, NULL, PFMT64x, rz_core_t::rasm, rz_analysis_archinfo(), RZ_ANALYSIS_ARCHINFO_ALIGN, rz_config_get(), rz_config_get_b(), rz_config_get_i(), rz_config_set(), rz_config_set_i(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_core_get_boundaries_prot(), rz_core_notify_done(), rz_core_search_value_in_range(), rz_itv_begin(), rz_itv_end(), rz_list_free(), strdup(), autogen_x86imm::tmp, to, UT32_MAX, ut64(), and UT64_MAX.

Referenced by rz_analyze_value_to_maps_handler(), and rz_core_analysis_everything().

◆ rz_core_analysis_var_display()

RZ_IPI char* rz_core_analysis_var_display ( RzCore core,
RzAnalysisVar var,
bool  add_name 
)

Definition at line 6148 of file canalysis.c.

6148  {
6149  RzAnalysis *analysis = core->analysis;
6151  char *fmt = rz_type_as_format(analysis->typedb, var->type);
6152  RzRegItem *i;
6153  if (!fmt) {
6154  return rz_strbuf_drain(sb);
6155  }
6156  bool usePxr = rz_type_is_strictly_atomic(core->analysis->typedb, var->type) && rz_type_atomic_str_eq(core->analysis->typedb, var->type, "int");
6157  if (add_name) {
6158  rz_strbuf_appendf(sb, "%s %s = ", var->isarg ? "arg" : "var", var->name);
6159  }
6160  switch (var->kind) {
6162  i = rz_reg_index_get(analysis->reg, var->delta);
6163  if (i) {
6164  char *r;
6165  if (usePxr) {
6166  r = rz_core_cmd_strf(core, "pxr $w @r:%s", i->name);
6167  } else {
6168  r = rz_core_cmd_strf(core, "pf r (%s)", i->name);
6169  }
6170  rz_strbuf_append(sb, r);
6171  free(r);
6172  } else {
6173  RZ_LOG_DEBUG("register not found\n");
6174  }
6175  break;
6176  case RZ_ANALYSIS_VAR_KIND_BPV: {
6177  const st32 real_delta = var->delta + var->fcn->bp_off;
6178  const ut32 udelta = RZ_ABS(real_delta);
6179  const char sign = real_delta >= 0 ? '+' : '-';
6180  char *r;
6181  if (usePxr) {
6182  r = rz_core_cmd_strf(core, "pxr $w @ %s%c0x%x", analysis->reg->name[RZ_REG_NAME_BP], sign, udelta);
6183  } else {
6184  r = rz_core_cmd_strf(core, "pf %s @ %s%c0x%x", fmt, analysis->reg->name[RZ_REG_NAME_BP], sign, udelta);
6185  }
6186  rz_strbuf_append(sb, r);
6187  free(r);
6188  } break;
6189  case RZ_ANALYSIS_VAR_KIND_SPV: {
6190  ut32 udelta = RZ_ABS(var->delta + var->fcn->maxstack);
6191  char *r;
6192  if (usePxr) {
6193  r = rz_core_cmd_strf(core, "pxr $w @ %s+0x%x", analysis->reg->name[RZ_REG_NAME_SP], udelta);
6194  } else {
6195  r = rz_core_cmd_strf(core, "pf %s @ %s+0x%x", fmt, analysis->reg->name[RZ_REG_NAME_SP], udelta);
6196  }
6197  rz_strbuf_append(sb, r);
6198  free(r);
6199  break;
6200  }
6201  }
6202  free(fmt);
6203  return rz_strbuf_drain(sb);
6204 }
RZ_API RZ_OWN char * rz_type_as_format(const RzTypeDB *typedb, RZ_NONNULL RzType *type)
Represents the RzType as a pf format string.
Definition: format.c:3005
RZ_API bool rz_type_atomic_str_eq(const RzTypeDB *typedb, RZ_NONNULL const RzType *typ1, RZ_NONNULL const char *name)
Checks if two atomic types (RzType and RzBaseType) are equivalent.
Definition: helpers.c:208
RZ_API bool rz_type_is_strictly_atomic(const RzTypeDB *typedb, RZ_NONNULL const RzType *type)
Checks if the RzType is strictly atomic.
Definition: helpers.c:349
RZ_API RzRegItem * rz_reg_index_get(RzReg *reg, int idx)
Definition: reg.c:262
@ RZ_ANALYSIS_VAR_KIND_REG
Definition: rz_analysis.h:703
@ RZ_REG_NAME_BP
Definition: rz_reg.h:46
RZ_API bool rz_strbuf_appendf(RzStrBuf *sb, const char *fmt,...) RZ_PRINTF_CHECK(2
#define st32
Definition: rz_types_base.h:12
RzAnalysisFunction * fcn
Definition: rz_analysis.h:726
char * name[RZ_REG_NAME_LAST]
Definition: rz_reg.h:149

References rz_core_t::analysis, rz_analysis_function_t::bp_off, core_noretl::core, rz_analysis_var_t::delta, rz_analysis_var_t::fcn, free(), i, rz_analysis_var_t::isarg, rz_analysis_var_t::kind, rz_analysis_function_t::maxstack, rz_analysis_var_t::name, rz_reg_t::name, NULL, r, rz_analysis_t::reg, RZ_ABS, RZ_ANALYSIS_VAR_KIND_BPV, RZ_ANALYSIS_VAR_KIND_REG, RZ_ANALYSIS_VAR_KIND_SPV, rz_core_cmd_strf(), RZ_LOG_DEBUG, rz_reg_index_get(), RZ_REG_NAME_BP, RZ_REG_NAME_SP, rz_strbuf_append(), rz_strbuf_appendf(), rz_strbuf_drain(), rz_strbuf_new(), rz_type_as_format(), rz_type_atomic_str_eq(), rz_type_is_strictly_atomic(), sb, st32, rz_analysis_var_t::type, and rz_analysis_t::typedb.

Referenced by ds_show_functions(), ds_show_functions_argvar(), rz_analysis_function_vars_display_handler(), and rz_core_analysis_all_vars_display().

◆ rz_core_analysis_var_rename()

RZ_IPI bool rz_core_analysis_var_rename ( RzCore core,
const char *  name,
const char *  newname 
)

Definition at line 5728 of file canalysis.c.

5728  {
5730  if (!name) {
5732  if (var) {
5733  name = var->name;
5734  } else {
5735  eprintf("Cannot find var @ 0x%08" PFMT64x "\n", core->offset);
5737  return false;
5738  }
5739  }
5740  RzAnalysisFunction *fcn = rz_analysis_get_fcn_in(core->analysis, core->offset, -1);
5741  if (fcn) {
5743  if (v1) {
5744  rz_analysis_var_rename(v1, newname, true);
5745  } else {
5746  eprintf("Cant find var by name\n");
5747  return false;
5748  }
5749  } else {
5750  eprintf("afv: Cannot find function in 0x%08" PFMT64x "\n", core->offset);
5752  return false;
5753  }
5755  return true;
5756 }
@ v1
Definition: lanai.h:85

References rz_core_t::analysis, core_noretl::core, eprintf, rz_analysis_var_t::name, NULL, rz_core_t::offset, PFMT64x, rz_analysis_function_get_var_byname(), rz_analysis_get_fcn_in(), rz_analysis_get_used_function_var(), rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_BASIC, rz_analysis_var_rename(), rz_core_analysis_op(), and v1.

Referenced by rz_analysis_function_vars_rename_handler(), and variable_rename().

◆ rz_core_get_stacksz()

RZ_API int rz_core_get_stacksz ( RzCore core,
ut64  from,
ut64  to 
)

Definition at line 6582 of file canalysis.c.

6582  {
6583  int stack = 0, maxstack = 0;
6584  ut64 at = from;
6585 
6586  if (from >= to) {
6587  return 0;
6588  }
6589  const int mininstrsz = rz_analysis_archinfo(core->analysis, RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE);
6590  const int minopcode = RZ_MAX(1, mininstrsz);
6591  while (at < to) {
6593  if (!op || op->size <= 0) {
6594  at += minopcode;
6596  continue;
6597  }
6598  if ((op->stackop == RZ_ANALYSIS_STACK_INC) && RZ_ABS(op->stackptr) < 8096) {
6599  stack += op->stackptr;
6600  if (stack > maxstack) {
6601  maxstack = stack;
6602  }
6603  }
6604  at += op->size;
6606  }
6607  return maxstack;
6608 }
#define RZ_MAX(x, y)
Definition: z80asm.h:140
static struct stack stack[MAX_INCLUDE]
Definition: z80asm.c:92

References rz_core_t::analysis, core_noretl::core, from, RZ_ABS, rz_analysis_archinfo(), RZ_ANALYSIS_ARCHINFO_MIN_OP_SIZE, rz_analysis_op_free(), RZ_ANALYSIS_OP_MASK_BASIC, RZ_ANALYSIS_STACK_INC, rz_core_analysis_op(), RZ_MAX, stack, to, and ut64().

Referenced by rz_core_link_stroff().

◆ rz_core_print_bb_custom()

RZ_API int rz_core_print_bb_custom ( RzCore core,
RzAnalysisFunction fcn 
)

Definition at line 2118 of file canalysis.c.

2118  {
2119  RzAnalysisBlock *bb;
2120  RzListIter *iter;
2121  if (!fcn) {
2122  return false;
2123  }
2124 
2125  RzConfigHold *hc = rz_config_hold_new(core->config);
2126  rz_config_hold_i(hc, "scr.color", "scr.utf8", "asm.marks", "asm.offset", "asm.lines",
2127  "asm.cmt.right", "asm.cmt.col", "asm.lines.fcn", "asm.bytes", NULL);
2128  /*rz_config_set_i (core->config, "scr.color", 0);*/
2129  rz_config_set_i(core->config, "scr.utf8", 0);
2130  rz_config_set_i(core->config, "asm.marks", 0);
2131  rz_config_set_i(core->config, "asm.offset", 0);
2132  rz_config_set_i(core->config, "asm.lines", 0);
2133  rz_config_set_i(core->config, "asm.cmt.right", 0);
2134  rz_config_set_i(core->config, "asm.cmt.col", 0);
2135  rz_config_set_i(core->config, "asm.lines.fcn", 0);
2136  rz_config_set_i(core->config, "asm.bytes", 0);
2137 
2138  rz_list_foreach (fcn->bbs, iter, bb) {
2139  if (bb->addr == UT64_MAX) {
2140  continue;
2141  }
2142  char *title = get_title(bb->addr);
2143  char *body = rz_core_cmd_strf(core, "pdb @ 0x%08" PFMT64x, bb->addr);
2144  char *body_b64 = rz_base64_encode_dyn((const ut8 *)body, strlen(body));
2145  if (!title || !body || !body_b64) {
2146  free(body_b64);
2147  free(body);
2148  free(title);
2150  rz_config_hold_free(hc);
2151  return false;
2152  }
2153  body_b64 = rz_str_prepend(body_b64, "base64:");
2154  rz_cons_printf("agn %s %s\n", title, body_b64);
2155  free(body);
2156  free(body_b64);
2157  free(title);
2158  }
2159 
2161  rz_config_hold_free(hc);
2162 
2163  rz_list_foreach (fcn->bbs, iter, bb) {
2164  if (bb->addr == UT64_MAX) {
2165  continue;
2166  }
2167  char *u = get_title(bb->addr), *v = NULL;
2168  if (bb->jump != UT64_MAX) {
2169  v = get_title(bb->jump);
2170  rz_cons_printf("age %s %s\n", u, v);
2171  free(v);
2172  }
2173  if (bb->fail != UT64_MAX) {
2174  v = get_title(bb->fail);
2175  rz_cons_printf("age %s %s\n", u, v);
2176  free(v);
2177  }
2178  if (bb->switch_op) {
2179  RzListIter *it;
2180  RzAnalysisCaseOp *cop;
2181  rz_list_foreach (bb->switch_op->cases, it, cop) {
2182  v = get_title(cop->addr);
2183  rz_cons_printf("age %s %s\n", u, v);
2184  free(v);
2185  }
2186  }
2187  free(u);
2188  }
2189  return true;
2190 }

References rz_analysis_case_obj_t::addr, rz_analysis_bb_t::addr, rz_analysis_function_t::bbs, rz_analysis_switch_obj_t::cases, rz_core_t::config, rz_analysis_bb_t::fail, free(), get_title(), rz_analysis_bb_t::jump, NULL, PFMT64x, rz_base64_encode_dyn(), rz_config_hold_free(), rz_config_hold_i(), rz_config_hold_new(), rz_config_hold_restore(), rz_config_set_i(), rz_cons_printf(), rz_core_cmd_strf(), rz_str_prepend(), rz_analysis_bb_t::switch_op, UT64_MAX, and v.

Referenced by cmd_analysis_graph().

◆ rz_core_print_bb_gml()

RZ_API int rz_core_print_bb_gml ( RzCore core,
RzAnalysisFunction fcn 
)

Definition at line 2193 of file canalysis.c.

2193  {
2194  RzAnalysisBlock *bb;
2195  RzListIter *iter;
2196  if (!fcn) {
2197  return false;
2198  }
2199  int id = 0;
2200  HtUUOptions opt = { 0 };
2201  HtUU *ht = ht_uu_new_opt(&opt);
2202 
2203  rz_cons_printf("graph\n[\n"
2204  "hierarchic 1\n"
2205  "label \"\"\n"
2206  "directed 1\n");
2207 
2208  rz_list_foreach (fcn->bbs, iter, bb) {
2209  RzFlagItem *flag = rz_flag_get_i(core->flags, bb->addr);
2210  char *msg = flag ? strdup(flag->name) : rz_str_newf("0x%08" PFMT64x, bb->addr);
2211 #if USE_ID
2212  ht_uu_insert(ht, bb->addr, id);
2213  rz_cons_printf(" node [\n"
2214  " id %d\n"
2215  " label \"%s\"\n"
2216  " ]\n",
2217  id, msg);
2218  id++;
2219 #else
2220  rz_cons_printf(" node [\n"
2221  " id %" PFMT64d "\n"
2222  " label \"%s\"\n"
2223  " ]\n",
2224  bb->addr, msg);
2225 #endif
2226  free(msg);
2227  }
2228 
2229  rz_list_foreach (fcn->bbs, iter, bb) {
2230  if (bb->addr == UT64_MAX) {
2231  continue;
2232  }
2233 
2234 #if USE_ID
2235  if (bb->jump != UT64_MAX) {
2236  bool found;
2237  int i = ht_uu_find(ht, bb->addr, &found);
2238  if (found) {
2239  int i2 = ht_uu_find(ht, bb->jump, &found);
2240  if (found) {
2241  rz_cons_printf(" edge [\n"
2242  " source %d\n"
2243  " target %d\n"
2244  " ]\n",
2245  i, i2);
2246  }
2247  }
2248  }
2249  if (bb->fail != UT64_MAX) {
2250  bool found;
2251  int i = ht_uu_find(ht, bb->addr, &found);
2252  if (found) {
2253  int i2 = ht_uu_find(ht, bb->fail, &found);
2254  if (found) {
2255  rz_cons_printf(" edge [\n"
2256  " source %d\n"
2257  " target %d\n"
2258  " ]\n",
2259  i, i2);
2260  }
2261  }
2262  }
2263  if (bb->switch_op) {
2264  RzListIter *it;
2265  RzAnalysisCaseOp *cop;
2266  rz_list_foreach (bb->switch_op->cases, it, cop) {
2267  bool found;
2268  int i = ht_uu_find(ht, bb->addr, &found);
2269  if (found) {
2270  int i2 = ht_uu_find(ht, cop->addr, &found);
2271  if (found) {
2272  rz_cons_printf(" edge [\n"
2273  " source %d\n"
2274  " target %d\n"
2275  " ]\n",
2276  i, i2);
2277  }
2278  }
2279  }
2280  }
2281 #else
2282  if (bb->jump != UT64_MAX) {
2283  rz_cons_printf(" edge [\n"
2284  " source %" PFMT64d "\n"
2285  " target %" PFMT64d "\n"
2286  " ]\n",
2287  bb->addr, bb->jump);
2288  }
2289  if (bb->fail != UT64_MAX) {
2290  rz_cons_printf(" edge [\n"
2291  " source %" PFMT64d "\n"
2292  " target %" PFMT64d "\n"
2293  " ]\n",
2294  bb->addr, bb->fail);
2295  }
2296  if (bb->switch_op) {
2297  RzListIter *it;
2298  RzAnalysisCaseOp *cop;
2299  rz_list_foreach (bb->switch_op->cases, it, cop) {
2300  rz_cons_printf(" edge [\n"
2301  " source %" PFMT64d "\n"
2302  " target %" PFMT64d "\n"
2303  " ]\n",
2304  bb->addr, cop->addr);
2305  }
2306  }
2307 #endif
2308  }
2309  rz_cons_printf("]\n");
2310  ht_uu_free(ht);
2311  return true;
2312 }

References rz_analysis_case_obj_t::addr, rz_analysis_bb_t::addr, rz_analysis_function_t::bbs, rz_analysis_switch_obj_t::cases, rz_analysis_bb_t::fail, rz_core_t::flags, found, free(), i, i2, rz_analysis_bb_t::jump, msg, rz_flag_item_t::name, PFMT64d, PFMT64x, rz_cons_printf(), rz_flag_get_i(), rz_str_newf(), strdup(), rz_analysis_bb_t::switch_op, and UT64_MAX.

Referenced by cmd_analysis_graph().

◆ rz_core_recover_vars()

RZ_API void rz_core_recover_vars ( RzCore core,
RzAnalysisFunction fcn,
bool  argonly 
)

Definition at line 2779 of file canalysis.c.

2779  {
2780  rz_return_if_fail(core && core->analysis && fcn);
2781  if (core->analysis->opt.bb_max_size < 1) {
2782  return;
2783  }
2784  BlockRecurseCtx ctx = { 0, { { 0 } }, argonly, fcn, core };
2785  rz_pvector_init(&ctx.reg_set, free);
2786  int *reg_set = RZ_NEWS0(int, REG_SET_SIZE);
2787  rz_pvector_push(&ctx.reg_set, reg_set);
2788  int saved_stack = fcn->stack;
2789  RzAnalysisBlock *first_bb = rz_analysis_get_block_at(fcn->analysis, fcn->addr);
2790  if (first_bb) {
2791  rz_analysis_block_recurse_depth_first(first_bb, (RzAnalysisBlockCb)analysis_block_cb, (RzAnalysisBlockCb)analysis_block_on_exit, &ctx);
2792  }
2793  rz_pvector_fini(&ctx.reg_set);
2794  fcn->stack = saved_stack;
2795 }
RZ_API bool rz_analysis_block_recurse_depth_first(RzAnalysisBlock *block, RzAnalysisBlockCb cb, RZ_NULLABLE RzAnalysisBlockCb on_exit, void *user)
Definition: block.c:492
static bool analysis_block_on_exit(RzAnalysisBlock *bb, BlockRecurseCtx *ctx)
Definition: canalysis.c:2711
static bool analysis_block_cb(RzAnalysisBlock *bb, BlockRecurseCtx *ctx)
Definition: canalysis.c:2724
#define RZ_NEWS0(x, y)
Definition: rz_types.h:282
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
Definition: vector.c:298
RZ_API void rz_pvector_fini(RzPVector *vec)
Definition: vector.c:331
struct rz_analysis_t * analysis
Definition: rz_analysis.h:267

References rz_analysis_function_t::addr, rz_analysis_function_t::analysis, rz_core_t::analysis, analysis_block_cb(), analysis_block_on_exit(), rz_analysis_options_t::bb_max_size, free(), rz_analysis_t::opt, REG_SET_SIZE, rz_analysis_block_recurse_depth_first(), rz_analysis_get_block_at(), RZ_NEWS0, rz_pvector_fini(), rz_pvector_init(), rz_pvector_push(), rz_return_if_fail, and rz_analysis_function_t::stack.

Referenced by rz_analysis_function_vars_detect_handler(), rz_core_analysis_all(), rz_core_analysis_everything(), and rz_core_analysis_function_add().

◆ rz_core_search_value_in_range()

RZ_API int rz_core_search_value_in_range ( RzCore core,
RzInterval  search_itv,
ut64  vmin,
ut64  vmax,
int  vsize,
inRangeCb  cb,
void *  cb_user 
)

Definition at line 4895 of file canalysis.c.

4896  {
4897  int i, align = core->search->align, hitctr = 0;
4898  bool vinfun = rz_config_get_b(core->config, "analysis.vinfun");
4899  bool vinfunr = rz_config_get_b(core->config, "analysis.vinfunrange");
4900  bool analyze_strings = rz_config_get_b(core->config, "analysis.strings");
4901  ut8 buf[4096];
4902  ut64 v64, value = 0, size;
4903  ut64 from = search_itv.addr, to = rz_itv_end(search_itv);
4904  ut32 v32;
4905  ut16 v16;
4906  if (from >= to) {
4907  eprintf("Error: from must be lower than to\n");
4908  return -1;
4909  }
4910  bool maybeThumb = false;
4911  if (align && core->analysis->cur && core->analysis->cur->arch) {
4912  if (!strcmp(core->analysis->cur->arch, "arm") && core->analysis->bits != 64) {
4913  maybeThumb = true;
4914  }
4915  }
4916 
4917  if (vmin >= vmax) {
4918  eprintf("Error: vmin must be lower than vmax\n");
4919  return -1;
4920  }
4921  if (to == UT64_MAX) {
4922  eprintf("Error: Invalid destination boundary\n");
4923  return -1;
4924  }
4926 
4927  if (!rz_io_is_valid_offset(core->io, from, 0)) {
4928  return -1;
4929  }
4930  while (from < to) {
4931  size = RZ_MIN(to - from, sizeof(buf));
4932  memset(buf, 0xff, sizeof(buf)); // probably unnecessary
4933  if (rz_cons_is_breaked()) {
4934  goto beach;
4935  }
4936  bool res = rz_io_read_at_mapped(core->io, from, buf, size);
4937  if (!res || !memcmp(buf, "\xff\xff\xff\xff", 4) || !memcmp(buf, "\x00\x00\x00\x00", 4)) {
4938  if (!isValidAddress(core, from)) {
4939  ut64 next = rz_io_map_next_address(core->io, from);
4940  if (next == UT64_MAX) {
4941  from += sizeof(buf);
4942  } else {
4943  from += (next - from);
4944  }
4945  continue;
4946  }
4947  }
4948  for (i = 0; i <= (size - vsize); i++) {
4949  void *v = (buf + i);
4950  ut64 addr = from + i;
4951  if (rz_cons_is_breaked()) {
4952  goto beach;
4953  }
4954  if (align && (addr) % align) {
4955  continue;
4956  }
4957  int match = false;
4958  int left = size - i;
4959  if (vsize > left) {
4960  break;
4961  }
4962  switch (vsize) {
4963  case 1:
4964  value = *(ut8 *)v;
4965  match = (buf[i] >= vmin && buf[i] <= vmax);
4966  break;
4967  case 2:
4968  v16 = *(uut16 *)v;
4969  match = (v16 >= vmin && v16 <= vmax);
4970  value = v16;
4971  break;
4972  case 4:
4973  v32 = *(uut32 *)v;
4974  match = (v32 >= vmin && v32 <= vmax);
4975  value = v32;
4976  break;
4977  case 8:
4978  v64 = *(uut64 *)v;
4979  match = (v64 >= vmin && v64 <= vmax);
4980  value = v64;
4981  break;
4982  default: eprintf("Unknown vsize %d\n", vsize); return -1;
4983  }
4984  if (match && !vinfun) {
4985  if (vinfunr) {
4987  match = false;
4988  }
4989  } else {
4991  match = false;
4992  }
4993  }
4994  }
4995  if (match && value) {
4996  bool isValidMatch = true;
4997  if (align && (value % align)) {
4998  // ignored .. unless we are analyzing arm/thumb and lower bit is 1
4999  isValidMatch = false;
5000  if (maybeThumb && (value & 1)) {
5001  isValidMatch = true;
5002  }
5003  }
5004  if (isValidMatch) {
5005  cb(core, addr, value, vsize, cb_user);
5006  if (analyze_strings && stringAt(core, addr)) {
5007  add_string_ref(core, addr, value);
5008  }
5009  hitctr++;
5010  }
5011  }
5012  }
5013  if (size == to - from) {
5014  break;
5015  }
5016  from += size - vsize + 1;
5017  }
5018 beach:
5020  return hitctr;
5021 }
static bool stringAt(RzCore *core, ut64 addr)
Definition: canalysis.c:4885
static bool isValidAddress(RzCore *core, ut64 addr)
Definition: canalysis.c:4863
RZ_DEPRECATE RZ_API RzAnalysisFunction * rz_analysis_get_fcn_in_bounds(RzAnalysis *analysis, ut64 addr, int type)
Definition: fcn.c:1708
@ RZ_ANALYSIS_FCN_TYPE_NULL
Definition: rz_analysis.h:192
RZ_API ut64 rz_io_map_next_address(RzIO *io, ut64 addr)
Definition: io_map.c:371
RZ_API bool rz_io_read_at_mapped(RzIO *io, ut64 addr, ut8 *buf, int len)
Definition: io.c:318
Definition: engine.c:71
ut64 addr
Definition: rz_itv.h:15
static const char * cb[]
Definition: z80_tab.h:176

References add_string_ref(), addr, rz_interval_t::addr, rz_search_t::align, rz_core_t::analysis, rz_analysis_plugin_t::arch, rz_analysis_t::bits, cb, rz_core_t::config, rz_analysis_t::cur, eprintf, from, i, rz_core_t::io, isValidAddress(), memset(), NULL, RZ_ANALYSIS_FCN_TYPE_NULL, rz_analysis_get_fcn_in(), rz_analysis_get_fcn_in_bounds(), rz_config_get_b(), rz_cons_break_pop(), rz_cons_break_push(), rz_cons_is_breaked(), rz_io_is_valid_offset(), rz_io_map_next_address(), rz_io_read_at_mapped(), rz_itv_end(), RZ_MIN, rz_core_t::search, stringAt(), to, ut64(), UT64_MAX, v, and value.

Referenced by rz_cmd_search(), and rz_core_analysis_value_pointers().

◆ rz_platform_index_add_flags_comments()

RZ_API bool rz_platform_index_add_flags_comments ( RzCore core)

Adds the information from the Platform Profiles as flags and comments.

Parameters
corereference to RzCore

Definition at line 5263 of file canalysis.c.

5263  {
5266  return true;
5267 }
static bool add_arch_platform_flag_comment_cb(void *user, const ut64 addr, const void *v)
Definition: canalysis.c:5243
RZ_API void rz_flag_unset_all_in_space(RzFlag *f, const char *space_name)
Unset all flag items in the space with the given name.
Definition: flag.c:692
RzPlatformTargetIndex * platform_target
Definition: rz_analysis.h:623

References add_arch_platform_flag_comment_cb(), rz_core_t::analysis, rz_core_t::flags, rz_analysis_t::platform_target, rz_platform_target_index_t::platforms, rz_flag_unset_all_in_space(), and RZ_FLAGS_FS_PLATFORM_PORTS.

Referenced by rz_core_analysis_all().

◆ rz_platform_profile_add_flag_every_io()

RZ_API void rz_platform_profile_add_flag_every_io ( RzPlatformProfile profile,
RzFlag flags 
)

Adds the IO and extended IO registers from the CPU profiles as flags.

Parameters
profilereference to RzPlatformProfile
flagsreference to RzFlag

Definition at line 5236 of file canalysis.c.

5236  {
5239  ht_up_foreach(profile->registers_mmio, add_mmio_flag_cb, flags);
5240  ht_up_foreach(profile->registers_extended, add_mmio_extended_flag_cb, flags);
5241 }
static bool add_mmio_extended_flag_cb(void *user, const ut64 addr, const void *v)
Definition: canalysis.c:5222
static bool add_mmio_flag_cb(void *user, const ut64 addr, const void *v)
Definition: canalysis.c:5213

References add_mmio_extended_flag_cb(), add_mmio_flag_cb(), flags, rz_platform_profile_t::registers_extended, rz_platform_profile_t::registers_mmio, rz_flag_unset_all_in_space(), RZ_FLAGS_FS_MMIO_REGISTERS, and RZ_FLAGS_FS_MMIO_REGISTERS_EXTENDED.

Referenced by rz_core_analysis_all().

◆ RzAnalysisRef_cmp()

static int RzAnalysisRef_cmp ( const RzAnalysisXRef xref1,
const RzAnalysisXRef xref2 
)
static

Definition at line 2421 of file canalysis.c.

2421  {
2422  return xref1->to != xref2->to;
2423 }

References rz_analysis_ref_t::to.

Referenced by rz_core_analysis_callgraph().

◆ sdb_concat_by_path()

static void sdb_concat_by_path ( Sdb s,
const char *  path 
)
static

Definition at line 6621 of file canalysis.c.

6621  {
6622  Sdb *db = sdb_new(0, path, 0);
6623  sdb_merge(s, db);
6624  sdb_close(db);
6625  sdb_free(db);
6626 }
RZ_API Sdb * sdb_new(const char *path, const char *name, int lock)
Definition: sdb.c:47
RZ_API void sdb_close(Sdb *s)
Definition: sdb.c:416
RZ_API bool sdb_merge(Sdb *d, Sdb *s)
Definition: sdb.c:144
RZ_API bool sdb_free(Sdb *s)
Definition: sdb.c:206

References path, s, sdb_close(), sdb_free(), sdb_merge(), and sdb_new().

Referenced by rz_core_analysis_cc_init().

◆ set_fcn_name_from_flag()

static void set_fcn_name_from_flag ( RzAnalysisFunction fcn,
RzFlagItem f,
const char *  fcnpfx 
)
static

Definition at line 793 of file canalysis.c.

793  {
794  bool nameChanged = false;
795  if (f && f->name) {
796  if (!strncmp(fcn->name, "loc.", 4) || !strncmp(fcn->name, "fcn.", 4)) {
797  rz_analysis_function_rename(fcn, f->name);
798  nameChanged = true;
799  } else if (strncmp(f->name, "sect", 4)) {
800  rz_analysis_function_rename(fcn, f->name);
801  nameChanged = true;
802  }
803  }
804  if (!nameChanged) {
805  rz_analysis_function_rename(fcn, sdb_fmt("%s.%08" PFMT64x, fcnpfx, fcn->addr));
806  }
807 }

References rz_analysis_function_t::addr, f, rz_analysis_function_t::name, PFMT64x, rz_analysis_function_rename(), and sdb_fmt().

Referenced by __core_analysis_fcn().

◆ set_new_xref()

static void set_new_xref ( RzCore core,
ut64  xref_from,
ut64  xref_to,
RzAnalysisXRefType  type,
bool  decode_str 
)
static

Sets a new xref according to the given to and from addresses.

Parameters
coreThe rizin core.
xref_fromThe address where the xref is located.
xref_toThe target address of the xref.
typeThe xref type.
decode_strWhen set to true, checks if the RZ_ANALYSIS_XREF_TYPE_DATA address is a string and adds a flag.

Definition at line 3349 of file canalysis.c.

3349  {
3350  if (decode_str && type == RZ_ANALYSIS_XREF_TYPE_DATA) {
3351  int len = 0;
3352  char *str_string = is_string_at(core, xref_to, &len);
3353  if (str_string) {
3354  rz_name_filter(str_string, -1, true);
3355  char *str_flagname = rz_str_newf("str.%s", str_string);
3356  rz_flag_space_push(core->flags, RZ_FLAGS_FS_STRINGS);
3357  (void)rz_flag_set(core->flags, str_flagname, xref_to, 1);
3358  rz_flag_space_pop(core->flags);
3359  free(str_flagname);
3360  if (len > 0) {
3361  rz_meta_set(core->analysis, RZ_META_TYPE_STRING, xref_to, len, (const char *)str_string);
3362  }
3363  free(str_string);
3364  }
3365  }
3366  // Add to SDB
3367  if (xref_to) {
3368  rz_analysis_xrefs_set(core->analysis, xref_from, xref_to, type);
3369  }
3370 }

References rz_core_t::analysis, rz_core_t::flags, free(), is_string_at(), len, RZ_ANALYSIS_XREF_TYPE_DATA, rz_analysis_xrefs_set(), rz_flag_set(), RZ_FLAGS_FS_STRINGS, rz_meta_set(), RZ_META_TYPE_STRING, rz_name_filter(), rz_str_newf(), and type.

Referenced by rz_core_analysis_search_xrefs().

◆ stringAt()

static bool stringAt ( RzCore core,
ut64  addr 
)
static

Definition at line 4885 of file canalysis.c.

4885  {
4886  ut8 buf[32];
4887  rz_io_read_at(core->io, addr - 1, buf, sizeof(buf));
4888  // check if previous byte is a null byte, all strings, except pascal ones should be like this
4889  if (buf[0] != 0) {
4890  return false;
4891  }
4892  return is_string(buf + 1, 31, NULL);
4893 }

References addr, rz_core_t::io, is_string(), NULL, and rz_io_read_at().

Referenced by rz_core_search_value_in_range().

Variable Documentation

◆ esil_analysis_stop

bool esil_analysis_stop = false
static

Definition at line 4096 of file canalysis.c.

Referenced by cccb(), and rz_core_analysis_esil().

◆ esilbreak_last_data

ut64 esilbreak_last_data = UT64_MAX
static

Definition at line 4206 of file canalysis.c.

Referenced by esilbreak_mem_read(), and rz_core_analysis_esil().

◆ esilbreak_last_read

ut64 esilbreak_last_read = UT64_MAX
static

Definition at line 4205 of file canalysis.c.

Referenced by esilbreak_mem_read(), and rz_core_analysis_esil().

◆ ntarget

ut64 ntarget = UT64_MAX
static

Definition at line 4208 of file canalysis.c.

Referenced by esilbreak_mem_read().

◆ RzCoreAnalysisNameTypeStrs

const char* RzCoreAnalysisNameTypeStrs[]
static
Initial value:
= {
"var",
"function",
"flag",
"address",
}

Definition at line 7130 of file canalysis.c.

Referenced by rz_core_analysis_name_type_to_str().