1 /* radare - LGPL - Copyright 2010-2021 - nibble, alvaro, pancake */
2 
3 #include <r_anal.h>
4 #include <r_parse.h>
5 #include <r_util.h>
6 
7 #define READ_AHEAD 1
8 #define SDB_KEY_BB "bb.0x%"PFMT64x ".0x%"PFMT64x
9 // XXX must be configurable by the user
10 #define JMPTBLSZ 512
11 #define JMPTBL_LEA_SEARCH_SZ 64
12 #define JMPTBL_MAXFCNSIZE 4096
13 #define R_ANAL_MAX_INCSTACK 8096
14 #define BB_ALIGN 0x10
15 #define MAX_SCAN_SIZE 0x7ffffff
16 
17 /* speedup analysis by removing some function overlapping checks */
18 #define JAYRO_04 1
19 
20 // 16 KB is the maximum size for a basic block
21 #define MAX_FLG_NAME_SIZE 64
22 
23 #define FIX_JMP_FWD 0
24 #define D if (a->verbose)
25 
26 // 64KB max size
27 // 256KB max function size
28 #define MAX_FCN_SIZE (1024 * 256)
29 
30 #define DB a->sdb_fcns
31 #define EXISTS(x, ...) snprintf (key, sizeof (key) - 1, x, ## __VA_ARGS__), sdb_exists (DB, key)
32 #define SETKEY(x, ...) snprintf (key, sizeof (key) - 1, x, ## __VA_ARGS__);
33 
34 typedef struct fcn_tree_iter_t {
35 	int len;
36 	RBNode *cur;
37 	RBNode *path[R_RBTREE_MAX_HEIGHT];
38 } FcnTreeIter;
39 
r_anal_fcntype_tostring(int type)40 R_API const char *r_anal_fcntype_tostring(int type) {
41 	switch (type) {
42 	case R_ANAL_FCN_TYPE_NULL: return "null";
43 	case R_ANAL_FCN_TYPE_FCN: return "fcn";
44 	case R_ANAL_FCN_TYPE_LOC: return "loc";
45 	case R_ANAL_FCN_TYPE_SYM: return "sym";
46 	case R_ANAL_FCN_TYPE_IMP: return "imp";
47 	case R_ANAL_FCN_TYPE_INT: return "int"; // interrupt
48 	case R_ANAL_FCN_TYPE_ROOT: return "root";
49 	}
50 	return "unk";
51 }
52 
53 #if READ_AHEAD
54 static ut64 cache_addr = UT64_MAX;
55 
56 // TODO: move into io :?
read_ahead(RAnal * anal,ut64 addr,ut8 * buf,int len)57 static int read_ahead(RAnal *anal, ut64 addr, ut8 *buf, int len) {
58 	static ut8 cache[1024];
59 	const int cache_len = sizeof (cache);
60 
61 	if (len < 1) {
62 		return 0;
63 	}
64 	if (len > cache_len) {
65 		int a = anal->iob.read_at (anal->iob.io, addr, buf, len); // double read
66 		memcpy (cache, buf, cache_len);
67 		cache_addr = addr;
68 		return a;
69 	}
70 
71 	ut64 addr_end = UT64_ADD_OVFCHK (addr, len)? UT64_MAX: addr + len;
72 	ut64 cache_addr_end = UT64_ADD_OVFCHK (cache_addr, cache_len)? UT64_MAX: cache_addr + cache_len;
73 	bool isCached = ((addr != UT64_MAX) && (addr >= cache_addr) && (addr_end < cache_addr_end));
74 	if (isCached) {
75 		memcpy (buf, cache + (addr - cache_addr), len);
76 	} else {
77 		anal->iob.read_at (anal->iob.io, addr, cache, sizeof (cache));
78 		memcpy (buf, cache, len);
79 		cache_addr = addr;
80 	}
81 	return len;
82 }
83 #else
read_ahead(RAnal * anal,ut64 addr,ut8 * buf,int len)84 static int read_ahead(RAnal *anal, ut64 addr, ut8 *buf, int len) {
85 	return anal->iob.read_at (anal->iob.io, addr, buf, len);
86 }
87 #endif
88 
r_anal_fcn_invalidate_read_ahead_cache(void)89 R_API void r_anal_fcn_invalidate_read_ahead_cache(void) {
90 #if READ_AHEAD
91 	cache_addr = UT64_MAX;
92 #endif
93 }
94 
cmpaddr(const void * _a,const void * _b)95 static int cmpaddr(const void *_a, const void *_b) {
96 	const RAnalBlock *a = _a, *b = _b;
97 	return a->addr > b->addr ? 1 : (a->addr < b->addr ? -1 : 0);
98 }
99 
r_anal_function_resize(RAnalFunction * fcn,int newsize)100 R_API int r_anal_function_resize(RAnalFunction *fcn, int newsize) {
101 	RAnal *anal = fcn->anal;
102 	RAnalBlock *bb;
103 	RListIter *iter, *iter2;
104 
105 	r_return_val_if_fail (fcn, false);
106 
107 	if (newsize < 1) {
108 		return false;
109 	}
110 
111 	// XXX this is something we should probably do for all the archs
112 	bool is_arm = anal->cur->arch && !strncmp (anal->cur->arch, "arm", 3);
113 	if (is_arm) {
114 		return true;
115 	}
116 
117 	ut64 eof = fcn->addr + newsize;
118 	r_list_foreach_safe (fcn->bbs, iter, iter2, bb) {
119 		if (bb->addr >= eof) {
120 			r_anal_function_remove_block (fcn, bb);
121 			continue;
122 		}
123 		if (bb->addr + bb->size >= eof) {
124 			r_anal_block_set_size (bb, eof - bb->addr);
125 			r_anal_block_update_hash (bb);
126 		}
127 		if (bb->jump != UT64_MAX && bb->jump >= eof) {
128 			bb->jump = UT64_MAX;
129 		}
130 		if (bb->fail != UT64_MAX && bb->fail >= eof) {
131 			bb->fail = UT64_MAX;
132 		}
133 	}
134 	return true;
135 }
136 
137 // Create a new 0-sized basic block inside the function
fcn_append_basic_block(RAnal * anal,RAnalFunction * fcn,ut64 addr)138 static RAnalBlock *fcn_append_basic_block(RAnal *anal, RAnalFunction *fcn, ut64 addr) {
139 	RAnalBlock *bb = r_anal_create_block (anal, addr, 0);
140 	if (!bb) {
141 		return NULL;
142 	}
143 	r_anal_function_add_block (fcn, bb);
144 	bb->stackptr = fcn->stack;
145 	bb->parent_stackptr = fcn->stack;
146 	return bb;
147 }
148 
149 #define gotoBeach(x) ret = x; goto beach;
150 
isInvalidMemory(RAnal * anal,const ut8 * buf,int len)151 static bool isInvalidMemory(RAnal *anal, const ut8 *buf, int len) {
152 	if (anal->opt.nonull > 0) {
153 		int i;
154 		const int count = R_MIN (len, anal->opt.nonull);
155 		for (i = 0; i < count; i++) {
156 			if (buf[i]) {
157 				break;
158 			}
159 		}
160 		if (i == count) {
161 			return true;
162 		}
163 	}
164 	return !memcmp (buf, "\xff\xff\xff\xff", R_MIN (len, 4));
165 }
166 
isSymbolNextInstruction(RAnal * anal,RAnalOp * op)167 static bool isSymbolNextInstruction(RAnal *anal, RAnalOp *op) {
168 	r_return_val_if_fail (anal && op && anal->flb.get_at, false);
169 
170 	RFlagItem *fi = anal->flb.get_at (anal->flb.f, op->addr + op->size, false);
171 	return (fi && fi->name && (strstr (fi->name, "imp.") || strstr (fi->name, "sym.")
172 			|| strstr (fi->name, "entry") || strstr (fi->name, "main")));
173 }
174 
is_delta_pointer_table(RAnal * anal,RAnalFunction * fcn,ut64 addr,ut64 lea_ptr,ut64 * jmptbl_addr,ut64 * casetbl_addr,RAnalOp * jmp_aop)175 static bool is_delta_pointer_table(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 lea_ptr, ut64 *jmptbl_addr, ut64 *casetbl_addr, RAnalOp *jmp_aop) {
176 	int i;
177 	ut64 dst;
178 	st32 jmptbl[64] = {0};
179 	/* check if current instruction is followed by an ujmp */
180 	ut8 buf[JMPTBL_LEA_SEARCH_SZ];
181 	RAnalOp *aop = jmp_aop;
182 	RAnalOp omov_aop = {0};
183 	RAnalOp mov_aop = {0};
184 	RAnalOp add_aop = {0};
185 	RRegItem *reg_src = NULL, *o_reg_dst = NULL;
186 	RAnalValue cur_scr, cur_dst = { 0 };
187 	read_ahead (anal, addr, (ut8*)buf, sizeof (buf));
188 	bool isValid = false;
189 	for (i = 0; i + 8 < JMPTBL_LEA_SEARCH_SZ; i++) {
190 		ut64 at = addr + i;
191 		int left = JMPTBL_LEA_SEARCH_SZ - i;
192 		int len = r_anal_op (anal, aop, at, buf + i, left, R_ANAL_OP_MASK_BASIC | R_ANAL_OP_MASK_HINT | R_ANAL_OP_MASK_VAL);
193 		if (len < 1) {
194 			len = 1;
195 		}
196 		if (aop->type == R_ANAL_OP_TYPE_UJMP || aop->type == R_ANAL_OP_TYPE_RJMP) {
197 			isValid = true;
198 			break;
199 		}
200 		if (aop->type == R_ANAL_OP_TYPE_MOV) {
201 			omov_aop = mov_aop;
202 			mov_aop = *aop;
203 			o_reg_dst = cur_dst.reg;
204 			if (mov_aop.dst) {
205 				cur_dst = *mov_aop.dst;
206 			}
207 			if (mov_aop.src[0]) {
208 				cur_scr = *mov_aop.src[0];
209 				reg_src = cur_scr.regdelta;
210 			}
211 		}
212 		if (aop->type == R_ANAL_OP_TYPE_ADD) {
213 			add_aop = *aop;
214 		}
215 		r_anal_op_fini (aop);
216 		i += len - 1;
217 	}
218 	if (!isValid) {
219 		return false;
220 	}
221 
222 	// check if we have a msvc 19xx style jump table using rva table entries
223 	// lea reg1, [base_addr]
224 	// mov reg2, dword [reg1 + tbl_off*4 + tbl_loc_off]
225 	// add reg2, reg1
226 	// jmp reg2
227 	if (mov_aop.type && add_aop.type && mov_aop.addr < add_aop.addr && add_aop.addr < jmp_aop->addr
228 	    && mov_aop.disp && mov_aop.disp != UT64_MAX) {
229 		// disp in this case should be tbl_loc_off
230 		*jmptbl_addr += mov_aop.disp;
231 		if (o_reg_dst && reg_src && o_reg_dst->offset == reg_src->offset && omov_aop.disp != UT64_MAX) {
232 			// Special case for indirection
233 			// lea reg1, [base_addr]
234 			// movzx reg2, byte [reg1 + tbl_off + casetbl_loc_off]
235 			// mov reg3, dword [reg1 + reg2*4 + tbl_loc_off]
236 			// add reg3, reg1
237 			// jmp reg3
238 			*casetbl_addr += omov_aop.disp;
239 		}
240 	}
241 #if 0
242 	// required for the last jmptbl.. but seems to work without it and breaks other tests
243 	if (mov_aop.type && mov_aop.ptr) {
244 		*jmptbl_addr += mov_aop.ptr;
245 		// absjmptbl
246 		lea_ptr = mov_aop.ptr;
247 	}
248 #endif
249 	/* check if jump table contains valid deltas */
250 	read_ahead (anal, *jmptbl_addr, (ut8 *)&jmptbl, 64);
251 	for (i = 0; i < 3; i++) {
252 		dst = lea_ptr + (st32)r_read_le32 (jmptbl);
253 		if (!anal->iob.is_valid_offset (anal->iob.io, dst, 0)) {
254 			return false;
255 		}
256 		if (dst > fcn->addr + JMPTBL_MAXFCNSIZE) {
257 			return false;
258 		}
259 		if (anal->opt.jmpabove && dst < (fcn->addr < JMPTBL_MAXFCNSIZE ? 0 : fcn->addr - JMPTBL_MAXFCNSIZE)) {
260 			return false;
261 		}
262 	}
263 	return true;
264 }
265 
try_get_cmpval_from_parents(RAnal * anal,RAnalFunction * fcn,RAnalBlock * my_bb,const char * cmp_reg)266 static ut64 try_get_cmpval_from_parents(RAnal * anal, RAnalFunction *fcn, RAnalBlock *my_bb, const char * cmp_reg) {
267 	r_return_val_if_fail (fcn && fcn->bbs && cmp_reg, UT64_MAX);
268 	RListIter *iter;
269 	RAnalBlock *tmp_bb;
270 	r_list_foreach (fcn->bbs, iter, tmp_bb) {
271 		if (tmp_bb->jump == my_bb->addr || tmp_bb->fail == my_bb->addr) {
272 			if (tmp_bb->cmpreg == cmp_reg) {
273 				if (tmp_bb->cond) {
274 					if (tmp_bb->cond->type == R_ANAL_COND_HI || tmp_bb->cond->type == R_ANAL_COND_GT) {
275 						return tmp_bb->cmpval + 1;
276 					}
277 				}
278 				return tmp_bb->cmpval;
279 			}
280 		}
281 	}
282 	return UT64_MAX;
283 }
284 
regs_exist(RAnalValue * src,RAnalValue * dst)285 static bool regs_exist(RAnalValue *src, RAnalValue *dst) {
286 	r_return_val_if_fail (src && dst, false);
287 	return src->reg && dst->reg && src->reg->name && dst->reg->name;
288 }
289 
290 // 0 if not skipped; 1 if skipped; 2 if skipped before
skip_hp(RAnal * anal,RAnalFunction * fcn,RAnalOp * op,RAnalBlock * bb,ut64 addr,int oplen,int un_idx,int * idx)291 static int skip_hp(RAnal *anal, RAnalFunction *fcn, RAnalOp *op, RAnalBlock *bb, ut64 addr, int oplen, int un_idx, int *idx) {
292 	// this step is required in order to prevent infinite recursion in some cases
293 	if ((addr + un_idx - oplen) == fcn->addr) {
294 		// use addr instead of op->addr to mark repeat
295 		if (!anal->flb.exist_at (anal->flb.f, "skip", 4, addr)) {
296 			char *name = r_str_newf ("skip.%"PFMT64x,  addr);
297 			anal->flb.set (anal->flb.f, name, addr, oplen);
298 			free (name);
299 			fcn->addr += oplen;
300 			r_anal_block_relocate (bb, bb->addr + oplen, bb->size - oplen);
301 			*idx = un_idx;
302 			return 1;
303 		}
304 		return 2;
305 	}
306 	return 0;
307 }
308 
purity_checked(HtUP * ht,RAnalFunction * fcn)309 static bool purity_checked(HtUP *ht, RAnalFunction *fcn) {
310 	bool checked;
311 	ht_up_find (ht, fcn->addr, &checked);
312 	return checked;
313 }
314 
315 /*
316  * Checks whether a given function is pure and sets its 'is_pure' field.
317  * This function marks fcn 'not pure' if fcn, or any function called by fcn, accesses data
318  * from outside, even if it only READS it.
319  * Probably worth changing it in the future, so that it marks fcn 'impure' only when it
320  * (or any function called by fcn) MODIFIES external data.
321  */
check_purity(HtUP * ht,RAnalFunction * fcn)322 static void check_purity(HtUP *ht, RAnalFunction *fcn) {
323 	RListIter *iter;
324 	RList *refs = r_anal_function_get_refs (fcn);
325 	RAnalRef *ref;
326 	ht_up_insert (ht, fcn->addr, NULL);
327 	fcn->is_pure = true;
328 	r_list_foreach (refs, iter, ref) {
329 		if (ref->type == R_ANAL_REF_TYPE_CALL || ref->type == R_ANAL_REF_TYPE_CODE) {
330 			RAnalFunction *called_fcn = r_anal_get_fcn_in (fcn->anal, ref->addr, 0);
331 			if (!called_fcn) {
332 				continue;
333 			}
334 			if (!purity_checked (ht, called_fcn)) {
335 				check_purity (ht, called_fcn);
336 			}
337 			if (!called_fcn->is_pure) {
338 				fcn->is_pure = false;
339 				break;
340 			}
341 		}
342 		if (ref->type == R_ANAL_REF_TYPE_DATA) {
343 			fcn->is_pure = false;
344 			break;
345 		}
346 	}
347 	r_list_free (refs);
348 }
349 
350 typedef struct {
351 	ut64 op_addr;
352 	ut64 leaddr;
353 } leaddr_pair;
354 
bbget(RAnal * anal,ut64 addr,bool jumpmid)355 static RAnalBlock *bbget(RAnal *anal, ut64 addr, bool jumpmid) {
356 	RList *intersecting = r_anal_get_blocks_in (anal, addr);
357 	RListIter *iter;
358 	RAnalBlock *bb;
359 
360 	RAnalBlock *ret = NULL;
361 	r_list_foreach (intersecting, iter, bb) {
362 		ut64 eaddr = bb->addr + bb->size;
363 		if (((bb->addr >= eaddr && addr == bb->addr)
364 		     || r_anal_block_contains (bb, addr))
365 		    && (!jumpmid || r_anal_block_op_starts_at (bb, addr))) {
366 			if (anal->opt.delay) {
367 				ut8 *buf = malloc (bb->size);
368 				if (anal->iob.read_at (anal->iob.io, bb->addr, buf, bb->size)) {
369 					const int last_instr_idx = bb->ninstr - 1;
370 					bool in_delay_slot = false;
371 					int i;
372 					for (i = last_instr_idx; i >= 0; i--) {
373 						const ut64 off = r_anal_bb_offset_inst (bb, i);
374 						const ut64 at = bb->addr + off;
375 						if (addr <= at || off >= bb->size) {
376 							continue;
377 						}
378 						RAnalOp op;
379 						int size = r_anal_op (anal, &op, at, buf + off, bb->size - off, R_ANAL_OP_MASK_BASIC);
380 						if (size > 0 && op.delay) {
381 							if (op.delay >= last_instr_idx - i) {
382 								in_delay_slot = true;
383 							}
384 							r_anal_op_fini (&op);
385 							break;
386 						}
387 						r_anal_op_fini (&op);
388 					}
389 					if (in_delay_slot) {
390 						free (buf);
391 						continue;
392 					}
393 				}
394 				free (buf);
395 			}
396 			ret = bb;
397 			break;
398 		}
399 	}
400 	r_list_free (intersecting);
401 	return ret;
402 }
403 
404 typedef struct {
405 	RAnalFunction *fcn;
406 	const int stack_diff;
407 } BlockTakeoverCtx;
408 
fcn_takeover_block_recursive_followthrough_cb(RAnalBlock * block,void * user)409 static bool fcn_takeover_block_recursive_followthrough_cb(RAnalBlock *block, void *user) {
410 	BlockTakeoverCtx *ctx = user;
411 	RAnalFunction *our_fcn = ctx->fcn;
412 	r_anal_block_ref (block);
413 	while (!r_list_empty (block->fcns)) {
414 		RAnalFunction *other_fcn = r_list_first (block->fcns);
415 		if (other_fcn->addr == block->addr) {
416 			return false;
417 		}
418 		// Steal vars from this block
419 		size_t i;
420 		for (i = 0; i < block->ninstr; i++) {
421 			const ut64 addr = r_anal_bb_opaddr_i (block, i);
422 			RPVector *vars_used = r_anal_function_get_vars_used_at (other_fcn, addr);
423 			if (!vars_used) {
424 				continue;
425 			}
426 			// vars_used will get modified if r_anal_var_remove_access_at gets called
427 			RPVector *cloned_vars_used = (RPVector *)r_vector_clone ((RVector *)vars_used);
428 			void **it;
429 			r_pvector_foreach (cloned_vars_used, it) {
430 				RAnalVar *other_var = *it;
431 				const int actual_delta = other_var->kind == R_ANAL_VAR_KIND_SPV
432 					? other_var->delta + ctx->stack_diff
433 					: other_var->delta + (other_fcn->bp_off - our_fcn->bp_off);
434 				RAnalVar *our_var = r_anal_function_get_var (our_fcn, other_var->kind, actual_delta);
435 				if (!our_var) {
436 					our_var = r_anal_function_set_var (our_fcn, actual_delta, other_var->kind, other_var->type, 0, other_var->isarg, other_var->name);
437 				}
438 				if (our_var) {
439 					RAnalVarAccess *acc = r_anal_var_get_access_at (other_var, addr);
440 					r_anal_var_set_access (our_var, acc->reg, addr, acc->type, acc->stackptr);
441 				}
442 				r_anal_var_remove_access_at (other_var, addr);
443 				if (r_vector_empty (&other_var->accesses)) {
444 					r_anal_function_delete_var (other_fcn, other_var);
445 				}
446 			}
447 			r_pvector_free (cloned_vars_used);
448 		}
449 
450 		// TODO: remove block->ninstr from other_fcn considering delay slots
451 		r_anal_function_remove_block (other_fcn, block);
452 	}
453 	block->stackptr -= ctx->stack_diff;
454 	block->parent_stackptr -= ctx->stack_diff;
455 	r_anal_function_add_block (our_fcn, block);
456 	// TODO: add block->ninstr from our_fcn considering delay slots
457 	r_anal_block_unref (block);
458 	return true;
459 }
460 
461 // Remove block and all of its recursive successors from all its functions and add them only to fcn
fcn_takeover_block_recursive(RAnalFunction * fcn,RAnalBlock * start_block)462 static void fcn_takeover_block_recursive(RAnalFunction *fcn, RAnalBlock *start_block) {
463 	BlockTakeoverCtx ctx = { fcn, start_block->parent_stackptr - fcn->stack};
464 	r_anal_block_recurse_followthrough (start_block, fcn_takeover_block_recursive_followthrough_cb, &ctx);
465 }
466 
retpoline_reg(RAnal * anal,ut64 addr)467 static const char *retpoline_reg(RAnal *anal, ut64 addr) {
468 	RFlagItem *flag = anal->flag_get (anal->flb.f, addr);
469 	if (flag) {
470 		const char *token = "x86_indirect_thunk_";
471 		const char *thunk = strstr (flag->name, token);
472 		if (thunk) {
473 			return thunk + strlen (token);
474 		}
475 	}
476 #if 0
477 // TODO: implement following code analysis check for stripped binaries:
478 // 1) op(addr).type == CALL
479 // 2) call_dest = op(addr).addr
480 // 3) op(call_dest).type == STORE
481 // 4) op(call_dest + op(call_dest).size).type == RET
482 [0x00000a65]> pid 6
483 0x00000a65  sym.__x86_indirect_thunk_rax:
484 0x00000a65  .------- e807000000  call 0xa71
485 0x00000a6a  |              f390  pause
486 0x00000a6c  |            0faee8  lfence
487 0x00000a6f  |              ebf9  jmp 0xa6a
488 0x00000a71  `---->     48890424  mov qword [rsp], rax
489 0x00000a75                   c3  ret
490 #endif
491 	return NULL;
492 }
493 
analyze_retpoline(RAnal * anal,RAnalOp * op)494 static void analyze_retpoline(RAnal *anal, RAnalOp *op) {
495 	if (anal->opt.retpoline) {
496 		const char *rr = retpoline_reg (anal, op->jump);
497 		if (rr) {
498 			op->type = R_ANAL_OP_TYPE_RJMP;
499 			op->reg = rr;
500 		}
501 	}
502 }
503 
op_is_set_bp(RAnalOp * op,const char * bp_reg,const char * sp_reg)504 static inline bool op_is_set_bp(RAnalOp *op, const char *bp_reg, const char *sp_reg) {
505 	bool has_dst_reg = op->dst && op->dst->reg && op->dst->reg->name;
506 	bool has_src_reg = op->src[0] && op->src[0]->reg && op->src[0]->reg->name;
507 	if (has_dst_reg && has_src_reg) {
508 		return !strcmp (bp_reg, op->dst->reg->name) && !strcmp (sp_reg, op->src[0]->reg->name);
509 	}
510 	return false;
511 }
512 
does_arch_destroys_dst(const char * arch)513 static inline bool does_arch_destroys_dst(const char *arch) {
514 	return arch && (!strncmp (arch, "arm", 3) || !strcmp (arch, "riscv") || !strcmp (arch, "ppc"));
515 }
516 
fcn_recurse(RAnal * anal,RAnalFunction * fcn,ut64 addr,ut64 len,int depth)517 static int fcn_recurse(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int depth) {
518 	if (depth < 1) {
519 		if (anal->verbose) {
520 			eprintf ("Too deep fcn_recurse at 0x%"PFMT64x "\n", addr);
521 		}
522 		return R_ANAL_RET_ERROR; // MUST BE TOO DEEP
523 	}
524 	// TODO Store all this stuff in the heap so we save memory in the stack
525 	RAnalOp *op = NULL;
526 	const bool continue_after_jump = anal->opt.afterjmp;
527 	const int addrbytes = anal->iob.io ? anal->iob.io->addrbytes : 1;
528 	char *last_reg_mov_lea_name = NULL;
529 	RAnalBlock *bb = NULL;
530 	RAnalBlock *bbg = NULL;
531 	int ret = R_ANAL_RET_END, skip_ret = 0;
532 	bool overlapped = false;
533 	int oplen, idx = 0;
534 	static ut64 cmpval = UT64_MAX; // inherited across functions, otherwise it breaks :?
535 	bool varset = false;
536 	struct {
537 		int cnt;
538 		int idx;
539 		int after;
540 		int pending;
541 		int adjust;
542 		int un_idx; // delay.un_idx
543 	} delay = {
544 		0
545 	};
546 	bool arch_destroys_dst = does_arch_destroys_dst (anal->cur->arch);
547 	const bool is_arm = anal->cur->arch && !strncmp (anal->cur->arch, "arm", 3);
548 	const bool is_x86 = is_arm ? false: anal->cur->arch && !strncmp (anal->cur->arch, "x86", 3);
549 	const bool is_amd64 = is_x86 ? fcn->cc && !strcmp (fcn->cc, "amd64") : false;
550 	const bool is_dalvik = is_x86? false: anal->cur->arch && !strncmp (anal->cur->arch, "dalvik", 6);
551 	RRegItem *variadic_reg = NULL;
552 	if (is_amd64) {
553 		variadic_reg = r_reg_get (anal->reg, "rax", R_REG_TYPE_GPR);
554 	}
555 	bool has_variadic_reg = !!variadic_reg;
556 
557 	if (r_cons_is_breaked ()) {
558 		return R_ANAL_RET_END;
559 	}
560 	if (anal->sleep) {
561 		r_sys_usleep (anal->sleep);
562 	}
563 
564 	// check if address is readable //:
565 	if (!anal->iob.is_valid_offset (anal->iob.io, addr, 0)) {
566 		if (addr != UT64_MAX && !anal->iob.io->va) {
567 			if (anal->verbose) {
568 				eprintf ("Invalid address 0x%"PFMT64x ". Try with io.va=true\n", addr);
569 			}
570 		}
571 		return R_ANAL_RET_ERROR; // MUST BE TOO DEEP
572 	}
573 
574 	RAnalFunction *fcn_at_addr = r_anal_get_function_at (anal, addr);
575 	if (fcn_at_addr && fcn_at_addr != fcn) {
576 		return R_ANAL_RET_ERROR; // MUST BE NOT FOUND
577 	}
578 
579 	RAnalBlock *existing_bb = bbget (anal, addr, anal->opt.jmpmid && is_x86);
580 	if (existing_bb) {
581 		bool existing_in_fcn = r_list_contains (existing_bb->fcns, fcn);
582 		existing_bb = r_anal_block_split (existing_bb, addr);
583 		if (!existing_in_fcn && existing_bb) {
584 			if (existing_bb->addr == fcn->addr) {
585 				// our function starts directly there, so we steal what is ours!
586 				fcn_takeover_block_recursive (fcn, existing_bb);
587 			}
588 		}
589 		if (existing_bb) {
590 			r_anal_block_unref (existing_bb);
591 		}
592 		if (anal->opt.recont) {
593 			return R_ANAL_RET_END;
594 		}
595 		if (anal->verbose) {
596 			eprintf ("r_anal_fcn_bb() fails at 0x%"PFMT64x "\n", addr);
597 		}
598 		return R_ANAL_RET_ERROR; // MUST BE NOT DUP
599 	}
600 
601 	bb = fcn_append_basic_block (anal, fcn, addr);
602 	// we checked before whether there is a bb at addr, so the create should have succeeded
603 	r_return_val_if_fail (bb, R_ANAL_RET_ERROR);
604 
605 	if (!anal->leaddrs) {
606 		anal->leaddrs = r_list_newf (free);
607 		if (!anal->leaddrs) {
608 			eprintf ("Cannot create leaddr list\n");
609 			gotoBeach (R_ANAL_RET_ERROR);
610 		}
611 	}
612 	static ut64 lea_jmptbl_ip = UT64_MAX;
613 	ut64 last_reg_mov_lea_val = UT64_MAX;
614 	bool last_is_reg_mov_lea = false;
615 	bool last_is_push = false;
616 	bool last_is_mov_lr_pc = false;
617 	ut64 last_push_addr = UT64_MAX;
618 	if (anal->limit && addr + idx < anal->limit->from) {
619 		gotoBeach (R_ANAL_RET_END);
620 	}
621 	RAnalFunction *tmp_fcn = r_anal_get_fcn_in (anal, addr, 0);
622 	if (tmp_fcn) {
623 		// Checks if var is already analyzed at given addr
624 		RList *list = r_anal_var_all_list (anal, tmp_fcn);
625 		if (!r_list_empty (list)) {
626 			varset = true;
627 		}
628 		r_list_free (list);
629 	}
630 	ut64 movdisp = UT64_MAX; // used by jmptbl when coded as "mov reg,[R*4+B]"
631 	int maxlen = len * addrbytes;
632 	if (is_dalvik) {
633 		bool skipAnalysis = false;
634 		if (!strncmp (fcn->name, "sym.", 4)) {
635 			if (!strncmp (fcn->name + 4, "imp.", 4)) {
636 				skipAnalysis = true;
637 			} else if (strstr (fcn->name, "field")) {
638 				skipAnalysis = true;
639 			}
640 		}
641 		if (skipAnalysis) {
642 			gotoBeach (R_ANAL_RET_END);
643 		}
644 	}
645 	if ((maxlen - (addrbytes * idx)) > MAX_SCAN_SIZE) {
646 		if (anal->verbose) {
647 			eprintf ("Warning: Skipping large memory region.\n");
648 		}
649 		maxlen = 0;
650 	}
651 
652 	op = r_anal_op_new ();
653 	while (addrbytes * idx < maxlen) {
654 		if (!last_is_reg_mov_lea) {
655 			free (last_reg_mov_lea_name);
656 			last_reg_mov_lea_name = NULL;
657 		}
658 		if (anal->limit && anal->limit->to <= addr + idx) {
659 			break;
660 		}
661 repeat:
662 		if (r_cons_is_breaked ()) {
663 			break;
664 		}
665 		ut8 buf[32]; // 32 bytes is enough to hold any instruction.
666 		ut32 at_delta = addrbytes * idx;
667 		ut64 at = addr + at_delta;
668 		ut64 bytes_read = R_MIN (len - at_delta, sizeof (buf));
669 		ret = read_ahead (anal, at, buf, bytes_read);
670 
671 		if (ret < 0) {
672 			eprintf ("Failed to read\n");
673 			break;
674 		}
675 		if (isInvalidMemory (anal, buf, bytes_read)) {
676 			if (anal->verbose) {
677 				eprintf ("Warning: FFFF opcode at 0x%08"PFMT64x "\n", at);
678 			}
679 			gotoBeach (R_ANAL_RET_ERROR)
680 		}
681 		r_anal_op_fini (op);
682 		if ((oplen = r_anal_op (anal, op, at, buf, bytes_read, R_ANAL_OP_MASK_ESIL | R_ANAL_OP_MASK_VAL | R_ANAL_OP_MASK_HINT)) < 1) {
683 			if (anal->verbose) {
684 				eprintf ("Invalid instruction at 0x%"PFMT64x" with %d bits\n", at, anal->bits);
685 			}
686 			// gotoBeach (R_ANAL_RET_ERROR);
687 			// RET_END causes infinite loops somehow
688 			gotoBeach (R_ANAL_RET_END);
689 		}
690 		const char *bp_reg = anal->reg->name[R_REG_NAME_BP];
691 		const char *sp_reg = anal->reg->name[R_REG_NAME_SP];
692 		const bool has_stack_regs = bp_reg && sp_reg;
693 
694 		if (anal->opt.nopskip && fcn->addr == at) {
695 			RFlagItem *fi = anal->flb.get_at (anal->flb.f, addr, false);
696 			if (!fi || strncmp (fi->name, "sym.", 4)) {
697 				if ((addr + delay.un_idx - oplen) == fcn->addr) {
698 					if (r_anal_block_relocate (bb, bb->addr + oplen, bb->size - oplen)) {
699 						fcn->addr += oplen;
700 						idx = delay.un_idx;
701 						goto repeat;
702 					}
703 				}
704 			}
705 			switch (op->type & R_ANAL_OP_TYPE_MASK) {
706 			case R_ANAL_OP_TYPE_TRAP:
707 			case R_ANAL_OP_TYPE_ILL:
708 			case R_ANAL_OP_TYPE_NOP:
709 				if (r_anal_block_relocate (bb, at + op->size, bb->size)) {
710 					addr = at + op->size;
711 					fcn->addr = addr;
712 					goto repeat;
713 				}
714 			}
715 		}
716 		if (op->hint.new_bits) {
717 			r_anal_hint_set_bits (anal, op->jump, op->hint.new_bits);
718 		}
719 		if (idx > 0 && !overlapped) {
720 			bbg = bbget (anal, at, anal->opt.jmpmid && is_x86);
721 			if (bbg && bbg != bb) {
722 				bb->jump = at;
723 				if (anal->opt.jmpmid && is_x86) {
724 					// This happens when we purposefully walked over another block and overlapped it
725 					// and now we hit an offset where the instructions match again.
726 					// So we need to split the overwalked block.
727 					RAnalBlock *split = r_anal_block_split (bbg, at);
728 					r_anal_block_unref (split);
729 				}
730 				overlapped = true;
731 				if (anal->verbose) {
732 					eprintf ("Overlapped at 0x%08"PFMT64x "\n", at);
733 				}
734 			}
735 		}
736 		if (!overlapped) {
737 			const ut64 newbbsize = bb->size + oplen;
738 			if (newbbsize > MAX_FCN_SIZE) {
739 				gotoBeach (R_ANAL_RET_ERROR);
740 			}
741 			r_anal_bb_set_offset (bb, bb->ninstr++, at - bb->addr);
742 			r_anal_block_set_size (bb, newbbsize);
743 			fcn->ninstr++;
744 		}
745 		if (anal->opt.trycatch) {
746 			const char *name = anal->coreb.getName (anal->coreb.core, at);
747 			if (name) {
748 				if (r_str_startswith (name, "try.") && r_str_endswith (name, ".from")) {
749 					char *handle = strdup (name);
750 					// handle = r_str_replace (handle, ".from", ".to", 0);
751 					ut64 from_addr = anal->coreb.numGet (anal->coreb.core, handle);
752 					handle = r_str_replace (handle, ".from", ".catch", 0);
753 					ut64 handle_addr = anal->coreb.numGet (anal->coreb.core, handle);
754 					bb->jump = at + oplen;
755 					if (from_addr != bb->addr) {
756 						bb->fail = handle_addr;
757 						ret = r_anal_fcn_bb (anal, fcn, handle_addr, depth - 1);
758 						eprintf ("(%s) 0x%08"PFMT64x"\n", handle, handle_addr);
759 						if (bb->size == 0) {
760 							r_anal_function_remove_block (fcn, bb);
761 						}
762 						r_anal_block_unref (bb);
763 						bb = fcn_append_basic_block (anal, fcn, addr);
764 						if (!bb) {
765 							gotoBeach (R_ANAL_RET_ERROR);
766 						}
767 					}
768 				}
769 			}
770 		}
771 		idx += oplen;
772 		delay.un_idx = idx;
773 		if (anal->opt.delay && op->delay > 0 && !delay.pending) {
774 			// Handle first pass through a branch delay jump:
775 			// Come back and handle the current instruction later.
776 			// Save the location of it in `delay.idx`
777 			// note, we have still increased size of basic block
778 			// (and function)
779 			if (anal->verbose) {
780 				eprintf("Enter branch delay at 0x%08"PFMT64x ". bb->sz=%"PFMT64u"\n", at - oplen, bb->size);
781 			}
782 			delay.idx = idx - oplen;
783 			delay.cnt = op->delay;
784 			delay.pending = 1; // we need this in case the actual idx is zero...
785 			delay.adjust = !overlapped; // adjustment is required later to avoid double count
786 			continue;
787 		}
788 
789 		if (delay.cnt > 0) {
790 			// if we had passed a branch delay instruction, keep
791 			// track of how many still to process.
792 			delay.cnt--;
793 			if (!delay.cnt) {
794 				if (anal->verbose) {
795 					eprintf("Last branch delayed opcode at 0x%08"PFMT64x ". bb->sz=%"PFMT64u"\n", addr + idx - oplen, bb->size);
796 				}
797 				delay.after = idx;
798 				idx = delay.idx;
799 				// At this point, we are still looking at the
800 				// last instruction in the branch delay group.
801 				// Next time, we will again be looking
802 				// at the original instruction that entered
803 				// the branch delay.
804 			}
805 		} else if (op->delay > 0 && delay.pending) {
806 			if (anal->verbose) {
807 				eprintf ("Revisit branch delay jump at 0x%08"PFMT64x ". bb->sz=%"PFMT64u"\n", addr + idx - oplen, bb->size);
808 			}
809 			// This is the second pass of the branch delaying opcode
810 			// But we also already counted this instruction in the
811 			// size of the current basic block, so we need to fix that
812 			if (delay.adjust) {
813 				r_anal_block_set_size (bb, (ut64)addrbytes * (ut64)delay.after);
814 				fcn->ninstr--;
815 				if (anal->verbose) {
816 					eprintf ("Correct for branch delay @ %08"PFMT64x " bb.addr=%08"PFMT64x " corrected.bb=%"PFMT64u" f.uncorr=%"PFMT64u"\n",
817 					addr + idx - oplen, bb->addr, bb->size, r_anal_function_linear_size (fcn));
818 				}
819 			}
820 			// Next time, we go to the opcode after the delay count
821 			// Take care not to use this below, use delay.un_idx instead ...
822 			idx = delay.after;
823 			delay.pending = delay.after = delay.idx = delay.adjust = 0;
824 		}
825 		// Note: if we got two branch delay instructions in a row due to an
826 		// compiler bug or junk or something it wont get treated as a delay
827 		switch (op->stackop) {
828 		case R_ANAL_STACK_INC:
829 			if (R_ABS (op->stackptr) < R_ANAL_MAX_INCSTACK) {
830 				fcn->stack += op->stackptr;
831 				if (fcn->stack > fcn->maxstack) {
832 					fcn->maxstack = fcn->stack;
833 				}
834 			}
835 			bb->stackptr += op->stackptr;
836 			break;
837 		case R_ANAL_STACK_RESET:
838 			bb->stackptr = 0;
839 			break;
840 		default:
841 			break;
842 		}
843 		if (op->ptr && op->ptr != UT64_MAX && op->ptr != UT32_MAX) {
844 			// swapped parameters wtf
845 			r_anal_xrefs_set (anal, op->addr, op->ptr, R_ANAL_REF_TYPE_DATA);
846 		}
847 		analyze_retpoline (anal, op);
848 		switch (op->type & R_ANAL_OP_TYPE_MASK) {
849 		case R_ANAL_OP_TYPE_CMOV:
850 		case R_ANAL_OP_TYPE_MOV:
851 			last_is_reg_mov_lea = false;
852 			if (is_arm) { // mov lr, pc
853 				const char *esil = r_strbuf_get (&op->esil);
854 				if (!r_str_cmp (esil, "pc,lr,=", -1)) {
855 					last_is_mov_lr_pc = true;
856 				}
857 			}
858 			if (has_stack_regs && op_is_set_bp (op, bp_reg, sp_reg)) {
859 				fcn->bp_off = fcn->stack;
860 			}
861 			// Is this a mov of immediate value into a register?
862 			if (op->dst && op->dst->reg && op->dst->reg->name && op->val > 0 && op->val != UT64_MAX) {
863 				free (last_reg_mov_lea_name);
864 				if ((last_reg_mov_lea_name = strdup (op->dst->reg->name))) {
865 					last_reg_mov_lea_val = op->val;
866 					last_is_reg_mov_lea = true;
867 				}
868 			}
869 			// skip mov reg, reg
870 			if (anal->opt.jmptbl) {
871 				if (op->scale && op->ireg) {
872 					movdisp = op->disp;
873 				}
874 			}
875 			if (anal->opt.hpskip && regs_exist (op->src[0], op->dst) && !strcmp (op->src[0]->reg->name, op->dst->reg->name)) {
876 				skip_ret = skip_hp (anal, fcn, op, bb, addr, oplen, delay.un_idx, &idx);
877 				if (skip_ret == 1) {
878 					goto repeat;
879 				}
880 				if (skip_ret == 2) {
881 					gotoBeach (R_ANAL_RET_END);
882 				}
883 			}
884 			break;
885 		case R_ANAL_OP_TYPE_LEA:
886 			last_is_reg_mov_lea = false;
887 			// if first byte in op->ptr is 0xff, then set leaddr assuming its a jumptable
888 			{
889 				ut8 buf[4];
890 				anal->iob.read_at (anal->iob.io, op->ptr, buf, sizeof (buf));
891 				if ((buf[2] == 0xff || buf[2] == 0xfe) && buf[3] == 0xff) {
892 					leaddr_pair *pair = R_NEW (leaddr_pair);
893 					if (!pair) {
894 						eprintf ("Cannot create leaddr_pair\n");
895 						gotoBeach (R_ANAL_RET_ERROR);
896 					}
897 					pair->op_addr = op->addr;
898 					pair->leaddr = op->ptr; // XXX movdisp is dupped but seems to be trashed sometimes(?), better track leaddr separately
899 					r_list_append (anal->leaddrs, pair);
900 				}
901 				if (has_stack_regs && op_is_set_bp (op, bp_reg, sp_reg)) {
902 					fcn->bp_off = fcn->stack - op->src[0]->delta;
903 				}
904 				if (op->dst && op->dst->reg && op->dst->reg->name && op->ptr > 0 && op->ptr != UT64_MAX) {
905 					free (last_reg_mov_lea_name);
906 					if ((last_reg_mov_lea_name = strdup (op->dst->reg->name))) {
907 						last_reg_mov_lea_val = op->ptr;
908 						last_is_reg_mov_lea = true;
909 					}
910 				}
911 			}
912 			// skip lea reg,[reg]
913 			if (anal->opt.hpskip && regs_exist (op->src[0], op->dst)
914 			&& !strcmp (op->src[0]->reg->name, op->dst->reg->name)) {
915 				skip_ret = skip_hp (anal, fcn, op, bb, at, oplen, delay.un_idx, &idx);
916 				if (skip_ret == 1) {
917 					goto repeat;
918 				}
919 				if (skip_ret == 2) {
920 					gotoBeach (R_ANAL_RET_END);
921 				}
922 			}
923 			if (anal->opt.jmptbl) {
924 				RAnalOp *jmp_aop = r_anal_op_new ();
925 				ut64 jmptbl_addr = op->ptr;
926 				ut64 casetbl_addr = op->ptr;
927 				if (is_delta_pointer_table (anal, fcn, op->addr, op->ptr, &jmptbl_addr, &casetbl_addr, jmp_aop)) {
928 					ut64 table_size, default_case = 0;
929 					// we require both checks here since try_get_jmptbl_info uses
930 					// BB info of the final jmptbl jump, which is no present with
931 					// is_delta_pointer_table just scanning ahead
932 					// try_get_delta_jmptbl_info doesn't work at times where the
933 					// lea comes after the cmp/default case cjmp, which can be
934 					// handled with try_get_jmptbl_info
935 					ut64 addr = jmp_aop->addr;
936 					if (try_get_jmptbl_info (anal, fcn, addr, bb, &table_size, &default_case)
937 						|| try_get_delta_jmptbl_info (anal, fcn, addr, op->addr, &table_size, &default_case)) {
938 // TODO: -1-
939 						ret = casetbl_addr == op->ptr
940 							? try_walkthrough_jmptbl (anal, fcn, bb, depth, addr, jmptbl_addr, op->ptr, 4, table_size, default_case, 4)
941 							: try_walkthrough_casetbl (anal, fcn, bb, depth, addr, jmptbl_addr, casetbl_addr, op->ptr, 4, table_size, default_case, 4);
942 						if (ret) {
943 							lea_jmptbl_ip = addr;
944 						}
945 					}
946 				}
947 				r_anal_op_free (jmp_aop);
948 			}
949 			break;
950 		case R_ANAL_OP_TYPE_LOAD:
951 			if (anal->opt.loads) {
952 				if (anal->iob.is_valid_offset (anal->iob.io, op->ptr, 0)) {
953 					r_meta_set (anal, R_META_TYPE_DATA, op->ptr, 4, "");
954 				}
955 			}
956 			break;
957 			// Case of valid but unused "add [rax], al"
958 		case R_ANAL_OP_TYPE_ADD:
959 			if (anal->opt.ijmp) {
960 				if ((op->size + 4 <= bytes_read) && !memcmp (buf + op->size, "\x00\x00\x00\x00", 4)) {
961 					r_anal_block_set_size (bb, bb->size - oplen);
962 					op->type = R_ANAL_OP_TYPE_RET;
963 					gotoBeach (R_ANAL_RET_END);
964 				}
965 			}
966 			break;
967 		case R_ANAL_OP_TYPE_ILL:
968 			gotoBeach (R_ANAL_RET_END);
969 		case R_ANAL_OP_TYPE_TRAP:
970 			gotoBeach (R_ANAL_RET_END);
971 		case R_ANAL_OP_TYPE_NOP:
972 			// do nothing, because the nopskip goes before this switch
973 			break;
974 		case R_ANAL_OP_TYPE_JMP:
975 			if (op->jump == UT64_MAX) {
976 				gotoBeach (R_ANAL_RET_END);
977 			}
978 			{
979 				RFlagItem *fi = anal->flb.get_at (anal->flb.f, op->jump, false);
980 				if (fi && strstr (fi->name, "imp.")) {
981 					gotoBeach (R_ANAL_RET_END);
982 				}
983 			}
984 			if (r_cons_is_breaked ()) {
985 				gotoBeach (R_ANAL_RET_END);
986 			}
987 			if (anal->opt.jmpref) {
988 				(void) r_anal_xrefs_set (anal, op->addr, op->jump, R_ANAL_REF_TYPE_CODE);
989 			}
990 			if (!anal->opt.jmpabove && (op->jump < fcn->addr)) {
991 				gotoBeach (R_ANAL_RET_END);
992 			}
993 			if (r_anal_noreturn_at (anal, op->jump)) {
994 				gotoBeach (R_ANAL_RET_END);
995 			}
996 			{
997 				bool must_eob = true;
998 				RIOMap *map = anal->iob.map_get (anal->iob.io, addr);
999 				if (map) {
1000 					must_eob = ( ! r_io_map_contain (map, op->jump) );
1001 				}
1002 				if (must_eob) {
1003 					op->jump = UT64_MAX;
1004 					gotoBeach (R_ANAL_RET_END);
1005 				}
1006 			}
1007 #if FIX_JMP_FWD
1008 			bb->jump = op->jump;
1009 			bb->fail = UT64_MAX;
1010 			FITFCNSZ ();
1011 			gotoBeach (R_ANAL_RET_END);
1012 #else
1013 			if (!overlapped) {
1014 				bb->jump = op->jump;
1015 				bb->fail = UT64_MAX;
1016 			}
1017 			// -1
1018 			ret = r_anal_fcn_bb (anal, fcn, op->jump, depth);
1019 			int tc = anal->opt.tailcall;
1020 			if (tc) {
1021 				// eprintf ("TAIL CALL AT 0x%llx\n", op->addr);
1022 				int diff = op->jump - op->addr;
1023 				if (tc < 0) {
1024 					ut8 buf[32];
1025 					(void)anal->iob.read_at (anal->iob.io, op->jump, (ut8 *) buf, sizeof (buf));
1026 					if (r_anal_is_prelude (anal, buf, sizeof (buf))) {
1027 						fcn_recurse (anal, fcn, op->jump, anal->opt.bb_max_size, depth - 1);
1028 					}
1029 				} else if (R_ABS (diff) > tc) {
1030 					(void) r_anal_xrefs_set (anal, op->addr, op->jump, R_ANAL_REF_TYPE_CALL);
1031 					fcn_recurse (anal, fcn, op->jump, anal->opt.bb_max_size, depth - 1);
1032 					gotoBeach (R_ANAL_RET_END);
1033 				}
1034 			}
1035 			goto beach;
1036 #endif
1037 			break;
1038 		case R_ANAL_OP_TYPE_SUB:
1039 			if (op->val != UT64_MAX && op->val > 0) {
1040 				// if register is not stack
1041 				cmpval = op->val;
1042 			}
1043 			break;
1044 		case R_ANAL_OP_TYPE_CMP: {
1045 			ut64 val = is_x86 ? op->val : op->ptr;
1046 			if (val) {
1047 				cmpval = val;
1048 				bb->cmpval = cmpval;
1049 				bb->cmpreg = op->reg;
1050 				r_anal_cond_free (bb->cond);
1051 				bb->cond = r_anal_cond_new_from_op (op);
1052 			}
1053 		}
1054 			break;
1055 		case R_ANAL_OP_TYPE_CJMP:
1056 		case R_ANAL_OP_TYPE_MCJMP:
1057 		case R_ANAL_OP_TYPE_RCJMP:
1058 		case R_ANAL_OP_TYPE_UCJMP:
1059 			if (anal->opt.cjmpref) {
1060 				(void) r_anal_xrefs_set (anal, op->addr, op->jump, R_ANAL_REF_TYPE_CODE);
1061 			}
1062 			if (!overlapped) {
1063 				bb->jump = op->jump;
1064 				bb->fail = op->fail;
1065 			}
1066 			if (bb->cond) {
1067 				bb->cond->type = op->cond;
1068 			}
1069 			if (anal->opt.jmptbl) {
1070 				if (op->ptr != UT64_MAX) {
1071 					ut64 table_size, default_case;
1072 					table_size = cmpval + 1;
1073 					default_case = op->fail; // is this really default case?
1074 					if (cmpval != UT64_MAX && default_case != UT64_MAX && (op->reg || op->ireg)) {
1075 						// TODO -1
1076 						if (op->ireg) {
1077 							ret = try_walkthrough_jmptbl (anal, fcn, bb, depth, op->addr, op->ptr, op->ptr, anal->bits >> 3, table_size, default_case, ret);
1078 						} else { // op->reg
1079 							ret = walkthrough_arm_jmptbl_style (anal, fcn, bb, depth, op->addr, op->ptr, anal->bits >> 3, table_size, default_case, ret);
1080 						}
1081 						// check if op->jump and op->fail contain jump table location
1082 						// clear jump address, because it's jump table location
1083 						if (op->jump == op->ptr) {
1084 							op->jump = UT64_MAX;
1085 						} else if (op->fail == op->ptr) {
1086 							op->fail = UT64_MAX;
1087 						}
1088 						cmpval = UT64_MAX;
1089 					}
1090 				}
1091 			}
1092 			int saved_stack = fcn->stack;
1093 			// TODO: depth -1 in here
1094 			if (continue_after_jump) {
1095 				r_anal_fcn_bb (anal, fcn, op->jump, depth);
1096 				fcn->stack = saved_stack;
1097 				ret = r_anal_fcn_bb (anal, fcn, op->fail, depth);
1098 				fcn->stack = saved_stack;
1099 			} else {
1100 				ret = r_anal_fcn_bb (anal, fcn, op->jump, depth);
1101 				fcn->stack = saved_stack;
1102 				ret = r_anal_fcn_bb (anal, fcn, op->fail, depth);
1103 				fcn->stack = saved_stack;
1104 				if (op->jump < fcn->addr) {
1105 					if (!overlapped) {
1106 						bb->jump = op->jump;
1107 						bb->fail = UT64_MAX;
1108 					}
1109 					gotoBeach (R_ANAL_RET_END);
1110 				}
1111 			}
1112 
1113 			// XXX breaks mips analysis too !op->delay
1114 			// this will be all x86, arm (at least)
1115 			// without which the analysis is really slow,
1116 			// presumably because each opcode would get revisited
1117 			// (and already covered by a bb) many times
1118 			goto beach;
1119 			// For some reason, branch delayed code (MIPS) needs to continue
1120 			break;
1121 		case R_ANAL_OP_TYPE_UCALL:
1122 		case R_ANAL_OP_TYPE_RCALL:
1123 		case R_ANAL_OP_TYPE_ICALL:
1124 		case R_ANAL_OP_TYPE_IRCALL:
1125 			/* call [dst] */
1126 			// XXX: this is TYPE_MCALL or indirect-call
1127 			(void) r_anal_xrefs_set (anal, op->addr, op->ptr, R_ANAL_REF_TYPE_CALL);
1128 
1129 			if (r_anal_noreturn_at (anal, op->ptr)) {
1130 				RAnalFunction *f = r_anal_get_function_at (anal, op->ptr);
1131 				if (f) {
1132 					f->is_noreturn = true;
1133 				}
1134 				gotoBeach (R_ANAL_RET_END);
1135 			}
1136 			break;
1137 		case R_ANAL_OP_TYPE_CCALL:
1138 		case R_ANAL_OP_TYPE_CALL:
1139 			/* call dst */
1140 			(void) r_anal_xrefs_set (anal, op->addr, op->jump, R_ANAL_REF_TYPE_CALL);
1141 
1142 			if (r_anal_noreturn_at (anal, op->jump)) {
1143 				RAnalFunction *f = r_anal_get_function_at (anal, op->jump);
1144 				if (f) {
1145 					f->is_noreturn = true;
1146 				}
1147 				gotoBeach (R_ANAL_RET_END);
1148 			}
1149 			break;
1150 		case R_ANAL_OP_TYPE_UJMP:
1151 		case R_ANAL_OP_TYPE_RJMP:
1152 			if (is_arm && last_is_mov_lr_pc) {
1153 				break;
1154 			}
1155 			/* fall through */
1156 		case R_ANAL_OP_TYPE_MJMP:
1157 		case R_ANAL_OP_TYPE_IJMP:
1158 		case R_ANAL_OP_TYPE_IRJMP:
1159 			// if the next instruction is a symbol
1160 			if (anal->opt.ijmp && isSymbolNextInstruction (anal, op)) {
1161 				gotoBeach (R_ANAL_RET_END);
1162 			}
1163 			// switch statement
1164 			if (anal->opt.jmptbl && lea_jmptbl_ip != op->addr) {
1165 				ut8 buf[32]; // 32 bytes is enough to hold any instruction.
1166 				// op->ireg since rip relative addressing produces way too many false positives otherwise
1167 				// op->ireg is 0 for rip relative, "rax", etc otherwise
1168 				if (op->ptr != UT64_MAX && op->ireg) { // direct jump
1169 					ut64 table_size, default_case;
1170 					if (try_get_jmptbl_info (anal, fcn, op->addr, bb, &table_size, &default_case)) {
1171 						bool case_table = false;
1172 						RAnalOp *prev_op = r_anal_op_new ();
1173 						anal->iob.read_at (anal->iob.io, op->addr - op->size, buf, sizeof (buf));
1174 						if (r_anal_op (anal, prev_op, op->addr - op->size, buf, sizeof (buf), R_ANAL_OP_MASK_VAL) > 0) {
1175 							bool prev_op_has_dst_name = prev_op->dst && prev_op->dst->reg && prev_op->dst->reg->name;
1176 							bool op_has_src_name = op->src[0] && op->src[0]->reg && op->src[0]->reg->name;
1177 							bool same_reg = (op->ireg && prev_op_has_dst_name && !strcmp (op->ireg, prev_op->dst->reg->name))
1178 								|| (op_has_src_name && prev_op_has_dst_name && !strcmp (op->src[0]->reg->name, prev_op->dst->reg->name));
1179 							if (prev_op->type == R_ANAL_OP_TYPE_MOV && prev_op->disp && prev_op->disp != UT64_MAX && same_reg) {
1180 								//	movzx reg, byte [reg + case_table]
1181 								//	jmp dword [reg*4 + jump_table]
1182 								if (try_walkthrough_casetbl (anal, fcn, bb, depth - 1, op->addr, op->ptr, prev_op->disp, op->ptr, anal->bits >> 3, table_size, default_case, ret)) {
1183 									ret = case_table = true;
1184 								}
1185 							}
1186 						}
1187 						r_anal_op_free (prev_op);
1188 						if (!case_table) {
1189 							ret = try_walkthrough_jmptbl (anal, fcn, bb, depth, op->addr, op->ptr, op->ptr, anal->bits >> 3, table_size, default_case, ret);
1190 						}
1191 					}
1192 				} else if (op->ptr != UT64_MAX && op->reg) { // direct jump
1193 					ut64 table_size, default_case;
1194 					if (try_get_jmptbl_info (anal, fcn, op->addr, bb, &table_size, &default_case)) {
1195 						ret = try_walkthrough_jmptbl (anal, fcn, bb, depth - 1, op->addr, op->ptr, op->ptr, anal->bits >> 3, table_size, default_case, ret);
1196 					}
1197 				} else if (movdisp == 0) {
1198 					ut64 jmptbl_base = UT64_MAX;
1199 					ut64 lea_op_off = UT64_MAX;
1200 					RListIter *lea_op_iter = NULL;
1201 					RListIter *iter;
1202 					leaddr_pair *pair;
1203 					// find nearest candidate leaddr before op->addr
1204 					r_list_foreach (anal->leaddrs, iter, pair) {
1205 						if (pair->op_addr >= op->addr) {
1206 							continue;
1207 						}
1208 						if (lea_op_off == UT64_MAX || lea_op_off > op->addr - pair->op_addr) {
1209 							lea_op_off = op->addr - pair->op_addr;
1210 							jmptbl_base = pair->leaddr;
1211 							lea_op_iter = iter;
1212 						}
1213 					}
1214 					if (lea_op_iter) {
1215 						r_list_delete (anal->leaddrs, lea_op_iter);
1216 					}
1217 					ut64 table_size = cmpval + 1;
1218 					ret = try_walkthrough_jmptbl (anal, fcn, bb, depth - 1, op->addr, jmptbl_base, jmptbl_base, 4, table_size, -1, ret);
1219 					cmpval = UT64_MAX;
1220 				} else if (movdisp != UT64_MAX) {
1221 					ut64 table_size, default_case;
1222 
1223 					if (try_get_jmptbl_info (anal, fcn, op->addr, bb, &table_size, &default_case)) {
1224 						op->ptr = movdisp;
1225 						ret = try_walkthrough_jmptbl (anal, fcn, bb, depth - 1, op->addr, op->ptr, op->ptr, anal->bits >> 3, table_size, default_case, ret);
1226 					}
1227 					movdisp = UT64_MAX;
1228 				} else if (is_arm) {
1229 					if (op->ptrsize == 1) { // TBB
1230 						ut64 pred_cmpval = try_get_cmpval_from_parents(anal, fcn, bb, op->ireg);
1231 						ut64 table_size = 0;
1232 						if (pred_cmpval != UT64_MAX) {
1233 							table_size += pred_cmpval;
1234 						} else {
1235 							table_size += cmpval;
1236 						}
1237 						ret = try_walkthrough_jmptbl (anal, fcn, bb, depth - 1, op->addr, op->addr + op->size,
1238 							op->addr + 4, 1, table_size, UT64_MAX, ret);
1239 						// skip inlined jumptable
1240 						idx += table_size;
1241 					}
1242 					if (op->ptrsize == 2) { // LDRH on thumb/arm
1243 						ut64 pred_cmpval = try_get_cmpval_from_parents(anal, fcn, bb, op->ireg);
1244 						int tablesize = 1;
1245 						if (pred_cmpval != UT64_MAX) {
1246 							tablesize += pred_cmpval;
1247 						} else {
1248 							tablesize += cmpval;
1249 						}
1250 						ret = try_walkthrough_jmptbl (anal, fcn, bb, depth - 1, op->addr, op->addr + op->size,
1251 							op->addr + 4, 2, tablesize, UT64_MAX, ret);
1252 						// skip inlined jumptable
1253 						idx += (tablesize * 2);
1254 					}
1255 				}
1256 			}
1257 			if (lea_jmptbl_ip == op->addr) {
1258 				lea_jmptbl_ip = UT64_MAX;
1259 			}
1260 			if (anal->opt.ijmp) {
1261 				if (continue_after_jump) {
1262 					r_anal_fcn_bb (anal, fcn, op->jump, depth - 1);
1263 					ret = r_anal_fcn_bb (anal, fcn, op->fail, depth - 1);
1264 					if (overlapped) {
1265 						goto analopfinish;
1266 					}
1267 				}
1268 				if (r_anal_noreturn_at (anal, op->jump) || op->eob) {
1269 					goto analopfinish;
1270 				}
1271 			} else {
1272 analopfinish:
1273 				if (op->type == R_ANAL_OP_TYPE_RJMP) {
1274 					gotoBeach (R_ANAL_RET_NOP);
1275 				} else {
1276 					gotoBeach (R_ANAL_RET_END);
1277 				}
1278 			}
1279 			break;
1280 		/* fallthru */
1281 		case R_ANAL_OP_TYPE_PUSH:
1282 			last_is_push = true;
1283 			last_push_addr = op->val;
1284 			if (anal->iob.is_valid_offset (anal->iob.io, last_push_addr, 1)) {
1285 				(void) r_anal_xrefs_set (anal, op->addr, last_push_addr, R_ANAL_REF_TYPE_DATA);
1286 			}
1287 			break;
1288 		case R_ANAL_OP_TYPE_UPUSH:
1289 			if ((op->type & R_ANAL_OP_TYPE_REG) && last_is_reg_mov_lea && op->src[0] && op->src[0]->reg
1290 				&& op->src[0]->reg->name && !strcmp (op->src[0]->reg->name, last_reg_mov_lea_name)) {
1291 				last_is_push = true;
1292 				last_push_addr = last_reg_mov_lea_val;
1293 				if (anal->iob.is_valid_offset (anal->iob.io, last_push_addr, 1)) {
1294 					(void) r_anal_xrefs_set (anal, op->addr, last_push_addr, R_ANAL_REF_TYPE_DATA);
1295 				}
1296 			}
1297 			break;
1298 		case R_ANAL_OP_TYPE_RET:
1299 			if (op->family == R_ANAL_OP_FAMILY_PRIV) {
1300 				fcn->type = R_ANAL_FCN_TYPE_INT;
1301 			}
1302 			if (last_is_push && anal->opt.pushret) {
1303 				op->type = R_ANAL_OP_TYPE_JMP;
1304 				op->jump = last_push_addr;
1305 				bb->jump = op->jump;
1306 				ret = r_anal_fcn_bb (anal, fcn, op->jump, depth - 1);
1307 				goto beach;
1308 			}
1309 			if (!op->cond) {
1310 				if (anal->verbose) {
1311 					eprintf ("RET 0x%08"PFMT64x ". overlap=%s %"PFMT64u" %"PFMT64u"\n",
1312 						addr + delay.un_idx - oplen, r_str_bool (overlapped),
1313 						bb->size, r_anal_function_linear_size (fcn));
1314 				}
1315 				gotoBeach (R_ANAL_RET_END);
1316 			}
1317 			break;
1318 		}
1319 		if (has_stack_regs && arch_destroys_dst) {
1320 			if (op_is_set_bp (op, bp_reg, sp_reg) && op->src[1]) {
1321 				switch (op->type & R_ANAL_OP_TYPE_MASK) {
1322 				case R_ANAL_OP_TYPE_ADD:
1323 					fcn->bp_off = fcn->stack - op->src[1]->imm;
1324 					break;
1325 				case R_ANAL_OP_TYPE_SUB:
1326 					fcn->bp_off = fcn->stack + op->src[1]->imm;
1327 					break;
1328 				}
1329 			}
1330 		}
1331 		if (anal->opt.vars && !varset) {
1332 			r_anal_extract_vars (anal, fcn, op);
1333 		}
1334 		if (op->type != R_ANAL_OP_TYPE_MOV && op->type != R_ANAL_OP_TYPE_CMOV && op->type != R_ANAL_OP_TYPE_LEA) {
1335 			last_is_reg_mov_lea = false;
1336 		}
1337 		if (op->type != R_ANAL_OP_TYPE_PUSH && op->type != R_ANAL_OP_TYPE_RPUSH) {
1338 			last_is_push = false;
1339 		}
1340 		if (is_arm && op->type != R_ANAL_OP_TYPE_MOV) {
1341 			last_is_mov_lr_pc = false;
1342 		}
1343 		if (has_variadic_reg && !fcn->is_variadic) {
1344 			variadic_reg = r_reg_get (anal->reg, "rax", R_REG_TYPE_GPR);
1345 			bool dst_is_variadic = op->dst && op->dst->reg
1346 					&& variadic_reg && op->dst->reg->offset == variadic_reg->offset;
1347 			bool op_is_cmp = (op->type == R_ANAL_OP_TYPE_CMP) || op->type == R_ANAL_OP_TYPE_ACMP;
1348 			if (dst_is_variadic && !op_is_cmp) {
1349 				has_variadic_reg = false;
1350 			} else if (op_is_cmp) {
1351 				if (op->src[0] && op->src[0]->reg && (op->dst->reg == op->src[0]->reg) && dst_is_variadic) {
1352 					fcn->is_variadic = true;
1353 				}
1354 			}
1355 		}
1356 	}
1357 beach:
1358 	r_anal_op_free (op);
1359 	R_FREE (last_reg_mov_lea_name);
1360 	if (bb && bb->size == 0) {
1361 		r_anal_function_remove_block (fcn, bb);
1362 	}
1363 	r_anal_block_update_hash (bb);
1364 	r_anal_block_unref (bb);
1365 	return ret;
1366 }
1367 
r_anal_fcn_bb(RAnal * anal,RAnalFunction * fcn,ut64 addr,int depth)1368 R_API int r_anal_fcn_bb(RAnal *anal, RAnalFunction *fcn, ut64 addr, int depth) {
1369 	return fcn_recurse (anal, fcn, addr, anal->opt.bb_max_size, depth - 1);
1370 }
1371 
r_anal_check_fcn(RAnal * anal,ut8 * buf,ut16 bufsz,ut64 addr,ut64 low,ut64 high)1372 R_API bool r_anal_check_fcn(RAnal *anal, ut8 *buf, ut16 bufsz, ut64 addr, ut64 low, ut64 high) {
1373 	RAnalOp op = {
1374 		0
1375 	};
1376 	int i, oplen, opcnt = 0, pushcnt = 0, movcnt = 0, brcnt = 0;
1377 	if (r_anal_is_prelude (anal, buf, bufsz)) {
1378 		return true;
1379 	}
1380 	for (i = 0; i < bufsz && opcnt < 10; i += oplen, opcnt++) {
1381 		r_anal_op_fini (&op);
1382 		if ((oplen = r_anal_op (anal, &op, addr + i, buf + i, bufsz - i, R_ANAL_OP_MASK_BASIC | R_ANAL_OP_MASK_HINT)) < 1) {
1383 			return false;
1384 		}
1385 		switch (op.type) {
1386 		case R_ANAL_OP_TYPE_PUSH:
1387 		case R_ANAL_OP_TYPE_UPUSH:
1388 		case R_ANAL_OP_TYPE_RPUSH:
1389 			pushcnt++;
1390 			break;
1391 		case R_ANAL_OP_TYPE_MOV:
1392 		case R_ANAL_OP_TYPE_CMOV:
1393 			movcnt++;
1394 			break;
1395 		case R_ANAL_OP_TYPE_JMP:
1396 		case R_ANAL_OP_TYPE_CJMP:
1397 		case R_ANAL_OP_TYPE_CALL:
1398 			if (op.jump < low || op.jump >= high) {
1399 				return false;
1400 			}
1401 			brcnt++;
1402 			break;
1403 		case R_ANAL_OP_TYPE_UNK:
1404 			return false;
1405 		default:
1406 			break;
1407 		}
1408 	}
1409 	return (pushcnt + movcnt + brcnt > 5);
1410 }
1411 
r_anal_trim_jmprefs(RAnal * anal,RAnalFunction * fcn)1412 R_API void r_anal_trim_jmprefs(RAnal *anal, RAnalFunction *fcn) {
1413 	RAnalRef *ref;
1414 	RList *refs = r_anal_function_get_refs (fcn);
1415 	RListIter *iter;
1416 	const bool is_x86 = anal->cur->arch && !strcmp (anal->cur->arch, "x86"); // HACK
1417 
1418 	r_list_foreach (refs, iter, ref) {
1419 		if (ref->type == R_ANAL_REF_TYPE_CODE && r_anal_function_contains (fcn, ref->addr)
1420 		    && (!is_x86 || !r_anal_function_contains (fcn, ref->at))) {
1421 			r_anal_xrefs_deln (anal, ref->at, ref->addr, ref->type);
1422 		}
1423 	}
1424 	r_list_free (refs);
1425 }
1426 
r_anal_del_jmprefs(RAnal * anal,RAnalFunction * fcn)1427 R_API void r_anal_del_jmprefs(RAnal *anal, RAnalFunction *fcn) {
1428 	RAnalRef *ref;
1429 	RList *refs = r_anal_function_get_refs (fcn);
1430 	RListIter *iter;
1431 
1432 	r_list_foreach (refs, iter, ref) {
1433 		if (ref->type == R_ANAL_REF_TYPE_CODE) {
1434 			r_anal_xrefs_deln (anal, ref->at, ref->addr, ref->type);
1435 		}
1436 	}
1437 	r_list_free (refs);
1438 }
1439 
1440 /* Does NOT invalidate read-ahead cache. */
r_anal_fcn(RAnal * anal,RAnalFunction * fcn,ut64 addr,ut64 len,int reftype)1441 R_API int r_anal_fcn(RAnal *anal, RAnalFunction *fcn, ut64 addr, ut64 len, int reftype) {
1442 	RPVector *metas = r_meta_get_all_in(anal, addr, R_META_TYPE_ANY);
1443 	void **it;
1444 	r_pvector_foreach (metas, it) {
1445 		RAnalMetaItem *meta = ((RIntervalNode *)*it)->data;
1446 		switch (meta->type) {
1447 		case R_META_TYPE_DATA:
1448 		case R_META_TYPE_STRING:
1449 		case R_META_TYPE_FORMAT:
1450 			r_pvector_free (metas);
1451 			return 0;
1452 		default:
1453 			break;
1454 		}
1455 	}
1456 	r_pvector_free (metas);
1457 	if (anal->opt.norevisit) {
1458 		if (!anal->visited) {
1459 			anal->visited = set_u_new ();
1460 		}
1461 		if (set_u_contains (anal->visited, addr)) {
1462 			eprintf ("r_anal_fcn: anal.norevisit at 0x%08"PFMT64x" %c\n", addr, reftype);
1463 			return R_ANAL_RET_END;
1464 		}
1465 		set_u_add (anal->visited, addr);
1466 	} else {
1467 		if (anal->visited) {
1468 			set_u_free (anal->visited);
1469 			anal->visited = NULL;
1470 		}
1471 	}
1472 	/* defines fcn. or loc. prefix */
1473 	fcn->type = (reftype == R_ANAL_REF_TYPE_CODE) ? R_ANAL_FCN_TYPE_LOC : R_ANAL_FCN_TYPE_FCN;
1474 	if (fcn->addr == UT64_MAX) {
1475 		fcn->addr = addr;
1476 	}
1477 	fcn->maxstack = 0;
1478 	if (fcn->cc && !strcmp (fcn->cc, "ms")) {
1479 		// Probably should put this on the cc sdb
1480 		const int shadow_store = 0x28; // First 4 args + retaddr
1481 		fcn->stack = fcn->maxstack = fcn->reg_save_area = shadow_store;
1482 	}
1483 	// XXX -1 here results in lots of errors
1484 	int ret = r_anal_fcn_bb (anal, fcn, addr, anal->opt.depth);
1485 	if (ret < 0) {
1486 		if (anal->verbose) {
1487 			eprintf ("Failed to analyze basic block at 0x%"PFMT64x"\n", addr);
1488 		}
1489 	}
1490 	if (anal->opt.endsize && ret == R_ANAL_RET_END && r_anal_function_realsize (fcn)) {   // cfg analysis completed
1491 		RListIter *iter;
1492 		RAnalBlock *bb;
1493 		ut64 endaddr = fcn->addr;
1494 		const bool is_x86 = anal->cur->arch && !strcmp (anal->cur->arch, "x86");
1495 
1496 		// set function size as length of continuous sequence of bbs
1497 		r_list_sort (fcn->bbs, &cmpaddr);
1498 		r_list_foreach (fcn->bbs, iter, bb) {
1499 			if (endaddr == bb->addr) {
1500 				endaddr += bb->size;
1501 			} else if ((endaddr < bb->addr && bb->addr - endaddr < BB_ALIGN)
1502 			           || (anal->opt.jmpmid && is_x86 && endaddr > bb->addr
1503 			               && bb->addr + bb->size > endaddr)) {
1504 				endaddr = bb->addr + bb->size;
1505 			} else {
1506 				break;
1507 			}
1508 		}
1509 #if JAYRO_04
1510 		// fcn is not yet in anal => pass NULL
1511 		r_anal_function_resize (fcn, endaddr - fcn->addr);
1512 #endif
1513 		r_anal_trim_jmprefs (anal, fcn);
1514 	}
1515 	return ret;
1516 }
1517 
1518 // XXX deprecate
r_anal_fcn_del_locs(RAnal * anal,ut64 addr)1519 R_API int r_anal_fcn_del_locs(RAnal *anal, ut64 addr) {
1520 	RListIter *iter, *iter2;
1521 	RAnalFunction *fcn, *f = r_anal_get_fcn_in (anal, addr, R_ANAL_FCN_TYPE_ROOT);
1522 	if (!f) {
1523 		return false;
1524 	}
1525 	r_list_foreach_safe (anal->fcns, iter, iter2, fcn) {
1526 		if (fcn->type != R_ANAL_FCN_TYPE_LOC) {
1527 			continue;
1528 		}
1529 		if (r_anal_function_contains (fcn, addr)) {
1530 			r_anal_function_delete (fcn);
1531 		}
1532 	}
1533 	r_anal_fcn_del (anal, addr);
1534 	return true;
1535 }
1536 
r_anal_fcn_del(RAnal * a,ut64 addr)1537 R_API int r_anal_fcn_del(RAnal *a, ut64 addr) {
1538 	RAnalFunction *fcn;
1539 	RListIter *iter, *iter_tmp;
1540 	r_list_foreach_safe (a->fcns, iter, iter_tmp, fcn) {
1541 		D eprintf ("fcn at %llx %llx\n", fcn->addr, addr);
1542 		if (fcn->addr == addr) {
1543 			r_anal_function_delete (fcn);
1544 		}
1545 	}
1546 	return true;
1547 }
1548 
r_anal_get_fcn_in(RAnal * anal,ut64 addr,int type)1549 R_API RAnalFunction *r_anal_get_fcn_in(RAnal *anal, ut64 addr, int type) {
1550 	RList *list = r_anal_get_functions_in (anal, addr);
1551 	RAnalFunction *ret = NULL;
1552 	if (list && !r_list_empty (list)) {
1553 		if (type == R_ANAL_FCN_TYPE_ROOT) {
1554 			RAnalFunction *fcn;
1555 			RListIter *iter;
1556 			r_list_foreach (list, iter, fcn) {
1557 				if (fcn->addr == addr) {
1558 					ret = fcn;
1559 					break;
1560 				}
1561 			}
1562 		} else {
1563 			ret = r_list_first (list);
1564 		}
1565 	}
1566 	r_list_free (list);
1567 	return ret;
1568 }
1569 
r_anal_get_fcn_in_bounds(RAnal * anal,ut64 addr,int type)1570 R_API RAnalFunction *r_anal_get_fcn_in_bounds(RAnal *anal, ut64 addr, int type) {
1571 	RAnalFunction *fcn, *ret = NULL;
1572 	RListIter *iter;
1573 	if (type == R_ANAL_FCN_TYPE_ROOT) {
1574 		r_list_foreach (anal->fcns, iter, fcn) {
1575 			if (addr == fcn->addr) {
1576 				return fcn;
1577 			}
1578 		}
1579 		return NULL;
1580 	}
1581 	r_list_foreach (anal->fcns, iter, fcn) {
1582 		if (!type || (fcn && fcn->type & type)) {
1583 			if (r_anal_function_contains (fcn, addr)) {
1584 				return fcn;
1585 			}
1586 		}
1587 	}
1588 	return ret;
1589 }
1590 
r_anal_get_function_byname(RAnal * a,const char * name)1591 R_API RAnalFunction *r_anal_get_function_byname(RAnal *a, const char *name) {
1592 	bool found = false;
1593 	RAnalFunction *f = ht_pp_find (a->ht_name_fun, name, &found);
1594 	if (f && found) {
1595 		return f;
1596 	}
1597 	return NULL;
1598 }
1599 
1600 /* rename RAnalFunctionBB.add() */
r_anal_fcn_add_bb(RAnal * a,RAnalFunction * fcn,ut64 addr,ut64 size,ut64 jump,ut64 fail,R_BORROW RAnalDiff * diff)1601 R_API bool r_anal_fcn_add_bb(RAnal *a, RAnalFunction *fcn, ut64 addr, ut64 size, ut64 jump, ut64 fail, R_BORROW RAnalDiff *diff) {
1602 	D eprintf ("Add bb\n");
1603 	if (size == 0) { // empty basic blocks allowed?
1604 		eprintf ("Warning: empty basic block at 0x%08"PFMT64x" is not allowed. pending discussion.\n", addr);
1605 		r_warn_if_reached ();
1606 		return false;
1607 	}
1608 	if (size > a->opt.bb_max_size) {
1609 		eprintf ("Warning: can't allocate such big bb of %"PFMT64d" bytes at 0x%08"PFMT64x"\n", (st64)size, addr);
1610 		r_warn_if_reached ();
1611 		return false;
1612 	}
1613 
1614 	RAnalBlock *block = r_anal_get_block_at (a, addr);
1615 	if (block) {
1616 		r_anal_delete_block (block);
1617 		block = NULL;
1618 	}
1619 
1620 	const bool is_x86 = a->cur->arch && !strcmp (a->cur->arch, "x86");
1621 	// TODO fix this x86-ism
1622 	if (is_x86) {
1623 		r_anal_fcn_invalidate_read_ahead_cache ();
1624 		fcn_recurse (a, fcn, addr, size, 1);
1625 		block = r_anal_get_block_at (a, addr);
1626 		if (block) {
1627 			r_anal_block_set_size (block, size);
1628 		}
1629 	} else {
1630 		block = r_anal_create_block (a, addr, size);
1631 	}
1632 
1633 	if (!block) {
1634 		D eprintf ("Warning: r_anal_fcn_add_bb failed in fcn 0x%08"PFMT64x" at 0x%08"PFMT64x"\n", fcn->addr, addr);
1635 		return false;
1636 	}
1637 
1638 	r_anal_function_add_block (fcn, block);
1639 
1640 	block->jump = jump;
1641 	block->fail = fail;
1642 	block->fail = fail;
1643 	if (diff) {
1644 		if (!block->diff) {
1645 			block->diff = r_anal_diff_new ();
1646 		}
1647 		if (block->diff) {
1648 			block->diff->type = diff->type;
1649 			block->diff->addr = diff->addr;
1650 			if (diff->name) {
1651 				R_FREE (block->diff->name);
1652 				block->diff->name = strdup (diff->name);
1653 			}
1654 		}
1655 	}
1656 	return true;
1657 }
1658 
r_anal_function_loops(RAnalFunction * fcn)1659 R_API int r_anal_function_loops(RAnalFunction *fcn) {
1660 	RListIter *iter;
1661 	RAnalBlock *bb;
1662 	ut32 loops = 0;
1663 	r_list_foreach (fcn->bbs, iter, bb) {
1664 		if (bb->jump != UT64_MAX && bb->jump < bb->addr) {
1665 			loops ++;
1666 		}
1667 		if (bb->fail != UT64_MAX && bb->fail < bb->addr) {
1668 			loops ++;
1669 		}
1670 	}
1671 	return loops;
1672 }
1673 
r_anal_function_complexity(RAnalFunction * fcn)1674 R_API int r_anal_function_complexity(RAnalFunction *fcn) {
1675 /*
1676         CC = E - N + 2P
1677         E = the number of edges of the graph.
1678         N = the number of nodes of the graph.
1679         P = the number of connected components (exit nodes).
1680  */
1681 	RAnal *anal = fcn->anal;
1682 	int E = 0, N = 0, P = 0;
1683 	RListIter *iter;
1684 	RAnalBlock *bb;
1685 
1686 	r_list_foreach (fcn->bbs, iter, bb) {
1687 		N++; // nodes
1688 		if ((!anal || anal->verbose) && bb->jump == UT64_MAX && bb->fail != UT64_MAX) {
1689 			eprintf ("Warning: invalid bb jump/fail pair at 0x%08"PFMT64x" (fcn 0x%08"PFMT64x"\n", bb->addr, fcn->addr);
1690 		}
1691 		if (bb->jump == UT64_MAX && bb->fail == UT64_MAX) {
1692 			P++; // exit nodes
1693 		} else {
1694 			E++; // edges
1695 			if (bb->fail != UT64_MAX) {
1696 				E++;
1697 			}
1698 		}
1699 		if (bb->switch_op && bb->switch_op->cases) {
1700 			E += r_list_length (bb->switch_op->cases);
1701 		}
1702 	}
1703 
1704 	int result = E - N + (2 * P);
1705 	if (result < 1 && (!anal || anal->verbose)) {
1706 		eprintf ("Warning: CC = E(%d) - N(%d) + (2 * P(%d)) < 1 at 0x%08"PFMT64x"\n", E, N, P, fcn->addr);
1707 	}
1708 	// r_return_val_if_fail (result > 0, 0);
1709 	return result;
1710 }
1711 
1712 // tfj and afsj call this function
r_anal_function_get_json(RAnalFunction * function)1713 R_API char *r_anal_function_get_json(RAnalFunction *function) {
1714 	RAnal *a = function->anal;
1715 	PJ *pj = a->coreb.pjWithEncoding (a->coreb.core);
1716 
1717 	char *args = strdup ("");
1718 	char *sdb_ret = r_str_newf ("func.%s.ret", function->name);
1719 	char *sdb_args = r_str_newf ("func.%s.args", function->name);
1720 	// RList *args_list = r_list_newf ((RListFree) free);
1721 	unsigned int i;
1722 	const char *ret_type = sdb_const_get (a->sdb_types, sdb_ret, 0);
1723 	const char *argc_str = sdb_const_get (a->sdb_types, sdb_args, 0);
1724 
1725 	int argc = argc_str? atoi (argc_str): 0;
1726 
1727 	pj_o (pj);
1728 	pj_ks (pj, "name", function->name);
1729 	const bool no_return = r_anal_noreturn_at_addr (a, function->addr);
1730 	pj_kb (pj, "noreturn", no_return);
1731 	pj_ks (pj, "ret", r_str_get_fail (ret_type, "void"));
1732 	if (function->cc) {
1733 		pj_ks (pj, "cc", function->cc);
1734 	}
1735 	pj_k (pj, "args");
1736 	pj_a (pj);
1737 	for (i = 0; i < argc; i++) {
1738 		pj_o (pj);
1739 		char *sdb_arg_i = r_str_newf ("func.%s.arg.%d", function->name, i);
1740 		char *arg_i = sdb_get (a->sdb_types, sdb_arg_i, 0);
1741 		char *comma = strchr (arg_i, ',');
1742 		if (comma) {
1743 			*comma = 0;
1744 			pj_ks (pj, "name", comma + 1);
1745 			pj_ks (pj, "type", arg_i);
1746 			const char *cc_arg = r_reg_get_name (a->reg, r_reg_get_name_idx (sdb_fmt ("A%d", i)));
1747 			if (cc_arg) {
1748 				pj_ks (pj, "cc", cc_arg);
1749 			}
1750 		}
1751 		free (arg_i);
1752 		free (sdb_arg_i);
1753 		pj_end (pj);
1754 	}
1755 	pj_end (pj);
1756 	free (sdb_args);
1757 	free (sdb_ret);
1758 	free (args);
1759 	pj_end (pj);
1760 	return pj_drain (pj);
1761 }
1762 
r_anal_function_get_signature(RAnalFunction * function)1763 R_API char *r_anal_function_get_signature(RAnalFunction *function) {
1764 	RAnal *a = function->anal;
1765 	const char *realname = NULL, *import_substring = NULL;
1766 
1767 	RFlagItem *flag = a->flag_get (a->flb.f, function->addr);
1768 	// Can't access R_FLAGS_FS_IMPORTS, since it is defined in r_core.h
1769 	if (flag && flag->space && !strcmp (flag->space->name, "imports")) {
1770 		// Get substring after last dot
1771 		import_substring = r_str_rchr (function->name, NULL, '.');
1772 		if (import_substring) {
1773 			realname = import_substring + 1;
1774 		}
1775 	} else {
1776 		realname = function->name;
1777 	}
1778 
1779 	char *ret = NULL, *args = strdup ("");
1780 	char *sdb_ret = r_str_newf ("func.%s.ret", realname);
1781 	char *sdb_args = r_str_newf ("func.%s.args", realname);
1782 	// RList *args_list = r_list_newf ((RListFree) free);
1783 	unsigned int i, j;
1784 	const char *ret_type = sdb_const_get (a->sdb_types, sdb_ret, 0);
1785 	const char *argc_str = sdb_const_get (a->sdb_types, sdb_args, 0);
1786 
1787 	int argc = argc_str? atoi (argc_str): 0;
1788 
1789 	for (i = 0; i < argc; i++) {
1790 		char *sdb_arg_i = r_str_newf ("func.%s.arg.%d", realname, i);
1791 		char *arg_i = sdb_get (a->sdb_types, sdb_arg_i, 0);
1792 		// parse commas
1793 		int arg_i_len = strlen (arg_i);
1794 		for (j = 0; j < arg_i_len; j++) {
1795 			if (j > 0 && arg_i[j] == ',') {
1796 				if (arg_i[j - 1] == '*') {
1797 					// remove whitespace
1798 					memmove (arg_i + j, arg_i + j + 1, strlen (arg_i) - j);
1799 				} else {
1800 					arg_i[j] = ' ';
1801 				}
1802 			}
1803 		}
1804 		char *new_args = (i + 1 == argc)
1805 			? r_str_newf ("%s%s", args, arg_i)
1806 			: r_str_newf ("%s%s, ", args, arg_i);
1807 		free (args);
1808 		args = new_args;
1809 
1810 		free (arg_i);
1811 		free (sdb_arg_i);
1812 	}
1813 	ret = r_str_newf ("%s %s (%s);", r_str_get_fail (ret_type, "void"), realname, args);
1814 
1815 	free (sdb_args);
1816 	free (sdb_ret);
1817 	free (args);
1818 	return ret;
1819 }
1820 
1821 /* set function signature from string */
r_anal_str_to_fcn(RAnal * a,RAnalFunction * f,const char * sig)1822 R_API int r_anal_str_to_fcn(RAnal *a, RAnalFunction *f, const char *sig) {
1823 	r_return_val_if_fail (a || f || sig, false);
1824 	char *error_msg = NULL;
1825 	const char *out = r_parse_c_string (a, sig, &error_msg);
1826 	if (out) {
1827 		r_anal_save_parsed_type (a, out);
1828 	}
1829 	if (error_msg) {
1830 		eprintf ("%s", error_msg);
1831 		free (error_msg);
1832 	}
1833 
1834 	return true;
1835 }
1836 
r_anal_fcn_next(RAnal * anal,ut64 addr)1837 R_API RAnalFunction *r_anal_fcn_next(RAnal *anal, ut64 addr) {
1838 	RAnalFunction *fcni;
1839 	RListIter *iter;
1840 	RAnalFunction *closer = NULL;
1841 	r_list_foreach (anal->fcns, iter, fcni) {
1842 		// if (fcni->addr == addr)
1843 		if (fcni->addr > addr && (!closer || fcni->addr < closer->addr)) {
1844 			closer = fcni;
1845 		}
1846 	}
1847 	return closer;
1848 }
1849 
r_anal_fcn_count(RAnal * anal,ut64 from,ut64 to)1850 R_API int r_anal_fcn_count(RAnal *anal, ut64 from, ut64 to) {
1851 	int n = 0;
1852 	RAnalFunction *fcni;
1853 	RListIter *iter;
1854 	r_list_foreach (anal->fcns, iter, fcni) {
1855 		if (fcni->addr >= from && fcni->addr < to) {
1856 			n++;
1857 		}
1858 	}
1859 	return n;
1860 }
1861 
1862 /* return the basic block in fcn found at the given address.
1863  * NULL is returned if such basic block doesn't exist. */
r_anal_fcn_bbget_in(const RAnal * anal,RAnalFunction * fcn,ut64 addr)1864 R_API RAnalBlock *r_anal_fcn_bbget_in(const RAnal *anal, RAnalFunction *fcn, ut64 addr) {
1865 	r_return_val_if_fail (anal && fcn, NULL);
1866 	if (addr == UT64_MAX) {
1867 		return NULL;
1868 	}
1869 	const bool is_x86 = anal->cur->arch && !strcmp (anal->cur->arch, "x86");
1870 	RListIter *iter;
1871 	RAnalBlock *bb;
1872 	r_list_foreach (fcn->bbs, iter, bb) {
1873 		if (addr >= bb->addr && addr < (bb->addr + bb->size)
1874 			&& (!anal->opt.jmpmid || !is_x86 || r_anal_block_op_starts_at (bb, addr))) {
1875 			return bb;
1876 		}
1877 	}
1878 	return NULL;
1879 }
1880 
r_anal_fcn_bbget_at(RAnal * anal,RAnalFunction * fcn,ut64 addr)1881 R_API RAnalBlock *r_anal_fcn_bbget_at(RAnal *anal, RAnalFunction *fcn, ut64 addr) {
1882 	r_return_val_if_fail (fcn && addr != UT64_MAX, NULL);
1883 	RAnalBlock *b = r_anal_get_block_at (anal, addr);
1884 	if (b) {
1885 		return b;
1886 	}
1887 	RListIter *iter;
1888 	RAnalBlock *bb;
1889 	r_list_foreach (fcn->bbs, iter, bb) {
1890 		if (addr == bb->addr) {
1891 			return bb;
1892 		}
1893 	}
1894 	return NULL;
1895 }
1896 
1897 // compute the cyclomatic cost
r_anal_function_cost(RAnalFunction * fcn)1898 R_API ut32 r_anal_function_cost(RAnalFunction *fcn) {
1899 	RListIter *iter;
1900 	RAnalBlock *bb;
1901 	ut32 totalCycles = 0;
1902 	if (!fcn) {
1903 		return 0;
1904 	}
1905 	RAnal *anal = fcn->anal;
1906 	r_list_foreach (fcn->bbs, iter, bb) {
1907 		RAnalOp op;
1908 		ut64 at, end = bb->addr + bb->size;
1909 		ut8 *buf = malloc (bb->size);
1910 		if (!buf) {
1911 			continue;
1912 		}
1913 		(void)anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *) buf, bb->size);
1914 		int idx = 0;
1915 		for (at = bb->addr; at < end;) {
1916 			memset (&op, 0, sizeof (op));
1917 			(void) r_anal_op (anal, &op, at, buf + idx, bb->size - idx, R_ANAL_OP_MASK_BASIC);
1918 			if (op.size < 1) {
1919 				op.size = 1;
1920 			}
1921 			idx += op.size;
1922 			at += op.size;
1923 			totalCycles += op.cycles;
1924 			r_anal_op_fini (&op);
1925 		}
1926 		free (buf);
1927 	}
1928 	return totalCycles;
1929 }
1930 
r_anal_function_count_edges(const RAnalFunction * fcn,R_NULLABLE int * ebbs)1931 R_API int r_anal_function_count_edges(const RAnalFunction *fcn, R_NULLABLE int *ebbs) {
1932 	r_return_val_if_fail (fcn, 0);
1933 	RListIter *iter;
1934 	RAnalBlock *bb;
1935 	int edges = 0;
1936 	if (ebbs) {
1937 		*ebbs = 0;
1938 	}
1939 	r_list_foreach (fcn->bbs, iter, bb) {
1940 		if (ebbs && bb->jump == UT64_MAX && bb->fail == UT64_MAX) {
1941 			*ebbs = *ebbs + 1;
1942 		} else {
1943 			if (bb->jump != UT64_MAX) {
1944 				edges ++;
1945 			}
1946 			if (bb->fail != UT64_MAX) {
1947 				edges ++;
1948 			}
1949 		}
1950 	}
1951 	return edges;
1952 }
1953 
r_anal_function_purity(RAnalFunction * fcn)1954 R_API bool r_anal_function_purity(RAnalFunction *fcn) {
1955 	if (fcn->has_changed) {
1956 		HtUP *ht = ht_up_new (NULL, NULL, NULL);
1957 		if (ht) {
1958 			check_purity (ht, fcn);
1959 			ht_up_free (ht);
1960 		}
1961 	}
1962 	return fcn->is_pure;
1963 }
1964 
can_affect_bp(RAnal * anal,RAnalOp * op)1965 static bool can_affect_bp(RAnal *anal, RAnalOp* op) {
1966 	RAnalValue *dst = op->dst;
1967 	RAnalValue *src = op->src[0];
1968 	const char *opdreg = (dst && dst->reg) ? dst->reg->name : NULL;
1969 	const char *opsreg = (src && src->reg) ? src->reg->name : NULL;
1970 	const char *bp_name = anal->reg->name[R_REG_NAME_BP];
1971 	bool is_bp_dst = opdreg && !dst->memref && !strcmp (opdreg, bp_name);
1972 	bool is_bp_src = opsreg && !src->memref && !strcmp (opsreg, bp_name);
1973 	if (op->type == R_ANAL_OP_TYPE_XCHG) {
1974 		return is_bp_src || is_bp_dst;
1975 	}
1976 	return is_bp_dst;
1977 }
1978 
1979 /*
1980  * This function checks whether any operation in a given function may change bp (excluding "mov bp, sp"
1981  * and "pop bp" at the end).
1982  */
__anal_fcn_check_bp_use(RAnal * anal,RAnalFunction * fcn)1983 static void __anal_fcn_check_bp_use(RAnal *anal, RAnalFunction *fcn) {
1984 	RListIter *iter;
1985 	RAnalBlock *bb;
1986 	char *pos;
1987 	char str_to_find[40];
1988 	snprintf (str_to_find, sizeof (str_to_find),
1989 		"\"type\":\"reg\",\"value\":\"%s", anal->reg->name[R_REG_NAME_BP]);
1990 	if (!fcn) {
1991 		return;
1992 	}
1993 	r_list_foreach (fcn->bbs, iter, bb) {
1994 		RAnalOp op;
1995 		ut64 at, end = bb->addr + bb->size;
1996 		ut8 *buf = malloc (bb->size);
1997 		if (!buf) {
1998 			continue;
1999 		}
2000 		(void)anal->iob.read_at (anal->iob.io, bb->addr, (ut8 *) buf, bb->size);
2001 		int idx = 0;
2002 		for (at = bb->addr; at < end;) {
2003 			r_anal_op (anal, &op, at, buf + idx, bb->size - idx, R_ANAL_OP_MASK_VAL | R_ANAL_OP_MASK_OPEX);
2004 			if (op.size < 1) {
2005 				op.size = 1;
2006 			}
2007 			switch (op.type) {
2008 			case R_ANAL_OP_TYPE_MOV:
2009 			case R_ANAL_OP_TYPE_LEA:
2010 				if (can_affect_bp (anal, &op) && op.src[0] && op.src[0]->reg && op.src[0]->reg->name
2011 				&& strcmp (op.src[0]->reg->name, anal->reg->name[R_REG_NAME_SP])) {
2012 					fcn->bp_frame = false;
2013 					r_anal_op_fini (&op);
2014 					free (buf);
2015 					return;
2016 				}
2017 				break;
2018 			case R_ANAL_OP_TYPE_ADD:
2019 			case R_ANAL_OP_TYPE_AND:
2020 			case R_ANAL_OP_TYPE_CMOV:
2021 			case R_ANAL_OP_TYPE_NOT:
2022 			case R_ANAL_OP_TYPE_OR:
2023 			case R_ANAL_OP_TYPE_ROL:
2024 			case R_ANAL_OP_TYPE_ROR:
2025 			case R_ANAL_OP_TYPE_SAL:
2026 			case R_ANAL_OP_TYPE_SAR:
2027 			case R_ANAL_OP_TYPE_SHR:
2028 			case R_ANAL_OP_TYPE_SUB:
2029 			case R_ANAL_OP_TYPE_XOR:
2030 			case R_ANAL_OP_TYPE_SHL:
2031 // op.dst is not filled for these operations, so for now, check for bp as dst looks like this; in the future it may be just replaced with call to can_affect_bp
2032  				pos = op.opex.ptr ? strstr (op.opex.ptr, str_to_find) : NULL;
2033 				if (pos && pos - op.opex.ptr < 60) {
2034 					fcn->bp_frame = false;
2035 					r_anal_op_fini (&op);
2036 					free (buf);
2037 					return;
2038 				}
2039 				break;
2040 			case R_ANAL_OP_TYPE_XCHG:
2041 				if (op.opex.ptr && strstr (op.opex.ptr, str_to_find)) {
2042 					fcn->bp_frame = false;
2043 					r_anal_op_fini (&op);
2044 					free (buf);
2045 					return;
2046 				}
2047 				break;
2048 			case R_ANAL_OP_TYPE_POP:
2049 				break;
2050 			default:
2051 				break;
2052 			}
2053 			idx += op.size;
2054 			at += op.size;
2055 			r_anal_op_fini (&op);
2056 		}
2057 		free (buf);
2058 	}
2059 }
2060 
r_anal_function_check_bp_use(RAnalFunction * fcn)2061 R_API void r_anal_function_check_bp_use(RAnalFunction *fcn) {
2062 	r_return_if_fail (fcn);
2063 	__anal_fcn_check_bp_use (fcn->anal, fcn);
2064 }
2065 
2066 typedef struct {
2067 	RAnalFunction *fcn;
2068 	HtUP *visited;
2069 } BlockRecurseCtx;
2070 
mark_as_visited(RAnalBlock * bb,void * user)2071 static bool mark_as_visited(RAnalBlock *bb, void *user) {
2072 	BlockRecurseCtx *ctx = user;
2073 	ht_up_insert (ctx->visited, bb->addr, NULL);
2074 	return true;
2075 }
2076 
analize_addr_cb(ut64 addr,void * user)2077 static bool analize_addr_cb(ut64 addr, void *user) {
2078 	BlockRecurseCtx *ctx = user;
2079 	RAnal *anal = ctx->fcn->anal;
2080 	RAnalBlock *existing_bb = r_anal_get_block_at (anal, addr);
2081 	if (!existing_bb || !r_list_contains (ctx->fcn->bbs, existing_bb)) {
2082 		int old_len = r_list_length (ctx->fcn->bbs);
2083 		r_anal_fcn_bb (ctx->fcn->anal, ctx->fcn, addr, anal->opt.depth);
2084 		if (old_len != r_list_length (ctx->fcn->bbs)) {
2085 			r_anal_block_recurse (r_anal_get_block_at (anal, addr), mark_as_visited, user);
2086 		}
2087 	}
2088 	ht_up_insert (ctx->visited, addr, NULL);
2089 	return true;
2090 }
2091 
analize_descendents(RAnalBlock * bb,void * user)2092 static bool analize_descendents(RAnalBlock *bb, void *user) {
2093 	return r_anal_block_successor_addrs_foreach (bb, analize_addr_cb, user);
2094 }
2095 
free_ht_up(HtUPKv * kv)2096 static void free_ht_up(HtUPKv *kv) {
2097 	ht_up_free ((HtUP *)kv->value);
2098 }
2099 
update_var_analysis(RAnalFunction * fcn,int align,ut64 from,ut64 to)2100 static void update_var_analysis(RAnalFunction *fcn, int align, ut64 from, ut64 to) {
2101 	RAnal *anal = fcn->anal;
2102 	ut64 cur_addr;
2103 	int opsz;
2104 	from = align ? from - (from % align) : from;
2105 	to = align ? R_ROUND (to, align) : to;
2106 	if (UT64_SUB_OVFCHK (to, from)) {
2107 		return;
2108 	}
2109 	ut64 len = to - from;
2110 	ut8 *buf = malloc (len);
2111 	if (!buf) {
2112 		return;
2113 	}
2114 	if (anal->iob.read_at (anal->iob.io, from, buf, len) < len) {
2115 		return;
2116 	}
2117 	for (cur_addr = from; cur_addr < to; cur_addr += opsz, len -= opsz) {
2118 		RAnalOp op;
2119 		int ret = r_anal_op (anal->coreb.core, &op, cur_addr, buf, len, R_ANAL_OP_MASK_ESIL | R_ANAL_OP_MASK_VAL);
2120 		if (ret < 1 || op.size < 1) {
2121 			r_anal_op_fini (&op);
2122 			break;
2123 		}
2124 		opsz = op.size;
2125 		r_anal_extract_vars (anal, fcn, &op);
2126 		r_anal_op_fini (&op);
2127 	}
2128 	free (buf);
2129 }
2130 
2131 // Clear function variable acesses inside in a block
clear_bb_vars(RAnalFunction * fcn,RAnalBlock * bb,ut64 from,ut64 to)2132 static void clear_bb_vars(RAnalFunction *fcn, RAnalBlock *bb, ut64 from, ut64 to) {
2133 	int i;
2134 	if (r_pvector_empty (&fcn->vars)) {
2135 		return;
2136 	}
2137 	for (i = 0; i < bb->ninstr; i++) {
2138 		const ut64 addr = r_anal_bb_opaddr_i (bb, i);
2139 		if (addr < from) {
2140 			continue;
2141 		}
2142 		if (addr >= to || addr == UT64_MAX) {
2143 			break;
2144 		}
2145 		RPVector *vars = r_anal_function_get_vars_used_at (fcn, addr);
2146 		if (vars) {
2147 			RPVector *vars_clone = (RPVector *)r_vector_clone ((RVector *)vars);
2148 			void **v;
2149 			r_pvector_foreach (vars_clone, v) {
2150 				r_anal_var_remove_access_at ((RAnalVar *)*v, addr);
2151 			}
2152 			r_pvector_clear (vars_clone);
2153 		}
2154 	}
2155 }
2156 
update_analysis(RAnal * anal,RList * fcns,HtUP * reachable)2157 static void update_analysis(RAnal *anal, RList *fcns, HtUP *reachable) {
2158 	RListIter *it, *it2, *tmp;
2159 	RAnalFunction *fcn;
2160 	bool old_jmpmid = anal->opt.jmpmid;
2161 	anal->opt.jmpmid = true;
2162 	r_anal_fcn_invalidate_read_ahead_cache ();
2163 	r_list_foreach (fcns, it, fcn) {
2164 		// Recurse through blocks of function, mark reachable,
2165 		// analyze edges that don't have a block
2166 		RAnalBlock *bb = r_anal_get_block_at (anal, fcn->addr);
2167 		if (!bb) {
2168 			r_anal_fcn_bb (anal, fcn, fcn->addr, anal->opt.depth);
2169 			bb = r_anal_get_block_at (anal, fcn->addr);
2170 			if (!bb) {
2171 				continue;
2172 			}
2173 		}
2174 		HtUP *ht = ht_up_new0 ();
2175 		ht_up_insert (ht, bb->addr, NULL);
2176 		BlockRecurseCtx ctx = { fcn, ht };
2177 		r_anal_block_recurse (bb, analize_descendents, &ctx);
2178 
2179 		// Remove non-reachable blocks
2180 		r_list_foreach_safe (fcn->bbs, it2, tmp, bb) {
2181 			if (ht_up_find_kv (ht, bb->addr, NULL)) {
2182 				continue;
2183 			}
2184 			HtUP *o_visited = ht_up_find (reachable, fcn->addr, NULL);
2185 			if (!ht_up_find_kv (o_visited, bb->addr, NULL)) {
2186 				// Avoid removing blocks that were already not reachable
2187 				continue;
2188 			}
2189 			fcn->ninstr -= bb->ninstr;
2190 			r_anal_function_remove_block (fcn, bb);
2191 		}
2192 
2193 		RList *bbs = r_list_clone (fcn->bbs);
2194 		r_anal_block_automerge (bbs);
2195 		r_anal_function_delete_unused_vars (fcn);
2196 		r_list_free (bbs);
2197 	}
2198 	anal->opt.jmpmid = old_jmpmid;
2199 }
2200 
calc_reachable_and_remove_block(RList * fcns,RAnalFunction * fcn,RAnalBlock * bb,HtUP * reachable)2201 static void calc_reachable_and_remove_block(RList *fcns, RAnalFunction *fcn, RAnalBlock *bb, HtUP *reachable) {
2202 	clear_bb_vars (fcn, bb, bb->addr, bb->addr + bb->size);
2203 	if (!r_list_contains (fcns, fcn)) {
2204 		r_list_append (fcns, fcn);
2205 
2206 		// Calculate reachable blocks from the start of function
2207 		HtUP *ht = ht_up_new0 ();
2208 		BlockRecurseCtx ctx = { fcn, ht };
2209 		r_anal_block_recurse (r_anal_get_block_at (fcn->anal, fcn->addr), mark_as_visited, &ctx);
2210 		ht_up_insert (reachable, fcn->addr, ht);
2211 	}
2212 	fcn->ninstr -= bb->ninstr;
2213 	r_anal_function_remove_block (fcn, bb);
2214 }
2215 
r_anal_update_analysis_range(RAnal * anal,ut64 addr,int size)2216 R_API void r_anal_update_analysis_range(RAnal *anal, ut64 addr, int size) {
2217 	r_return_if_fail (anal);
2218 	RListIter *it, *it2, *tmp;
2219 	RAnalBlock *bb;
2220 	RAnalFunction *fcn;
2221 	RList *blocks = r_anal_get_blocks_intersect (anal, addr, size);
2222 	if (r_list_empty (blocks)) {
2223 		r_list_free (blocks);
2224 		return;
2225 	}
2226 	RList *fcns = r_list_new ();
2227 	HtUP *reachable = ht_up_new (NULL, free_ht_up, NULL);
2228 	const int align = r_anal_archinfo (anal, R_ANAL_ARCHINFO_ALIGN);
2229 	const ut64 end_write = addr + size;
2230 
2231 	r_list_foreach (blocks, it, bb) {
2232 		if (!r_anal_block_was_modified (bb)) {
2233 			continue;
2234 		}
2235 		r_list_foreach_safe (bb->fcns, it2, tmp, fcn) {
2236 			if (align > 1) {
2237 				if ((end_write < r_anal_bb_opaddr_i (bb, bb->ninstr - 1))
2238 					&& (!bb->switch_op || end_write < bb->switch_op->addr)) {
2239 					// Special case when instructions are aligned and we don't
2240 					// need to worry about a write messing with the jump instructions
2241 					clear_bb_vars (fcn, bb, addr > bb->addr ? addr : bb->addr, end_write);
2242 					update_var_analysis (fcn, align, addr > bb->addr ? addr : bb->addr, end_write);
2243 					r_anal_function_delete_unused_vars (fcn);
2244 					continue;
2245 				}
2246 			}
2247 			calc_reachable_and_remove_block (fcns, fcn, bb, reachable);
2248 		}
2249 	}
2250 	r_list_free (blocks); // This will call r_anal_block_unref to actually remove blocks from RAnal
2251 	update_analysis (anal, fcns, reachable);
2252 	ht_up_free (reachable);
2253 	r_list_free (fcns);
2254 }
2255 
r_anal_function_update_analysis(RAnalFunction * fcn)2256 R_API void r_anal_function_update_analysis(RAnalFunction *fcn) {
2257 	r_return_if_fail (fcn);
2258 	RListIter *it, *it2, *tmp, *tmp2;
2259 	RAnalBlock *bb;
2260 	RAnalFunction *f;
2261 	RList *fcns = r_list_new ();
2262 	HtUP *reachable = ht_up_new (NULL, free_ht_up, NULL);
2263 	r_list_foreach_safe (fcn->bbs, it, tmp, bb) {
2264 		if (r_anal_block_was_modified (bb)) {
2265 			r_list_foreach_safe (bb->fcns, it2, tmp2, f) {
2266 				calc_reachable_and_remove_block (fcns, f, bb, reachable);
2267 			}
2268 		}
2269 	}
2270 	update_analysis (fcn->anal, fcns, reachable);
2271 	ht_up_free (reachable);
2272 	r_list_free (fcns);
2273 }
2274