1 /* radare - LGPL - Copyright 2014-2020 - pancake, condret */
2
3 #include <r_anal.h>
4 #include <r_types.h>
5 #include <r_util.h>
6 #include <r_bind.h>
7
8 // should these be here?
9 #include <math.h>
10 #include <float.h>
11 #include <fenv.h>
12
13 #define IFDBG if (esil && esil->verbose > 1)
14 #define IFVBS if (esil && esil->verbose > 0)
15 #define FLG(x) R_ANAL_ESIL_FLAG_##x
16 #define cpuflag(x, y)\
17 if (esil) {\
18 if (y) { \
19 R_BIT_SET (&esil->flags, FLG (x));\
20 } else { \
21 R_BIT_UNSET (&esil->flags, FLG (x));\
22 } \
23 }
24
25 /* Returns the number that has bits + 1 least significant bits set. */
genmask(int bits)26 static inline ut64 genmask(int bits) {
27 ut64 m = UT64_MAX;
28 if (bits > 0 && bits < 64) {
29 m = (ut64)(((ut64)(2) << bits) - 1);
30 if (!m) {
31 m = UT64_MAX;
32 }
33 }
34 return m;
35 }
36
37 #define ERR(x) if (esil->verbose) { eprintf ("%s\n", x); }
38
isnum(RAnalEsil * esil,const char * str,ut64 * num)39 static bool isnum(RAnalEsil *esil, const char *str, ut64 *num) {
40 if (!esil || !str) {
41 return false;
42 }
43 if (IS_DIGIT (*str)) {
44 if (num) {
45 *num = r_num_get (NULL, str);
46 }
47 return true;
48 }
49 if (num) {
50 *num = 0;
51 }
52 return false;
53 }
54
ispackedreg(RAnalEsil * esil,const char * str)55 static bool ispackedreg(RAnalEsil *esil, const char *str) {
56 RRegItem *ri = r_reg_get (esil->anal->reg, str, -1);
57 return ri? ri->packed_size > 0: false;
58 }
59
isregornum(RAnalEsil * esil,const char * str,ut64 * num)60 static bool isregornum(RAnalEsil *esil, const char *str, ut64 *num) {
61 if (!r_anal_esil_reg_read (esil, str, num, NULL)) {
62 if (!isnum (esil, str, num)) {
63 return false;
64 }
65 }
66 return true;
67 }
68
69 /* pop Register or Number */
popRN(RAnalEsil * esil,ut64 * n)70 static bool popRN(RAnalEsil *esil, ut64 *n) {
71 char *str = r_anal_esil_pop (esil);
72 if (str) {
73 bool ret = isregornum (esil, str, n);
74 free (str);
75 return ret;
76 }
77 return false;
78 }
79
80 /* R_ANAL_ESIL API */
81
esil_ops_free(HtPPKv * kv)82 static void esil_ops_free(HtPPKv *kv) {
83 free (kv->key);
84 free (kv->value);
85 }
86
r_anal_esil_new(int stacksize,int iotrap,unsigned int addrsize)87 R_API RAnalEsil *r_anal_esil_new(int stacksize, int iotrap, unsigned int addrsize) {
88 RAnalEsil *esil = R_NEW0 (RAnalEsil);
89 if (!esil) {
90 return NULL;
91 }
92 if (stacksize < 3) {
93 free (esil);
94 return NULL;
95 }
96 if (!(esil->stack = calloc (sizeof (char *), stacksize))) {
97 free (esil);
98 return NULL;
99 }
100 esil->verbose = false;
101 esil->stacksize = stacksize;
102 esil->parse_goto_count = R_ANAL_ESIL_GOTO_LIMIT;
103 esil->ops = ht_pp_new (NULL, esil_ops_free, NULL);
104 esil->iotrap = iotrap;
105 r_anal_esil_handlers_init (esil);
106 esil->addrmask = genmask (addrsize - 1);
107 return esil;
108 }
109
r_anal_esil_set_op(RAnalEsil * esil,const char * op,RAnalEsilOpCb code,ut32 push,ut32 pop,ut32 type)110 R_API bool r_anal_esil_set_op(RAnalEsil *esil, const char *op, RAnalEsilOpCb code, ut32 push, ut32 pop, ut32 type) {
111 r_return_val_if_fail (code && R_STR_ISNOTEMPTY (op) && esil && esil->ops, false);
112 RAnalEsilOp *eop = ht_pp_find (esil->ops, op, NULL);
113 if (!eop) {
114 eop = R_NEW (RAnalEsilOp);
115 if (!eop) {
116 eprintf ("Cannot allocate esil-operation %s\n", op);
117 return false;
118 }
119 if (!ht_pp_insert (esil->ops, op, eop)) {
120 eprintf ("Cannot set esil-operation %s\n", op);
121 free (eop);
122 return false;
123 }
124 }
125 eop->push = push;
126 eop->pop = pop;
127 eop->type = type;
128 eop->code = code;
129 return true;
130 }
131
r_anal_esil_fire_trap(RAnalEsil * esil,int trap_type,int trap_code)132 static bool r_anal_esil_fire_trap(RAnalEsil *esil, int trap_type, int trap_code) {
133 r_return_val_if_fail (esil, false);
134 if (esil->cmd) {
135 if (esil->cmd (esil, esil->cmd_trap, trap_type, trap_code)) {
136 return true;
137 }
138 }
139 if (esil->anal) {
140 RAnalPlugin *ap = esil->anal->cur;
141 if (ap && ap->esil_trap) {
142 if (ap->esil_trap (esil, trap_type, trap_code)) {
143 return true;
144 }
145 }
146 }
147 #if 0
148 RAnalEsilTrapCB icb;
149 icb = (RAnalEsilTrapCB)sdb_ptr_get (esil->traps, i, 0);
150 return icb (esil, trap_type, trap_code);
151 #endif
152 return false;
153 }
154
r_anal_esil_set_pc(RAnalEsil * esil,ut64 addr)155 R_API bool r_anal_esil_set_pc(RAnalEsil *esil, ut64 addr) {
156 if (esil) {
157 esil->address = addr;
158 return true;
159 }
160 return false;
161 }
162
r_anal_esil_free(RAnalEsil * esil)163 R_API void r_anal_esil_free(RAnalEsil *esil) {
164 if (!esil) {
165 return;
166 }
167 if (esil->anal && esil == esil->anal->esil) {
168 esil->anal->esil = NULL;
169 }
170 ht_pp_free (esil->ops);
171 esil->ops = NULL;
172 r_anal_esil_handlers_fini (esil);
173 sdb_free (esil->stats);
174 esil->stats = NULL;
175 r_anal_esil_stack_free (esil);
176 free (esil->stack);
177 if (esil->anal && esil->anal->cur && esil->anal->cur->esil_fini) {
178 esil->anal->cur->esil_fini (esil);
179 }
180 r_anal_esil_trace_free (esil->trace);
181 esil->trace = NULL;
182 free (esil->cmd_intr);
183 free (esil->cmd_trap);
184 free (esil->cmd_mdev);
185 free (esil->cmd_todo);
186 free (esil->cmd_step);
187 free (esil->cmd_step_out);
188 free (esil->cmd_ioer);
189 free (esil);
190 }
191
esil_internal_sizeof_reg(RAnalEsil * esil,const char * r)192 static ut8 esil_internal_sizeof_reg(RAnalEsil *esil, const char *r) {
193 r_return_val_if_fail (esil && esil->anal && esil->anal->reg && r, 0);
194 RRegItem *ri = r_reg_get (esil->anal->reg, r, -1);
195 return ri? ri->size: 0;
196 }
197
alignCheck(RAnalEsil * esil,ut64 addr)198 static bool alignCheck(RAnalEsil *esil, ut64 addr) {
199 int dataAlign = r_anal_archinfo (esil->anal, R_ANAL_ARCHINFO_DATA_ALIGN);
200 return !(dataAlign > 0 && addr % dataAlign);
201 }
202
internal_esil_mem_read(RAnalEsil * esil,ut64 addr,ut8 * buf,int len)203 static int internal_esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
204 r_return_val_if_fail (esil && esil->anal && esil->anal->iob.io, 0);
205
206 addr &= esil->addrmask;
207 if (!alignCheck (esil, addr)) {
208 esil->trap = R_ANAL_TRAP_READ_ERR;
209 esil->trap_code = addr;
210 return false;
211 }
212 if (esil->cmd_mdev && esil->mdev_range) {
213 if (r_str_range_in (esil->mdev_range, addr)) {
214 if (esil->cmd (esil, esil->cmd_mdev, addr, 0)) {
215 return true;
216 }
217 }
218 }
219 //TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
220 (void)esil->anal->iob.read_at (esil->anal->iob.io, addr, buf, len);
221 // check if request address is mapped , if don't fire trap and esil ioer callback
222 // now with siol, read_at return true/false can't be used to check error vs len
223 if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
224 if (esil->iotrap) {
225 esil->trap = R_ANAL_TRAP_READ_ERR;
226 esil->trap_code = addr;
227 }
228 if (esil->cmd && esil->cmd_ioer && *esil->cmd_ioer) {
229 esil->cmd (esil, esil->cmd_ioer, esil->address, 0);
230 }
231 }
232 return len;
233 }
234
internal_esil_mem_read_no_null(RAnalEsil * esil,ut64 addr,ut8 * buf,int len)235 static int internal_esil_mem_read_no_null(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
236 r_return_val_if_fail (esil && esil->anal && esil->anal->iob.io, 0);
237
238 addr &= esil->addrmask;
239 if (!alignCheck (esil, addr)) {
240 esil->trap = R_ANAL_TRAP_READ_ERR;
241 esil->trap_code = addr;
242 return false;
243 }
244 //TODO: Check if error return from read_at.(on previous version of r2 this call always return len)
245 (void)esil->anal->iob.read_at (esil->anal->iob.io, addr, buf, len);
246 // check if request address is mapped , if don't fire trap and esil ioer callback
247 // now with siol, read_at return true/false can't be used to check error vs len
248 if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
249 if (esil->iotrap) {
250 esil->trap = R_ANAL_TRAP_READ_ERR;
251 esil->trap_code = addr;
252 }
253 }
254 return len;
255 }
256
r_anal_esil_mem_read(RAnalEsil * esil,ut64 addr,ut8 * buf,int len)257 R_API int r_anal_esil_mem_read(RAnalEsil *esil, ut64 addr, ut8 *buf, int len) {
258 int i, ret = 0;
259 r_return_val_if_fail (buf && esil, 0);
260 addr &= esil->addrmask;
261 if (esil->cb.hook_mem_read) {
262 ret = esil->cb.hook_mem_read (esil, addr, buf, len);
263 }
264 if (!alignCheck (esil, addr)) {
265 esil->trap = R_ANAL_TRAP_READ_ERR;
266 esil->trap_code = addr;
267 return false;
268 }
269 if (!ret && esil->cb.mem_read) {
270 ret = esil->cb.mem_read (esil, addr, buf, len);
271 if (ret != len) {
272 if (esil->iotrap) {
273 esil->trap = R_ANAL_TRAP_READ_ERR;
274 esil->trap_code = addr;
275 }
276 }
277 }
278 IFDBG {
279 eprintf ("0x%08" PFMT64x " R> ", addr);
280 for (i = 0; i < len; i++) {
281 eprintf ("%02x", buf[i]);
282 }
283 eprintf ("\n");
284 }
285 return ret;
286 }
287
internal_esil_mem_write(RAnalEsil * esil,ut64 addr,const ut8 * buf,int len)288 static int internal_esil_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
289 int ret = 0;
290 if (!esil || !esil->anal || !esil->anal->iob.io || esil->nowrite) {
291 return 0;
292 }
293 addr &= esil->addrmask;
294 if (!alignCheck (esil, addr)) {
295 esil->trap = R_ANAL_TRAP_READ_ERR;
296 esil->trap_code = addr;
297 return false;
298 }
299 if (esil->cmd_mdev && esil->mdev_range) {
300 if (r_str_range_in (esil->mdev_range, addr)) {
301 if (esil->cmd (esil, esil->cmd_mdev, addr, 1)) {
302 return true;
303 }
304 }
305 }
306 if (esil->anal->iob.write_at (esil->anal->iob.io, addr, buf, len)) {
307 ret = len;
308 }
309 // check if request address is mapped , if don't fire trap and esil ioer callback
310 // now with siol, write_at return true/false can't be used to check error vs len
311 if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
312 if (esil->iotrap) {
313 esil->trap = R_ANAL_TRAP_WRITE_ERR;
314 esil->trap_code = addr;
315 }
316 if (esil->cmd && esil->cmd_ioer && *esil->cmd_ioer) {
317 esil->cmd (esil, esil->cmd_ioer, esil->address, 0);
318 }
319 }
320 return ret;
321 }
322
internal_esil_mem_write_no_null(RAnalEsil * esil,ut64 addr,const ut8 * buf,int len)323 static int internal_esil_mem_write_no_null(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
324 int ret = 0;
325 if (!esil || !esil->anal || !esil->anal->iob.io || !addr) {
326 return 0;
327 }
328 if (esil->nowrite) {
329 return 0;
330 }
331 addr &= esil->addrmask;
332 if (esil->anal->iob.write_at (esil->anal->iob.io, addr, buf, len)) {
333 ret = len;
334 }
335 // check if request address is mapped , if don't fire trap and esil ioer callback
336 // now with siol, write_at return true/false can't be used to check error vs len
337 if (!esil->anal->iob.is_valid_offset (esil->anal->iob.io, addr, false)) {
338 if (esil->iotrap) {
339 esil->trap = R_ANAL_TRAP_WRITE_ERR;
340 esil->trap_code = addr;
341 }
342 }
343 return ret;
344 }
345
r_anal_esil_mem_write(RAnalEsil * esil,ut64 addr,const ut8 * buf,int len)346 R_API int r_anal_esil_mem_write(RAnalEsil *esil, ut64 addr, const ut8 *buf, int len) {
347 int i, ret = 0;
348 if (!buf || !esil) {
349 return 0;
350 }
351 addr &= esil->addrmask;
352 IFDBG {
353 eprintf ("0x%08" PFMT64x " <W ", addr);
354 for (i = 0; i < len; i++) {
355 eprintf ("%02x", buf[i]);
356 }
357 eprintf ("\n");
358 }
359 if (esil->cb.hook_mem_write) {
360 ret = esil->cb.hook_mem_write (esil, addr, buf, len);
361 }
362 if (!ret && esil->cb.mem_write) {
363 ret = esil->cb.mem_write (esil, addr, buf, len);
364 }
365 return ret;
366 }
367
internal_esil_reg_read(RAnalEsil * esil,const char * regname,ut64 * num,int * size)368 static int internal_esil_reg_read(RAnalEsil *esil, const char *regname, ut64 *num, int *size) {
369 RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
370 if (reg) {
371 if (size) {
372 *size = reg->size;
373 }
374 if (num) {
375 *num = r_reg_get_value (esil->anal->reg, reg);
376 }
377 return true;
378 }
379 return false;
380 }
381
internal_esil_reg_write(RAnalEsil * esil,const char * regname,ut64 num)382 static int internal_esil_reg_write(RAnalEsil *esil, const char *regname, ut64 num) {
383 if (esil && esil->anal) {
384 RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
385 if (reg) {
386 r_reg_set_value (esil->anal->reg, reg, num);
387 return true;
388 }
389 }
390 return false;
391 }
392
393 //WTF IS THIS!!!
394 //Are you really trying to prevent the analyzed binary from doing anything that would cause it to segfault irl?
395 //WHY?
396 // - condret
internal_esil_reg_write_no_null(RAnalEsil * esil,const char * regname,ut64 num)397 static int internal_esil_reg_write_no_null (RAnalEsil *esil, const char *regname, ut64 num) {
398 r_return_val_if_fail (esil && esil->anal && esil->anal->reg, false);
399
400 RRegItem *reg = r_reg_get (esil->anal->reg, regname, -1);
401 const char *pc = r_reg_get_name (esil->anal->reg, R_REG_NAME_PC);
402 const char *sp = r_reg_get_name (esil->anal->reg, R_REG_NAME_SP);
403 const char *bp = r_reg_get_name (esil->anal->reg, R_REG_NAME_BP);
404
405 if (!pc) {
406 eprintf ("Warning: RReg profile does not contain PC register\n");
407 return false;
408 }
409 if (!sp) {
410 eprintf ("Warning: RReg profile does not contain SP register\n");
411 return false;
412 }
413 if (!bp) {
414 eprintf ("Warning: RReg profile does not contain BP register\n");
415 return false;
416 }
417 if (reg && reg->name && ((strcmp (reg->name , pc) && strcmp (reg->name, sp) && strcmp(reg->name, bp)) || num)) { //I trust k-maps
418 r_reg_set_value (esil->anal->reg, reg, num);
419 return true;
420 }
421 return false;
422 }
423
r_anal_esil_pushnum(RAnalEsil * esil,ut64 num)424 R_API bool r_anal_esil_pushnum(RAnalEsil *esil, ut64 num) {
425 char str[64];
426 snprintf (str, sizeof (str) - 1, "0x%" PFMT64x, num);
427 return r_anal_esil_push (esil, str);
428 }
429
r_anal_esil_push(RAnalEsil * esil,const char * str)430 R_API bool r_anal_esil_push(RAnalEsil *esil, const char *str) {
431 if (!str || !esil || !*str || esil->stackptr > (esil->stacksize - 1)) {
432 return false;
433 }
434 esil->stack[esil->stackptr++] = strdup (str);
435 return true;
436 }
437
r_anal_esil_pop(RAnalEsil * esil)438 R_API char *r_anal_esil_pop(RAnalEsil *esil) {
439 r_return_val_if_fail (esil, NULL);
440 if (esil->stackptr < 1) {
441 return NULL;
442 }
443 return esil->stack[--esil->stackptr];
444 }
445
r_anal_esil_get_parm_type(RAnalEsil * esil,const char * str)446 R_API int r_anal_esil_get_parm_type(RAnalEsil *esil, const char *str) {
447 int len, i;
448
449 if (!str || !(len = strlen (str))) {
450 return R_ANAL_ESIL_PARM_INVALID;
451 }
452 if (!strncmp (str, "0x", 2)) {
453 return R_ANAL_ESIL_PARM_NUM;
454 }
455 if (!((IS_DIGIT (str[0])) || str[0] == '-')) {
456 goto not_a_number;
457 }
458 for (i = 1; i < len; i++) {
459 if (!(IS_DIGIT (str[i]))) {
460 goto not_a_number;
461 }
462 }
463 return R_ANAL_ESIL_PARM_NUM;
464 not_a_number:
465 if (r_reg_get (esil->anal->reg, str, -1)) {
466 return R_ANAL_ESIL_PARM_REG;
467 }
468 return R_ANAL_ESIL_PARM_INVALID;
469 }
470
r_anal_esil_get_parm_size(RAnalEsil * esil,const char * str,ut64 * num,int * size)471 R_API int r_anal_esil_get_parm_size(RAnalEsil *esil, const char *str, ut64 *num, int *size) {
472 if (!str || !*str) {
473 return false;
474 }
475 int parm_type = r_anal_esil_get_parm_type (esil, str);
476 if (!num || !esil) {
477 return false;
478 }
479 switch (parm_type) {
480 case R_ANAL_ESIL_PARM_NUM:
481 *num = r_num_get (NULL, str);
482 if (size) {
483 *size = esil->anal->bits;
484 }
485 return true;
486 case R_ANAL_ESIL_PARM_REG:
487 if (!r_anal_esil_reg_read (esil, str, num, size)) {
488 break;
489 }
490 return true;
491 default:
492 if (esil->verbose) {
493 eprintf ("Invalid arg (%s)\n", str);
494 }
495 esil->parse_stop = 1;
496 break;
497 }
498 return false;
499 }
500
r_anal_esil_get_parm(RAnalEsil * esil,const char * str,ut64 * num)501 R_API int r_anal_esil_get_parm(RAnalEsil *esil, const char *str, ut64 *num) {
502 return r_anal_esil_get_parm_size (esil, str, num, NULL);
503 }
504
r_anal_esil_reg_write(RAnalEsil * esil,const char * dst,ut64 num)505 R_API int r_anal_esil_reg_write(RAnalEsil *esil, const char *dst, ut64 num) {
506 int ret = 0;
507 IFDBG { eprintf ("%s=0x%" PFMT64x "\n", dst, num); }
508 if (esil && esil->cb.hook_reg_write) {
509 ret = esil->cb.hook_reg_write (esil, dst, &num);
510 }
511 if (!ret && esil && esil->cb.reg_write) {
512 ret = esil->cb.reg_write (esil, dst, num);
513 }
514 return ret;
515 }
516
r_anal_esil_reg_read_nocallback(RAnalEsil * esil,const char * regname,ut64 * num,int * size)517 R_API int r_anal_esil_reg_read_nocallback(RAnalEsil *esil, const char *regname, ut64 *num, int *size) {
518 int ret;
519 void *old_hook_reg_read = (void *) esil->cb.hook_reg_read;
520 esil->cb.hook_reg_read = NULL;
521 ret = r_anal_esil_reg_read (esil, regname, num, size);
522 esil->cb.hook_reg_read = old_hook_reg_read;
523 return ret;
524 }
525
r_anal_esil_reg_read(RAnalEsil * esil,const char * regname,ut64 * num,int * size)526 R_API int r_anal_esil_reg_read(RAnalEsil *esil, const char *regname, ut64 *num, int *size) {
527 bool ret = false;
528 ut64 localnum; // XXX why is this necessary?
529 if (!esil || !regname) {
530 return false;
531 }
532 if (!num) {
533 num = &localnum;
534 }
535 *num = 0LL;
536 if (size) {
537 *size = esil->anal->bits;
538 }
539 if (esil->cb.hook_reg_read) {
540 ret = esil->cb.hook_reg_read (esil, regname, num, size);
541 }
542 if (!ret && esil->cb.reg_read) {
543 ret = esil->cb.reg_read (esil, regname, num, size);
544 }
545 return ret;
546 }
547
r_anal_esil_signext(RAnalEsil * esil,bool assign)548 R_API int r_anal_esil_signext(RAnalEsil *esil, bool assign) {
549 bool ret = false;
550 ut64 src, dst;
551
552 char *p_src = r_anal_esil_pop (esil);
553 if (!p_src) {
554 return false;
555 }
556
557 if (!r_anal_esil_get_parm (esil, p_src, &src)) {
558 ERR ("esil_of: empty stack");
559 free (p_src);
560 return false;
561 }
562
563 char *p_dst = r_anal_esil_pop (esil);
564 if (!p_dst) {
565 free (p_src);
566 return false;
567 }
568
569 if (!r_anal_esil_get_parm (esil, p_dst, &dst)) {
570 ERR ("esil_of: empty stack");
571 free (p_src);
572 free (p_dst);
573 return false;
574 } else {
575 free (p_dst);
576 }
577
578 //Make sure the other bits are 0
579 src &= UT64_MAX >> (64 - dst);
580
581 ut64 m = 0;
582 if (dst < 64) {
583 m = 1ULL << (dst - 1);
584 }
585
586 // dst = (dst & ((1U << src_bit) - 1)); // clear upper bits
587 if (assign) {
588 ret = r_anal_esil_reg_write (esil, p_src, ((src ^ m) - m));
589 } else {
590 ret = r_anal_esil_pushnum (esil, ((src ^ m) - m));
591 }
592
593 free (p_src);
594 return ret;
595 }
596
597 // sign extension operator for use in idiv, imul, movsx*
598 // and other instructions involving signed values, extends n bit value to 64 bit value
599 // example : >"ae 8,0x81,~" ( <src bit width>,<value>,~ )
600 // output : 0xffffffffffffff81
esil_signext(RAnalEsil * esil)601 static bool esil_signext(RAnalEsil *esil) {
602 return r_anal_esil_signext(esil, false);
603 }
604
605 // sign extension assignement
606 // example : > "ae 0x81,a0,="
607 // > "ae 8,a0,~=" ( <src bit width>,register,~= )
608 // output : > ar a0
609 // 0xffffff81
esil_signexteq(RAnalEsil * esil)610 static bool esil_signexteq(RAnalEsil *esil) {
611 return r_anal_esil_signext(esil, true);
612 }
613
esil_zf(RAnalEsil * esil)614 static bool esil_zf(RAnalEsil *esil) {
615 return r_anal_esil_pushnum (esil, !(esil->cur & genmask (esil->lastsz - 1)));
616 }
617
618 // checks if there was a carry from bit x (x,$c)
esil_cf(RAnalEsil * esil)619 static bool esil_cf(RAnalEsil *esil) {
620 char *src = r_anal_esil_pop (esil);
621
622 if (!src) {
623 return false;
624 }
625
626 if (r_anal_esil_get_parm_type (esil, src) != R_ANAL_ESIL_PARM_NUM) {
627 //I'd wish we could enforce consts here
628 //I can't say why, but I feel like "al,$c" would be cancer af
629 // - condret
630 free (src);
631 return false;
632 }
633 ut64 bit;
634 r_anal_esil_get_parm (esil, src, &bit);
635 free (src);
636 //carry from bit <src>
637 //range of src goes from 0 to 63
638 //
639 //implements bit mod 64
640 const ut64 mask = genmask (bit & 0x3f);
641 return r_anal_esil_pushnum (esil, (esil->cur & mask) < (esil->old & mask));
642 }
643
644 // checks if there was a borrow from bit x (x,$b)
esil_bf(RAnalEsil * esil)645 static bool esil_bf(RAnalEsil *esil) {
646 char *src = r_anal_esil_pop (esil);
647
648 if (!src) {
649 return false;
650 }
651
652 if (r_anal_esil_get_parm_type (esil, src) != R_ANAL_ESIL_PARM_NUM) {
653 free (src);
654 return false;
655 }
656 ut64 bit;
657 r_anal_esil_get_parm (esil, src, &bit);
658 free (src);
659 //borrow from bit <src>
660 //range of src goes from 1 to 64
661 // you cannot borrow from bit 0, bc bit -1 cannot not exist
662 //
663 //implements (bit - 1) mod 64
664 const ut64 mask = genmask ((bit + 0x3f) & 0x3f);
665 return r_anal_esil_pushnum (esil, (esil->old & mask) < (esil->cur & mask));
666 }
667
esil_pf(RAnalEsil * esil)668 static bool esil_pf(RAnalEsil *esil) {
669 // Set if the number of set bits in the least significant _byte_ is a multiple of 2.
670 // - Taken from: https://graphics.stanford.edu/~seander/bithacks.html#ParityWith64Bits
671 const ut64 c1 = 0x0101010101010101ULL;
672 const ut64 c2 = 0x8040201008040201ULL;
673 const ut64 c3 = 0x1FF;
674 // Take only the least significant byte.
675 ut64 lsb = esil->cur & 0xff;
676 return r_anal_esil_pushnum (esil, !((((lsb * c1) & c2) % c3) & 1));
677 }
678
679 // like carry
680 // checks overflow from bit x (x,$o)
681 // x,$o ===> x,$c,x-1,$c,^
esil_of(RAnalEsil * esil)682 static bool esil_of(RAnalEsil *esil) {
683 char *p_bit = r_anal_esil_pop (esil);
684
685 if (!p_bit) {
686 return false;
687 }
688
689 if (r_anal_esil_get_parm_type (esil, p_bit) != R_ANAL_ESIL_PARM_NUM) {
690 free (p_bit);
691 return false;
692 }
693 ut64 bit;
694
695 if (!r_anal_esil_get_parm (esil, p_bit, &bit)) {
696 ERR ("esil_of: empty stack");
697 free (p_bit);
698 return false;
699 }
700 free (p_bit);
701
702 const ut64 m[2] = {genmask (bit & 0x3f), genmask ((bit + 0x3f) & 0x3f)};
703 const ut64 result = ((esil->cur & m[0]) < (esil->old & m[0])) ^ ((esil->cur & m[1]) < (esil->old & m[1]));
704 ut64 res = r_anal_esil_pushnum (esil, result);
705 return res;
706 }
707
708 //checks sign bit at x (x,$s)
esil_sf(RAnalEsil * esil)709 static bool esil_sf(RAnalEsil *esil) {
710 r_return_val_if_fail (esil, false);
711
712 char *p_size = r_anal_esil_pop (esil);
713 r_return_val_if_fail (p_size, false);
714
715 if (r_anal_esil_get_parm_type (esil, p_size) != R_ANAL_ESIL_PARM_NUM) {
716 free (p_size);
717 return false;
718 }
719 ut64 size, num;
720 r_anal_esil_get_parm (esil, p_size, &size);
721 free (p_size);
722
723 if (size > 63) {
724 num = 0;
725 } else {
726 num = (esil->cur >> size) & 1;
727 }
728 ut64 res = r_anal_esil_pushnum (esil, num);
729 return res;
730 }
731
esil_ds(RAnalEsil * esil)732 static bool esil_ds(RAnalEsil *esil) {
733 r_return_val_if_fail (esil, false);
734 return r_anal_esil_pushnum (esil, esil->delay);
735 }
736
esil_jt(RAnalEsil * esil)737 static bool esil_jt(RAnalEsil *esil) {
738 r_return_val_if_fail (esil, false);
739 return r_anal_esil_pushnum (esil, esil->jump_target);
740 }
741
esil_js(RAnalEsil * esil)742 static bool esil_js(RAnalEsil *esil) {
743 r_return_val_if_fail (esil, false);
744 return r_anal_esil_pushnum (esil, esil->jump_target_set);
745 }
746
747 //regsize
748 //can we please deprecate this, it's neither accurate, nor needed
749 //plugins should know regsize, and since this is a const even users should know this: ?´e anal.bits´/8
750 // - condret
751 // YES PLS KILL IT
esil_rs(RAnalEsil * esil)752 static bool esil_rs(RAnalEsil *esil) {
753 r_return_val_if_fail (esil && esil->anal, false);
754 return r_anal_esil_pushnum (esil, esil->anal->bits >> 3);
755 }
756
757 //can we please deprecate this, plugins should know their current address
758 //even if they don't know it, $$ should be equal to PC register at the begin of each expression
759 // - condret
760 // YES PLS KILL IT
esil_address(RAnalEsil * esil)761 static bool esil_address(RAnalEsil *esil) {
762 r_return_val_if_fail (esil, false);
763 return r_anal_esil_pushnum (esil, esil->address);
764 }
765
esil_weak_eq(RAnalEsil * esil)766 static bool esil_weak_eq(RAnalEsil *esil) {
767 r_return_val_if_fail (esil && esil->anal, false);
768 char *dst = r_anal_esil_pop (esil);
769 char *src = r_anal_esil_pop (esil);
770
771 if (!(dst && src && (r_anal_esil_get_parm_type(esil, dst) == R_ANAL_ESIL_PARM_REG))) {
772 free (dst);
773 free (src);
774 return false;
775 }
776
777 ut64 src_num;
778 if (r_anal_esil_get_parm (esil, src, &src_num)) {
779 (void)r_anal_esil_reg_write (esil, dst, src_num);
780 free (src);
781 free (dst);
782 return true;
783 }
784
785 free (src);
786 free (dst);
787 return false;
788 }
789
esil_eq(RAnalEsil * esil)790 static bool esil_eq(RAnalEsil *esil) {
791 bool ret = false;
792 ut64 num, num2;
793 char *dst = r_anal_esil_pop (esil);
794 char *src = r_anal_esil_pop (esil);
795 if (!src || !dst) {
796 if (esil->verbose) {
797 eprintf ("Missing elements in the esil stack for '=' at 0x%08"PFMT64x"\n", esil->address);
798 }
799 free (src);
800 free (dst);
801 return false;
802 }
803 if (ispackedreg (esil, dst)) {
804 char *src2 = r_anal_esil_pop (esil);
805 char *newreg = r_str_newf ("%sl", dst);
806 if (r_anal_esil_get_parm (esil, src2, &num2)) {
807 ret = r_anal_esil_reg_write (esil, newreg, num2);
808 }
809 free (newreg);
810 free (src2);
811 goto beach;
812 }
813
814 if (src && dst && r_anal_esil_reg_read_nocallback (esil, dst, &num, NULL)) {
815 if (r_anal_esil_get_parm (esil, src, &num2)) {
816 ret = r_anal_esil_reg_write (esil, dst, num2);
817 esil->cur = num2;
818 esil->old = num;
819 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
820 } else {
821 ERR ("esil_eq: invalid src");
822 }
823 } else {
824 ERR ("esil_eq: invalid parameters");
825 }
826 beach:
827 free (src);
828 free (dst);
829 return ret;
830 }
831
esil_neg(RAnalEsil * esil)832 static bool esil_neg(RAnalEsil *esil) {
833 bool ret = false;
834 char *src = r_anal_esil_pop (esil);
835 if (src) {
836 ut64 num;
837 if (r_anal_esil_get_parm (esil, src, &num)) {
838 r_anal_esil_pushnum (esil, !num);
839 ret = true;
840 } else {
841 if (isregornum (esil, src, &num)) {
842 ret = true;
843 r_anal_esil_pushnum (esil, !num);
844 } else {
845 eprintf ("0x%08"PFMT64x" esil_neg: unknown reg %s\n", esil->address, src);
846 }
847 }
848 } else {
849 ERR ("esil_neg: empty stack");
850 }
851 free (src);
852 return ret;
853 }
854
esil_negeq(RAnalEsil * esil)855 static bool esil_negeq(RAnalEsil *esil) {
856 bool ret = false;
857 ut64 num;
858 char *src = r_anal_esil_pop (esil);
859 if (src && r_anal_esil_reg_read (esil, src, &num, NULL)) {
860 num = !num;
861 r_anal_esil_reg_write (esil, src, num);
862 ret = true;
863 } else {
864 ERR ("esil_negeq: empty stack");
865 }
866 free (src);
867 //r_anal_esil_pushnum (esil, ret);
868 return ret;
869 }
870
esil_nop(RAnalEsil * esil)871 static bool esil_nop(RAnalEsil *esil) {
872 return true;
873 }
874
esil_andeq(RAnalEsil * esil)875 static bool esil_andeq(RAnalEsil *esil) {
876 bool ret = false;
877 ut64 num, num2;
878 char *dst = r_anal_esil_pop (esil);
879 char *src = r_anal_esil_pop (esil);
880 if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
881 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
882 esil->old = num;
883 esil->cur = num & num2;
884 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
885 r_anal_esil_reg_write (esil, dst, num & num2);
886 ret = true;
887 } else {
888 ERR ("esil_andeq: empty stack");
889 }
890 }
891 free (src);
892 free (dst);
893 return ret;
894 }
895
esil_oreq(RAnalEsil * esil)896 static bool esil_oreq(RAnalEsil *esil) {
897 bool ret = false;
898 ut64 num, num2;
899 char *dst = r_anal_esil_pop (esil);
900 char *src = r_anal_esil_pop (esil);
901 if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
902 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
903 esil->old = num;
904 esil->cur = num | num2;
905 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
906 ret = r_anal_esil_reg_write (esil, dst, num | num2);
907 } else {
908 ERR ("esil_ordeq: empty stack");
909 }
910 }
911 free (src);
912 free (dst);
913 return ret;
914 }
915
esil_xoreq(RAnalEsil * esil)916 static bool esil_xoreq(RAnalEsil *esil) {
917 bool ret = false;
918 ut64 num, num2;
919 char *dst = r_anal_esil_pop (esil);
920 char *src = r_anal_esil_pop (esil);
921 if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
922 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
923 esil->old = num;
924 esil->cur = num ^ num2;
925 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
926 ret = r_anal_esil_reg_write (esil, dst, num ^ num2);
927 } else {
928 ERR ("esil_xoreq: empty stack");
929 }
930 }
931 free (src);
932 free (dst);
933 return ret;
934 }
935
936 #if 0
937 static int esil_interrupt_linux_i386(RAnalEsil *esil) { //move this into a plugin
938 ut32 sn, ret = 0;
939 char *usn = r_anal_esil_pop (esil);
940 if (usn) {
941 sn = (ut32) r_num_get (NULL, usn);
942 } else sn = 0x80;
943
944 if (sn == 3) {
945 // trap
946 esil->trap = R_ANAL_TRAP_BREAKPOINT;
947 esil->trap_code = 3;
948 return -1;
949 }
950
951 if (sn != 0x80) {
952 eprintf ("Interrupt 0x%x not handled.", sn);
953 esil->trap = R_ANAL_TRAP_UNHANDLED;
954 esil->trap_code = sn;
955 return -1;
956 }
957 #undef r
958 #define r(x) r_reg_getv (esil->anal->reg, "##x##")
959 #undef rs
960 #define rs(x, y) r_reg_setv (esil->anal->reg, "##x##", y)
961 switch (r(eax)) {
962 case 1:
963 printf ("exit(%d)\n", (int)r(ebx));
964 rs(eax, -1);
965 // never return. stop execution somehow, throw an exception
966 break;
967 case 3:
968 ret = r(edx);
969 printf ("ret:%d = read(fd:%"PFMT64d", ptr:0x%08"PFMT64x", len:%"PFMT64d")\n",
970 (int)ret, r(ebx), r(ecx), r(edx));
971 rs(eax, ret);
972 break;
973 case 4:
974 ret = r(edx);
975 printf ("ret:%d = write(fd:%"PFMT64d", ptr:0x%08"PFMT64x", len:%"PFMT64d")\n",
976 (int)ret, r(ebx), r(ecx), r(edx));
977 rs(eax, ret);
978 break;
979 case 5:
980 ret = -1;
981 printf ("fd:%d = open(file:0x%08"PFMT64x", mode:%"PFMT64d", perm:%"PFMT64d")\n",
982 (int)ret, r(ebx), r(ecx), r(edx));
983 rs(eax, ret);
984 break;
985 }
986 #undef r
987 #undef rs
988 return 0;
989 }
990 #endif
991
esil_trap(RAnalEsil * esil)992 static bool esil_trap(RAnalEsil *esil) {
993 ut64 s, d;
994 if (popRN (esil, &s) && popRN (esil, &d)) {
995 esil->trap = s;
996 esil->trap_code = d;
997 return r_anal_esil_fire_trap (esil, (int)s, (int)d);
998 }
999 ERR ("esil_trap: missing parameters in stack");
1000 return false;
1001 }
1002
esil_bits(RAnalEsil * esil)1003 static bool esil_bits(RAnalEsil *esil) {
1004 ut64 s;
1005 if (popRN (esil, &s)) {
1006 if (esil->anal && esil->anal->coreb.setab) {
1007 esil->anal->coreb.setab (esil->anal->coreb.core, NULL, s);
1008 }
1009 return true;
1010 }
1011 ERR ("esil_bits: missing parameters in stack");
1012 return false;
1013 }
1014
esil_interrupt(RAnalEsil * esil)1015 static bool esil_interrupt(RAnalEsil *esil) {
1016 ut64 interrupt;
1017 if (popRN (esil, &interrupt)) {
1018 return r_anal_esil_fire_interrupt (esil, (ut32)interrupt);
1019 }
1020 return false;
1021 }
1022
esil_syscall(RAnalEsil * esil)1023 static bool esil_syscall(RAnalEsil *esil) {
1024 ut64 sc;
1025 if (popRN (esil, &sc)) {
1026 return r_anal_esil_do_syscall (esil, (ut32)sc);
1027 }
1028 return false;
1029 }
1030
1031 // This function also sets internal vars which is used in flag calculations.
esil_cmp(RAnalEsil * esil)1032 static bool esil_cmp(RAnalEsil *esil) {
1033 ut64 num, num2;
1034 bool ret = false;
1035 char *dst = r_anal_esil_pop (esil);
1036 char *src = r_anal_esil_pop (esil);
1037 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1038 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1039 esil->old = num;
1040 esil->cur = num - num2;
1041 ret = true;
1042 if (r_reg_get (esil->anal->reg, dst, -1)) {
1043 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1044 } else if (r_reg_get (esil->anal->reg, src, -1)) {
1045 esil->lastsz = esil_internal_sizeof_reg (esil, src);
1046 } else {
1047 // default size is set to 64 as internally operands are ut64
1048 esil->lastsz = 64;
1049 }
1050 }
1051 }
1052 free (dst);
1053 free (src);
1054 return ret;
1055 }
1056
1057 #if 0
1058 x86 documentation:
1059 CF - carry flag -- Set on high-order bit carry or borrow; cleared otherwise
1060 num>>63
1061 PF - parity flag
1062 (num&0xff)
1063 Set if low-order eight bits of result contain an even number of "1" bits; cleared otherwise
1064 ZF - zero flags
1065 Set if result is zero; cleared otherwise
1066 zf = num?0:1;
1067 SF - sign flag
1068 Set equal to high-order bit of result (0 if positive 1 if negative)
1069 sf = ((st64)num)<0)?1:0;
1070 OF - overflow flag
1071 if (a>0&&b>0 && (a+b)<0)
1072 Set if result is too large a positive number or too small a negative number (excluding sign bit) to fit in destination operand; cleared otherwise
1073
1074 JBE: CF = 1 || ZF = 1
1075
1076 #endif
1077
1078 /*
1079 * Expects a string in the stack. Each char of the string represents a CPU flag.
1080 * Those relations are associated by the CPU itself and are used to move values
1081 * from the internal ESIL into the RReg instance.
1082 *
1083 * For example:
1084 * zco,?= # update zf, cf and of
1085 *
1086 * If we want to update the esil value of a specific flag we use the =? command
1087 *
1088 * zf,z,=? # esil[zf] = r_reg[zf]
1089 *
1090 * Defining new cpu flags
1091 */
1092 #if 0
1093 static int esil_ifset(RAnalEsil *esil) {
1094 char *s, *src = r_anal_esil_pop (esil);
1095 for (s=src; *s; s++) {
1096 switch (*s) {
1097 case 'z':
1098 r_anal_esil_reg_write (esil, "zf", R_BIT_CHK(&esil->flags, FLG(ZERO)));
1099 break;
1100 case 'c':
1101 r_anal_esil_reg_write (esil, "cf", R_BIT_CHK(&esil->flags, FLG(CARRY)));
1102 break;
1103 case 'o':
1104 r_anal_esil_reg_write (esil, "of", R_BIT_CHK(&esil->flags, FLG(OVERFLOW)));
1105 break;
1106 case 'p':
1107 r_anal_esil_reg_write (esil, "pf", R_BIT_CHK(&esil->flags, FLG(PARITY)));
1108 break;
1109 }
1110 }
1111 free (src);
1112 return 0;
1113 }
1114 #endif
1115
esil_if(RAnalEsil * esil)1116 static bool esil_if(RAnalEsil *esil) {
1117 ut64 num = 0LL;
1118 if (esil->skip) {
1119 esil->skip++;
1120 return true;
1121 }
1122 bool ret = false;
1123 char *src = r_anal_esil_pop (esil);
1124 if (src && r_anal_esil_get_parm (esil, src, &num)) {
1125 // condition not matching, skipping until
1126 if (!num) {
1127 esil->skip++;
1128 }
1129 ret = true;
1130 }
1131 free (src);
1132 return ret;
1133 }
1134
esil_lsl(RAnalEsil * esil)1135 static bool esil_lsl(RAnalEsil *esil) {
1136 bool ret = false;
1137 ut64 num, num2;
1138 char *dst = r_anal_esil_pop (esil);
1139 char *src = r_anal_esil_pop (esil);
1140 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1141 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1142 if (num2 > sizeof (ut64) * 8) {
1143 ERR ("esil_lsl: shift is too big");
1144 } else {
1145 if (num2 > 63) {
1146 r_anal_esil_pushnum (esil, 0);
1147 } else {
1148 r_anal_esil_pushnum (esil, num << num2);
1149 }
1150 ret = true;
1151 }
1152 } else {
1153 ERR ("esil_lsl: empty stack");
1154 }
1155 }
1156 free (src);
1157 free (dst);
1158 return ret;
1159 }
1160
esil_lsleq(RAnalEsil * esil)1161 static bool esil_lsleq(RAnalEsil *esil) {
1162 bool ret = false;
1163 ut64 num, num2;
1164 char *dst = r_anal_esil_pop (esil);
1165 char *src = r_anal_esil_pop (esil);
1166 if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
1167 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1168 if (num2 > sizeof (ut64) * 8) {
1169 ERR ("esil_lsleq: shift is too big");
1170 } else {
1171 esil->old = num;
1172 if (num2 > 63) {
1173 num = 0;
1174 } else {
1175 num <<= num2;
1176 }
1177 esil->cur = num;
1178 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1179 r_anal_esil_reg_write (esil, dst, num);
1180 ret = true;
1181 }
1182 } else {
1183 ERR ("esil_lsleq: empty stack");
1184 }
1185 }
1186 free (src);
1187 free (dst);
1188 return ret;
1189 }
1190
esil_lsr(RAnalEsil * esil)1191 static bool esil_lsr(RAnalEsil *esil) {
1192 bool ret = false;
1193 ut64 num, num2;
1194 char *dst = r_anal_esil_pop (esil);
1195 char *src = r_anal_esil_pop (esil);
1196 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1197 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1198 ut64 res = num >> R_MIN (num2, 63);
1199 r_anal_esil_pushnum (esil, res);
1200 ret = true;
1201 } else {
1202 ERR ("esil_lsr: empty stack");
1203 }
1204 }
1205 free (src);
1206 free (dst);
1207 return ret;
1208 }
1209
esil_lsreq(RAnalEsil * esil)1210 static bool esil_lsreq(RAnalEsil *esil) {
1211 bool ret = false;
1212 ut64 num, num2;
1213 char *dst = r_anal_esil_pop (esil);
1214 char *src = r_anal_esil_pop (esil);
1215 if (dst && r_anal_esil_reg_read (esil, dst, &num, NULL)) {
1216 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1217 if (num2 > 63) {
1218 if (esil->verbose) {
1219 eprintf ("Invalid shift at 0x%08"PFMT64x"\n", esil->address);
1220 }
1221 num2 = 63;
1222 }
1223 esil->old = num;
1224 num >>= num2;
1225 esil->cur = num;
1226 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1227 r_anal_esil_reg_write (esil, dst, num);
1228 ret = true;
1229 } else {
1230 ERR ("esil_lsreq: empty stack");
1231 }
1232 }
1233 free (src);
1234 free (dst);
1235 return ret;
1236 }
1237
esil_asreq(RAnalEsil * esil)1238 static bool esil_asreq(RAnalEsil *esil) {
1239 bool ret = false;
1240 int regsize = 0;
1241 ut64 op_num, param_num;
1242 char *op = r_anal_esil_pop (esil);
1243 char *param = r_anal_esil_pop (esil);
1244 if (op && r_anal_esil_get_parm_size (esil, op, &op_num, ®size)) {
1245 if (param && r_anal_esil_get_parm (esil, param, ¶m_num)) {
1246 ut64 mask = (regsize - 1);
1247 param_num &= mask;
1248 bool isNegative;
1249 if (regsize == 32) {
1250 isNegative = ((st32)op_num)<0;
1251 st32 snum = op_num;
1252 op_num = snum;
1253 } else {
1254 isNegative = ((st64)op_num)<0;
1255 }
1256 if (isNegative) {
1257 if (regsize == 32) {
1258 op_num = -(st64)op_num;
1259 if (op_num >> param_num) {
1260 op_num >>= param_num;
1261 op_num = -(st64)op_num;
1262 } else {
1263 op_num = -1;
1264 }
1265 } else {
1266 ut64 mask = (regsize - 1);
1267 param_num &= mask;
1268 ut64 left_bits = 0;
1269 int shift = regsize - 1;
1270 if (shift < 0 || shift > regsize - 1) {
1271 if (esil->verbose) {
1272 eprintf ("Invalid asreq shift of %d at 0x%"PFMT64x"\n", shift, esil->address);
1273 }
1274 shift = 0;
1275 }
1276 if (param_num > regsize - 1) {
1277 // capstone bug?
1278 if (esil->verbose) {
1279 eprintf ("Invalid asreq shift of %"PFMT64d" at 0x%"PFMT64x"\n", param_num, esil->address);
1280 }
1281 param_num = 30;
1282 }
1283 if (shift >= 63) {
1284 // LL can't handle LShift of 63 or more
1285 if (esil->verbose) {
1286 eprintf ("Invalid asreq shift of %d at 0x%08"PFMT64x"\n", shift, esil->address);
1287 }
1288 } else if (op_num & (1LL << shift)) {
1289 left_bits = (1 << param_num) - 1;
1290 left_bits <<= regsize - param_num;
1291 }
1292 op_num = left_bits | (op_num >> param_num);
1293 }
1294 } else {
1295 op_num >>= param_num;
1296 }
1297 ut64 res = op_num;
1298 esil->cur = res;
1299 esil->lastsz = esil_internal_sizeof_reg (esil, op);
1300 r_anal_esil_reg_write (esil, op, res);
1301 // r_anal_esil_pushnum (esil, res);
1302 ret = true;
1303 } else {
1304 if (esil->verbose) {
1305 eprintf ("esil_asr: empty stack");
1306 }
1307 }
1308 }
1309 free (param);
1310 free (op);
1311 return ret;
1312 }
1313
esil_asr(RAnalEsil * esil)1314 static bool esil_asr(RAnalEsil *esil) {
1315 bool ret = false;
1316 int regsize = 0;
1317 ut64 op_num = 0, param_num = 0;
1318 char *op = r_anal_esil_pop (esil);
1319 char *param = r_anal_esil_pop (esil);
1320 if (op && r_anal_esil_get_parm_size (esil, op, &op_num, ®size)) {
1321 if (param && r_anal_esil_get_parm (esil, param, ¶m_num)) {
1322 if (param_num > regsize - 1) {
1323 // capstone bug?
1324 if (esil->verbose) {
1325 eprintf ("Invalid asr shift of %"PFMT64d" at 0x%"PFMT64x"\n", param_num, esil->address);
1326 }
1327 param_num = 30;
1328 }
1329 bool isNegative;
1330 if (regsize == 32) {
1331 isNegative = ((st32)op_num)<0;
1332 st32 snum = op_num;
1333 op_num = snum;
1334 } else {
1335 isNegative = ((st64)op_num)<0;
1336 }
1337 if (isNegative) {
1338 ut64 mask = (regsize - 1);
1339 param_num &= mask;
1340 ut64 left_bits = 0;
1341 if (op_num & (1ULL << (regsize - 1))) {
1342 left_bits = (1ULL << param_num) - 1;
1343 left_bits <<= regsize - param_num;
1344 }
1345 op_num = left_bits | (op_num >> param_num);
1346 } else {
1347 op_num >>= param_num;
1348 }
1349 ut64 res = op_num;
1350 r_anal_esil_pushnum (esil, res);
1351 ret = true;
1352 } else {
1353 ERR ("esil_asr: empty stack");
1354 }
1355 }
1356 free (param);
1357 free (op);
1358 return ret;
1359 }
1360
esil_ror(RAnalEsil * esil)1361 static bool esil_ror(RAnalEsil *esil) {
1362 bool ret = 0;
1363 int regsize;
1364 ut64 num, num2;
1365 char *dst = r_anal_esil_pop (esil);
1366 char *src = r_anal_esil_pop (esil);
1367 if (dst && r_anal_esil_get_parm_size (esil, dst, &num, ®size)) {
1368 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1369 ut64 mask = (regsize - 1);
1370 num2 &= mask;
1371 ut64 res = (num >> num2) | (num << ((-(st64)num2) & mask));
1372 r_anal_esil_pushnum (esil, res);
1373 ret = true;
1374 } else {
1375 ERR ("esil_ror: empty stack");
1376 }
1377 }
1378 free (src);
1379 free (dst);
1380 return ret;
1381 }
1382
esil_rol(RAnalEsil * esil)1383 static bool esil_rol(RAnalEsil *esil) {
1384 bool ret = 0;
1385 int regsize;
1386 ut64 num, num2;
1387 char *dst = r_anal_esil_pop (esil);
1388 char *src = r_anal_esil_pop (esil);
1389 if (dst && r_anal_esil_get_parm_size (esil, dst, &num, ®size)) {
1390 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1391 ut64 mask = (regsize - 1);
1392 num2 &= mask;
1393 ut64 res = (num << num2) | (num >> ((-(st64)num2) & mask));
1394 r_anal_esil_pushnum (esil, res);
1395 ret = true;
1396 } else {
1397 ERR ("esil_rol: empty stack");
1398 }
1399 }
1400 free (src);
1401 free (dst);
1402 return ret;
1403 }
1404
esil_and(RAnalEsil * esil)1405 static bool esil_and(RAnalEsil *esil) {
1406 bool ret = false;
1407 ut64 num, num2;
1408 char *dst = r_anal_esil_pop (esil);
1409 char *src = r_anal_esil_pop (esil);
1410 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1411 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1412 num &= num2;
1413 r_anal_esil_pushnum (esil, num);
1414 ret = true;
1415 } else {
1416 ERR ("esil_and: empty stack");
1417 }
1418 }
1419 free (src);
1420 free (dst);
1421 return ret;
1422 }
1423
esil_xor(RAnalEsil * esil)1424 static bool esil_xor(RAnalEsil *esil) {
1425 bool ret = false;
1426 ut64 num, num2;
1427 char *dst = r_anal_esil_pop (esil);
1428 char *src = r_anal_esil_pop (esil);
1429 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1430 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1431 num ^= num2;
1432 r_anal_esil_pushnum (esil, num);
1433 ret = true;
1434 } else {
1435 ERR ("esil_xor: empty stack");
1436 }
1437 }
1438 free (src);
1439 free (dst);
1440 return ret;
1441 }
1442
esil_or(RAnalEsil * esil)1443 static bool esil_or(RAnalEsil *esil) {
1444 bool ret = false;
1445 ut64 num, num2;
1446 char *dst = r_anal_esil_pop (esil);
1447 char *src = r_anal_esil_pop (esil);
1448 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
1449 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
1450 num |= num2;
1451 r_anal_esil_pushnum (esil, num);
1452 ret = true;
1453 } else {
1454 ERR ("esil_xor: empty stack");
1455 }
1456 }
1457 free (src);
1458 free (dst);
1459 return ret;
1460 }
1461
r_anal_esil_trapstr(int type)1462 R_API const char *r_anal_esil_trapstr(int type) {
1463 switch (type) {
1464 case R_ANAL_TRAP_READ_ERR:
1465 return "read-err";
1466 case R_ANAL_TRAP_WRITE_ERR:
1467 return "write-err";
1468 case R_ANAL_TRAP_BREAKPOINT:
1469 return "breakpoint";
1470 case R_ANAL_TRAP_UNHANDLED:
1471 return "unhandled";
1472 case R_ANAL_TRAP_DIVBYZERO:
1473 return "divbyzero";
1474 case R_ANAL_TRAP_INVALID:
1475 return "invalid";
1476 case R_ANAL_TRAP_UNALIGNED:
1477 return "unaligned";
1478 case R_ANAL_TRAP_TODO:
1479 return "todo";
1480 default:
1481 return "unknown";
1482 }
1483 }
1484
r_anal_esil_dumpstack(RAnalEsil * esil)1485 R_API bool r_anal_esil_dumpstack(RAnalEsil *esil) {
1486 r_return_val_if_fail (esil, false);
1487 int i;
1488 if (esil->trap) {
1489 eprintf ("ESIL TRAP type %d code 0x%08x %s\n",
1490 esil->trap, esil->trap_code,
1491 r_anal_esil_trapstr (esil->trap));
1492 }
1493 if (esil->stackptr < 1) {
1494 return false;
1495 }
1496 for (i = esil->stackptr - 1; i >= 0; i--) {
1497 esil->anal->cb_printf ("%s\n", esil->stack[i]);
1498 }
1499 return true;
1500 }
1501
esil_break(RAnalEsil * esil)1502 static bool esil_break(RAnalEsil *esil) {
1503 esil->parse_stop = 1;
1504 return 1;
1505 }
1506
esil_clear(RAnalEsil * esil)1507 static bool esil_clear(RAnalEsil *esil) {
1508 char *r;
1509 while ((r = r_anal_esil_pop (esil))) {
1510 free (r);
1511 }
1512 return 1;
1513 }
1514
esil_todo(RAnalEsil * esil)1515 static bool esil_todo(RAnalEsil *esil) {
1516 esil->parse_stop = 2;
1517 return 1;
1518 }
1519
esil_goto(RAnalEsil * esil)1520 static bool esil_goto(RAnalEsil *esil) {
1521 ut64 num = 0;
1522 char *src = r_anal_esil_pop (esil);
1523 if (src && *src && r_anal_esil_get_parm (esil, src, &num)) {
1524 esil->parse_goto = num;
1525 }
1526 free (src);
1527 return 1;
1528 }
1529
esil_repeat(RAnalEsil * esil)1530 static bool esil_repeat(RAnalEsil *esil) {
1531 char *dst = r_anal_esil_pop (esil); // destaintion of the goto
1532 char *src = r_anal_esil_pop (esil); // value of the counter
1533 ut64 n, num = 0;
1534 if (r_anal_esil_get_parm (esil, src, &n) && r_anal_esil_get_parm (esil, dst, &num)) {
1535 if (n > 1) {
1536 esil->parse_goto = num;
1537 r_anal_esil_pushnum (esil, n - 1);
1538 }
1539 }
1540 free (dst);
1541 free (src);
1542 return 1;
1543 }
1544
esil_pop(RAnalEsil * esil)1545 static bool esil_pop(RAnalEsil *esil) {
1546 char *dst = r_anal_esil_pop (esil);
1547 free (dst);
1548 return 1;
1549 }
1550
esil_mod(RAnalEsil * esil)1551 static bool esil_mod(RAnalEsil *esil) {
1552 bool ret = false;
1553 ut64 s, d;
1554 char *dst = r_anal_esil_pop (esil);
1555 char *src = r_anal_esil_pop (esil);
1556 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1557 if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1558 if (s == 0) {
1559 if (esil->verbose > 0) {
1560 eprintf ("0x%08"PFMT64x" esil_mod: Division by zero!\n", esil->address);
1561 }
1562 esil->trap = R_ANAL_TRAP_DIVBYZERO;
1563 esil->trap_code = 0;
1564 } else {
1565 r_anal_esil_pushnum (esil, d % s);
1566 }
1567 ret = true;
1568 }
1569 } else {
1570 ERR ("esil_mod: invalid parameters");
1571 }
1572 free (dst);
1573 free (src);
1574 return ret;
1575 }
1576
esil_signed_mod(RAnalEsil * esil)1577 static bool esil_signed_mod(RAnalEsil *esil) {
1578 bool ret = false;
1579 st64 s, d;
1580 char *dst = r_anal_esil_pop (esil);
1581 char *src = r_anal_esil_pop (esil);
1582 if (src && r_anal_esil_get_parm (esil, src, (ut64 *)&s)) {
1583 if (dst && r_anal_esil_get_parm (esil, dst, (ut64 *)&d)) {
1584 if (ST64_DIV_OVFCHK (d, s)) {
1585 if (esil->verbose > 0) {
1586 eprintf ("0x%08"PFMT64x" esil_mod: Division by zero!\n", esil->address);
1587 }
1588 esil->trap = R_ANAL_TRAP_DIVBYZERO;
1589 esil->trap_code = 0;
1590 } else {
1591 r_anal_esil_pushnum (esil, d % s);
1592 }
1593 ret = true;
1594 }
1595 } else {
1596 ERR ("esil_mod: invalid parameters");
1597 }
1598 free (dst);
1599 free (src);
1600 return ret;
1601 }
1602
esil_modeq(RAnalEsil * esil)1603 static bool esil_modeq(RAnalEsil *esil) {
1604 bool ret = false;
1605 ut64 s, d;
1606 char *dst = r_anal_esil_pop (esil);
1607 char *src = r_anal_esil_pop (esil);
1608 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1609 if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1610 if (s) {
1611 esil->old = d;
1612 esil->cur = d % s;
1613 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1614 r_anal_esil_reg_write (esil, dst, d % s);
1615 } else {
1616 ERR ("esil_modeq: Division by zero!");
1617 esil->trap = R_ANAL_TRAP_DIVBYZERO;
1618 esil->trap_code = 0;
1619 }
1620 ret = true;
1621 } else {
1622 ERR ("esil_modeq: empty stack");
1623 }
1624 } else {
1625 ERR ("esil_modeq: invalid parameters");
1626 }
1627 free (src);
1628 free (dst);
1629 return ret;
1630 }
1631
esil_div(RAnalEsil * esil)1632 static bool esil_div(RAnalEsil *esil) {
1633 bool ret = false;
1634 ut64 s, d;
1635 char *dst = r_anal_esil_pop (esil);
1636 char *src = r_anal_esil_pop (esil);
1637 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1638 if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1639 if (s == 0) {
1640 ERR ("esil_div: Division by zero!");
1641 esil->trap = R_ANAL_TRAP_DIVBYZERO;
1642 esil->trap_code = 0;
1643 } else {
1644 r_anal_esil_pushnum (esil, d / s);
1645 }
1646 ret = true;
1647 }
1648 } else {
1649 ERR ("esil_div: invalid parameters");
1650 }
1651 free (src);
1652 free (dst);
1653 return ret;
1654 }
1655
esil_signed_div(RAnalEsil * esil)1656 static bool esil_signed_div(RAnalEsil *esil) {
1657 bool ret = false;
1658 st64 s, d;
1659 char *dst = r_anal_esil_pop (esil);
1660 char *src = r_anal_esil_pop (esil);
1661 if (src && r_anal_esil_get_parm (esil, src, (ut64 *)&s)) {
1662 if (dst && r_anal_esil_get_parm (esil, dst, (ut64 *)&d)) {
1663 if (ST64_DIV_OVFCHK (d, s)) {
1664 ERR ("esil_div: Division by zero!");
1665 esil->trap = R_ANAL_TRAP_DIVBYZERO;
1666 esil->trap_code = 0;
1667 } else {
1668 r_anal_esil_pushnum (esil, d / s);
1669 }
1670 ret = true;
1671 }
1672 } else {
1673 ERR ("esil_div: invalid parameters");
1674 }
1675 free (src);
1676 free (dst);
1677 return ret;
1678 }
1679
esil_diveq(RAnalEsil * esil)1680 static bool esil_diveq(RAnalEsil *esil) {
1681 bool ret = false;
1682 ut64 s, d;
1683 char *dst = r_anal_esil_pop (esil);
1684 char *src = r_anal_esil_pop (esil);
1685 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1686 if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1687 if (s) {
1688 esil->old = d;
1689 esil->cur = d / s;
1690 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1691 r_anal_esil_reg_write (esil, dst, d / s);
1692 } else {
1693 // eprintf ("0x%08"PFMT64x" esil_diveq: Division by zero!\n", esil->address);
1694 esil->trap = R_ANAL_TRAP_DIVBYZERO;
1695 esil->trap_code = 0;
1696 }
1697 ret = true;
1698 } else {
1699 ERR ("esil_diveq: empty stack");
1700 }
1701 } else {
1702 ERR ("esil_diveq: invalid parameters");
1703 }
1704 free (src);
1705 free (dst);
1706 return ret;
1707 }
1708
1709 // 128 bit multiplication result
mult64to128(ut64 op1,ut64 op2,ut64 * hi,ut64 * lo)1710 static void mult64to128(ut64 op1, ut64 op2, ut64 *hi, ut64 *lo) {
1711 ut64 u1 = (op1 & 0xffffffff);
1712 ut64 v1 = (op2 & 0xffffffff);
1713 ut64 t = (u1 * v1);
1714 ut64 w3 = (t & 0xffffffff);
1715 ut64 k = (t >> 32);
1716
1717 op1 >>= 32;
1718 t = (op1 * v1) + k;
1719 k = (t & 0xffffffff);
1720 ut64 w1 = (t >> 32);
1721
1722 op2 >>= 32;
1723 t = (u1 * op2) + k;
1724 k = (t >> 32);
1725
1726 *hi = (op1 * op2) + w1 + k;
1727 *lo = (t << 32) + w3;
1728 }
1729
esil_long_mul(RAnalEsil * esil)1730 static bool esil_long_mul(RAnalEsil *esil) {
1731 bool ret = false;
1732 ut64 s, d;
1733 ut64 hi, lo;
1734 char *dst = r_anal_esil_pop (esil);
1735 char *src = r_anal_esil_pop (esil);
1736 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1737 if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1738 mult64to128(s, d, &hi, &lo);
1739 r_anal_esil_pushnum (esil, hi);
1740 r_anal_esil_pushnum (esil, lo);
1741 ret = true;
1742 } else {
1743 ERR ("esil_long_mul: empty stack");
1744 }
1745 } else {
1746 ERR ("esil_long_mul: invalid parameters");
1747 }
1748 free (src);
1749 free (dst);
1750 return ret;
1751 }
1752
esil_mul(RAnalEsil * esil)1753 static bool esil_mul(RAnalEsil *esil) {
1754 bool ret = false;
1755 ut64 s, d;
1756 char *dst = r_anal_esil_pop (esil);
1757 char *src = r_anal_esil_pop (esil);
1758 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1759 if (dst && r_anal_esil_get_parm (esil, dst, &d)) {
1760 r_anal_esil_pushnum (esil, d * s);
1761 ret = true;
1762 } else {
1763 ERR ("esil_mul: empty stack");
1764 }
1765 } else {
1766 ERR ("esil_mul: invalid parameters");
1767 }
1768 free (src);
1769 free (dst);
1770 return ret;
1771 }
1772
esil_muleq(RAnalEsil * esil)1773 static bool esil_muleq(RAnalEsil *esil) {
1774 bool ret = false;
1775 ut64 s, d;
1776 char *dst = r_anal_esil_pop (esil);
1777 char *src = r_anal_esil_pop (esil);
1778 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1779 if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1780 esil->old = d;
1781 esil->cur = d * s;
1782 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1783 ret = r_anal_esil_reg_write (esil, dst, s * d);
1784 } else {
1785 ERR ("esil_muleq: empty stack");
1786 }
1787 } else {
1788 ERR ("esil_muleq: invalid parameters");
1789 }
1790 free (dst);
1791 free (src);
1792 return ret;
1793 }
1794
esil_add(RAnalEsil * esil)1795 static bool esil_add(RAnalEsil *esil) {
1796 bool ret = false;
1797 ut64 s, d;
1798 char *dst = r_anal_esil_pop (esil);
1799 char *src = r_anal_esil_pop (esil);
1800 if ((src && r_anal_esil_get_parm (esil, src, &s)) && (dst && r_anal_esil_get_parm (esil, dst, &d))) {
1801 r_anal_esil_pushnum (esil, s + d);
1802 ret = true;
1803 } else {
1804 ERR ("esil_add: invalid parameters");
1805 }
1806 free (src);
1807 free (dst);
1808 return ret;
1809 }
1810
esil_addeq(RAnalEsil * esil)1811 static bool esil_addeq(RAnalEsil *esil) {
1812 bool ret = false;
1813 ut64 s, d;
1814 char *dst = r_anal_esil_pop (esil);
1815 char *src = r_anal_esil_pop (esil);
1816 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1817 if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1818 esil->old = d;
1819 esil->cur = d + s;
1820 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1821 ret = r_anal_esil_reg_write (esil, dst, s + d);
1822 }
1823 } else {
1824 ERR ("esil_addeq: invalid parameters");
1825 }
1826 free (src);
1827 free (dst);
1828 return ret;
1829 }
1830
esil_inc(RAnalEsil * esil)1831 static bool esil_inc(RAnalEsil *esil) {
1832 bool ret = false;
1833 ut64 s;
1834 char *src = r_anal_esil_pop (esil);
1835 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1836 s++;
1837 ret = r_anal_esil_pushnum (esil, s);
1838 } else {
1839 ERR ("esil_inc: invalid parameters");
1840 }
1841 free (src);
1842 return ret;
1843 }
1844
esil_inceq(RAnalEsil * esil)1845 static bool esil_inceq(RAnalEsil *esil) {
1846 bool ret = false;
1847 ut64 sd;
1848 char *src_dst = r_anal_esil_pop (esil);
1849 if (src_dst && (r_anal_esil_get_parm_type (esil, src_dst) == R_ANAL_ESIL_PARM_REG) && r_anal_esil_get_parm (esil, src_dst, &sd)) {
1850 // inc rax
1851 esil->old = sd++;
1852 esil->cur = sd;
1853 r_anal_esil_reg_write (esil, src_dst, sd);
1854 esil->lastsz = esil_internal_sizeof_reg (esil, src_dst);
1855 ret = true;
1856 } else {
1857 ERR ("esil_inceq: invalid parameters");
1858 }
1859 free (src_dst);
1860 return ret;
1861 }
1862
esil_sub(RAnalEsil * esil)1863 static bool esil_sub(RAnalEsil *esil) {
1864 bool ret = false;
1865 ut64 s, d;
1866 char *dst = r_anal_esil_pop (esil);
1867 char *src = r_anal_esil_pop (esil);
1868 if ((src && r_anal_esil_get_parm (esil, src, &s)) && (dst && r_anal_esil_get_parm (esil, dst, &d))) {
1869 ret = r_anal_esil_pushnum (esil, d - s);
1870 } else {
1871 ERR ("esil_sub: invalid parameters");
1872 }
1873 free (src);
1874 free (dst);
1875 return ret;
1876 }
1877
esil_subeq(RAnalEsil * esil)1878 static bool esil_subeq(RAnalEsil *esil) {
1879 bool ret = false;
1880 ut64 s, d;
1881 char *dst = r_anal_esil_pop (esil);
1882 char *src = r_anal_esil_pop (esil);
1883 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1884 if (dst && r_anal_esil_reg_read (esil, dst, &d, NULL)) {
1885 esil->old = d;
1886 esil->cur = d - s;
1887 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
1888 ret = r_anal_esil_reg_write (esil, dst, d - s);
1889 }
1890 } else {
1891 ERR ("esil_subeq: invalid parameters");
1892 }
1893 free (src);
1894 free (dst);
1895 return ret;
1896 }
1897
esil_dec(RAnalEsil * esil)1898 static bool esil_dec(RAnalEsil *esil) {
1899 bool ret = false;
1900 ut64 s;
1901 char *src = r_anal_esil_pop (esil);
1902 if (src && r_anal_esil_get_parm (esil, src, &s)) {
1903 s--;
1904 ret = r_anal_esil_pushnum (esil, s);
1905 } else {
1906 ERR ("esil_dec: invalid parameters");
1907 }
1908 free (src);
1909 return ret;
1910 }
1911
esil_deceq(RAnalEsil * esil)1912 static bool esil_deceq(RAnalEsil *esil) {
1913 bool ret = false;
1914 ut64 sd;
1915 char *src_dst = r_anal_esil_pop (esil);
1916 if (src_dst && (r_anal_esil_get_parm_type (esil, src_dst) == R_ANAL_ESIL_PARM_REG) && r_anal_esil_get_parm (esil, src_dst, &sd)) {
1917 esil->old = sd;
1918 sd--;
1919 esil->cur = sd;
1920 r_anal_esil_reg_write (esil, src_dst, sd);
1921 esil->lastsz = esil_internal_sizeof_reg (esil, src_dst);
1922 ret = true;
1923 } else {
1924 ERR ("esil_deceq: invalid parameters");
1925 }
1926 free (src_dst);
1927 return ret;
1928 }
1929
1930 /* POKE */
esil_poke_n(RAnalEsil * esil,int bits)1931 static bool esil_poke_n(RAnalEsil *esil, int bits) {
1932 ut64 bitmask = genmask (bits - 1);
1933 ut64 num, num2, addr;
1934 ut8 b[8] = {0};
1935 ut64 n;
1936 char *dst = r_anal_esil_pop (esil);
1937 char *src = r_anal_esil_pop (esil);
1938 int bytes = R_MIN (sizeof (b), bits / 8);
1939 if (bits % 8) {
1940 free (src);
1941 free (dst);
1942 return false;
1943 }
1944 bool ret = false;
1945 //eprintf ("GONA POKE %d src:%s dst:%s\n", bits, src, dst);
1946 char *src2 = NULL;
1947 if (src && r_anal_esil_get_parm (esil, src, &num)) {
1948 if (dst && r_anal_esil_get_parm (esil, dst, &addr)) {
1949 if (bits == 128) {
1950 src2 = r_anal_esil_pop (esil);
1951 if (src2 && r_anal_esil_get_parm (esil, src2, &num2)) {
1952 r_write_ble (b, num, esil->anal->big_endian, 64);
1953 ret = r_anal_esil_mem_write (esil, addr, b, bytes);
1954 if (ret == 0) {
1955 r_write_ble (b, num2, esil->anal->big_endian, 64);
1956 ret = r_anal_esil_mem_write (esil, addr + 8, b, bytes);
1957 }
1958 goto out;
1959 }
1960 ret = 0;
1961 goto out;
1962 }
1963 // this is a internal peek performed before a poke
1964 // we disable hooks to avoid run hooks on internal peeks
1965 void * oldhook = (void*)esil->cb.hook_mem_read;
1966 esil->cb.hook_mem_read = NULL;
1967 r_anal_esil_mem_read (esil, addr, b, bytes);
1968 esil->cb.hook_mem_read = oldhook;
1969 n = r_read_ble64 (b, esil->anal->big_endian);
1970 esil->old = n;
1971 esil->cur = num;
1972 esil->lastsz = bits;
1973 num = num & bitmask;
1974 r_write_ble (b, num, esil->anal->big_endian, bits);
1975 ret = r_anal_esil_mem_write (esil, addr, b, bytes);
1976 }
1977 }
1978 out:
1979 free (src2);
1980 free (src);
1981 free (dst);
1982 return ret;
1983 }
1984
esil_poke1(RAnalEsil * esil)1985 static bool esil_poke1(RAnalEsil *esil) {
1986 return esil_poke_n (esil, 8);
1987 }
1988
esil_poke2(RAnalEsil * esil)1989 static bool esil_poke2(RAnalEsil *esil) {
1990 return esil_poke_n (esil, 16);
1991 }
1992
esil_poke3(RAnalEsil * esil)1993 static bool esil_poke3(RAnalEsil *esil) {
1994 return esil_poke_n (esil, 24);
1995 }
1996
esil_poke4(RAnalEsil * esil)1997 static bool esil_poke4(RAnalEsil *esil) {
1998 return esil_poke_n (esil, 32);
1999 }
2000
esil_poke8(RAnalEsil * esil)2001 static bool esil_poke8(RAnalEsil *esil) {
2002 return esil_poke_n (esil, 64);
2003 }
2004
esil_poke16(RAnalEsil * esil)2005 static bool esil_poke16(RAnalEsil *esil) {
2006 return esil_poke_n (esil, 128);
2007 }
2008
esil_poke(RAnalEsil * esil)2009 static bool esil_poke(RAnalEsil *esil) {
2010 return esil_poke_n (esil, esil->anal->bits);
2011 }
2012
esil_poke_some(RAnalEsil * esil)2013 static bool esil_poke_some(RAnalEsil *esil) {
2014 bool ret = false;
2015 int i, regsize;
2016 ut64 ptr, regs = 0, tmp;
2017 char *count, *dst = r_anal_esil_pop (esil);
2018
2019 if (dst && r_anal_esil_get_parm_size (esil, dst, &tmp, ®size)) {
2020 // reg
2021 isregornum (esil, dst, &ptr);
2022 count = r_anal_esil_pop (esil);
2023 if (count) {
2024 isregornum (esil, count, ®s);
2025 if (regs > 0) {
2026 ut8 b[8] = {0};
2027 ut64 num64;
2028 for (i = 0; i < regs; i++) {
2029 char *foo = r_anal_esil_pop (esil);
2030 if (!foo) {
2031 // avoid looping out of stack
2032 free (dst);
2033 free (count);
2034 return true;
2035 }
2036 r_anal_esil_get_parm_size (esil, foo, &tmp, ®size);
2037 isregornum (esil, foo, &num64);
2038 r_write_ble (b, num64, esil->anal->big_endian, regsize);
2039 const int size_bytes = regsize / 8;
2040 const ut32 written = r_anal_esil_mem_write (esil, ptr, b, size_bytes);
2041 if (written != size_bytes) {
2042 //eprintf ("Cannot write at 0x%08" PFMT64x "\n", ptr);
2043 esil->trap = 1;
2044 }
2045 ptr += size_bytes;
2046 free (foo);
2047 }
2048 }
2049 free (dst);
2050 free (count);
2051 return ret;
2052 }
2053 free (dst);
2054 }
2055 return false;
2056 }
2057
2058 /* PEEK */
2059
esil_peek_n(RAnalEsil * esil,int bits)2060 static bool esil_peek_n(RAnalEsil *esil, int bits) {
2061 if (bits & 7) {
2062 return false;
2063 }
2064 bool ret = false;
2065 char res[32];
2066 ut64 addr;
2067 ut32 bytes = bits / 8;
2068 char *dst = r_anal_esil_pop (esil);
2069 if (!dst) {
2070 eprintf ("ESIL-ERROR at 0x%08"PFMT64x": Cannot peek memory without specifying an address\n", esil->address);
2071 return false;
2072 }
2073 //eprintf ("GONA PEEK %d dst:%s\n", bits, dst);
2074 if (dst && isregornum (esil, dst, &addr)) {
2075 if (bits == 128) {
2076 ut8 a[sizeof(ut64) * 2] = {0};
2077 ret = r_anal_esil_mem_read (esil, addr, a, bytes);
2078 ut64 b = r_read_ble64 (&a, 0); //esil->anal->big_endian);
2079 ut64 c = r_read_ble64 (&a[8], 0); //esil->anal->big_endian);
2080 snprintf (res, sizeof (res), "0x%" PFMT64x, b);
2081 r_anal_esil_push (esil, res);
2082 snprintf (res, sizeof (res), "0x%" PFMT64x, c);
2083 r_anal_esil_push (esil, res);
2084 free (dst);
2085 return ret;
2086 }
2087 ut64 bitmask = genmask (bits - 1);
2088 ut8 a[sizeof(ut64)] = {0};
2089 ret = !!r_anal_esil_mem_read (esil, addr, a, bytes);
2090 ut64 b = r_read_ble64 (a, 0); //esil->anal->big_endian);
2091 if (esil->anal->big_endian) {
2092 r_mem_swapendian ((ut8*)&b, (const ut8*)&b, bytes);
2093 }
2094 snprintf (res, sizeof (res), "0x%" PFMT64x, b & bitmask);
2095 r_anal_esil_push (esil, res);
2096 esil->lastsz = bits;
2097 }
2098 free (dst);
2099 return ret;
2100 }
2101
esil_peek1(RAnalEsil * esil)2102 static bool esil_peek1(RAnalEsil *esil) {
2103 return esil_peek_n (esil, 8);
2104 }
2105
esil_peek2(RAnalEsil * esil)2106 static bool esil_peek2(RAnalEsil *esil) {
2107 return esil_peek_n (esil, 16);
2108 }
2109
esil_peek3(RAnalEsil * esil)2110 static bool esil_peek3(RAnalEsil *esil) {
2111 return esil_peek_n (esil, 24);
2112 }
2113
esil_peek4(RAnalEsil * esil)2114 static bool esil_peek4(RAnalEsil *esil) {
2115 return esil_peek_n (esil, 32);
2116 }
2117
esil_peek8(RAnalEsil * esil)2118 static bool esil_peek8(RAnalEsil *esil) {
2119 return esil_peek_n (esil, 64);
2120 }
2121
esil_peek16(RAnalEsil * esil)2122 static bool esil_peek16(RAnalEsil *esil) {
2123 // packed only
2124 return esil_peek_n (esil, 128);
2125 }
2126
esil_peek(RAnalEsil * esil)2127 static bool esil_peek(RAnalEsil *esil) {
2128 return esil_peek_n (esil, esil->anal->bits);
2129 };
2130
esil_peek_some(RAnalEsil * esil)2131 static bool esil_peek_some(RAnalEsil *esil) {
2132 int i;
2133 ut64 ptr, regs;
2134 // pop ptr
2135 char *count, *dst = r_anal_esil_pop (esil);
2136 if (dst) {
2137 // reg
2138 isregornum (esil, dst, &ptr);
2139 count = r_anal_esil_pop (esil);
2140 if (count) {
2141 isregornum (esil, count, ®s);
2142 if (regs > 0) {
2143 ut32 num32;
2144 ut8 a[4];
2145 for (i = 0; i < regs; i++) {
2146 char *foo = r_anal_esil_pop (esil);
2147 if (!foo) {
2148 ERR ("Cannot pop in peek");
2149 free (dst);
2150 free (count);
2151 return 0;
2152 }
2153 const ut32 read = r_anal_esil_mem_read (esil, ptr, a, 4);
2154 if (read == 4) { //this is highly questionabla
2155 num32 = r_read_ble32 (a, esil->anal->big_endian);
2156 r_anal_esil_reg_write (esil, foo, num32);
2157 } else {
2158 if (esil->verbose) {
2159 eprintf ("Cannot peek from 0x%08" PFMT64x "\n", ptr);
2160 }
2161 }
2162 ptr += 4;
2163 free (foo);
2164 }
2165 }
2166 free (dst);
2167 free (count);
2168 return 1;
2169 }
2170 free (dst);
2171 }
2172 return 0;
2173 }
2174
2175 /* OREQ */
2176
esil_mem_oreq_n(RAnalEsil * esil,int bits)2177 static bool esil_mem_oreq_n(RAnalEsil *esil, int bits) {
2178 bool ret = false;
2179 ut64 s, d;
2180 char *dst = r_anal_esil_pop (esil); //save the dst-addr
2181 char *src0 = r_anal_esil_pop (esil); //get the src
2182 char *src1 = NULL;
2183 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) { //get the src
2184 r_anal_esil_push (esil, dst); //push the dst-addr
2185 ret = (!!esil_peek_n (esil, bits)); //read
2186 src1 = r_anal_esil_pop (esil); //get the old dst-value
2187 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) { //get the old dst-value
2188 d |= s; //calculate the new dst-value
2189 r_anal_esil_pushnum (esil, d); //push the new dst-value
2190 r_anal_esil_push (esil, dst); //push the dst-addr
2191 ret &= (!!esil_poke_n (esil, bits)); //write
2192 } else {
2193 ret = false;
2194 }
2195 }
2196 if (!ret) {
2197 ERR ("esil_mem_oreq_n: invalid parameters");
2198 }
2199 free (dst);
2200 free (src0);
2201 free (src1);
2202 return ret;
2203 }
2204
esil_mem_oreq1(RAnalEsil * esil)2205 static bool esil_mem_oreq1(RAnalEsil *esil) {
2206 return esil_mem_oreq_n (esil, 8);
2207 }
esil_mem_oreq2(RAnalEsil * esil)2208 static bool esil_mem_oreq2(RAnalEsil *esil) {
2209 return esil_mem_oreq_n (esil, 16);
2210 }
esil_mem_oreq4(RAnalEsil * esil)2211 static bool esil_mem_oreq4(RAnalEsil *esil) {
2212 return esil_mem_oreq_n (esil, 32);
2213 }
esil_mem_oreq8(RAnalEsil * esil)2214 static bool esil_mem_oreq8(RAnalEsil *esil) {
2215 return esil_mem_oreq_n (esil, 64);
2216 }
esil_mem_oreq(RAnalEsil * esil)2217 static bool esil_mem_oreq(RAnalEsil *esil) {
2218 return esil_mem_oreq_n (esil, esil->anal->bits);
2219 }
2220
2221 /* XOREQ */
2222
esil_mem_xoreq_n(RAnalEsil * esil,int bits)2223 static bool esil_mem_xoreq_n(RAnalEsil *esil, int bits) {
2224 bool ret = false;
2225 ut64 s, d;
2226 char *dst = r_anal_esil_pop (esil);
2227 char *src0 = r_anal_esil_pop (esil);
2228 char *src1 = NULL;
2229 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2230 r_anal_esil_push (esil, dst);
2231 ret = (!!esil_peek_n (esil, bits));
2232 src1 = r_anal_esil_pop (esil);
2233 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2234 d ^= s;
2235 r_anal_esil_pushnum (esil, d);
2236 r_anal_esil_push (esil, dst);
2237 ret &= (!!esil_poke_n (esil, bits));
2238 } else {
2239 ret = false;
2240 }
2241 }
2242 if (!ret) {
2243 ERR ("esil_mem_xoreq_n: invalid parameters");
2244 }
2245 free (dst);
2246 free (src0);
2247 free (src1);
2248 return ret;
2249 }
2250
esil_mem_xoreq1(RAnalEsil * esil)2251 static bool esil_mem_xoreq1(RAnalEsil *esil) {
2252 return esil_mem_xoreq_n (esil, 8);
2253 }
esil_mem_xoreq2(RAnalEsil * esil)2254 static bool esil_mem_xoreq2(RAnalEsil *esil) {
2255 return esil_mem_xoreq_n (esil, 16);
2256 }
esil_mem_xoreq4(RAnalEsil * esil)2257 static bool esil_mem_xoreq4(RAnalEsil *esil) {
2258 return esil_mem_xoreq_n (esil, 32);
2259 }
esil_mem_xoreq8(RAnalEsil * esil)2260 static bool esil_mem_xoreq8(RAnalEsil *esil) {
2261 return esil_mem_xoreq_n (esil, 64);
2262 }
esil_mem_xoreq(RAnalEsil * esil)2263 static bool esil_mem_xoreq(RAnalEsil *esil) {
2264 return esil_mem_xoreq_n (esil, esil->anal->bits);
2265 }
2266
2267 /* ANDEQ */
2268
esil_mem_andeq_n(RAnalEsil * esil,int bits)2269 static bool esil_mem_andeq_n(RAnalEsil *esil, int bits) {
2270 bool ret = false;
2271 ut64 s, d;
2272 char *dst = r_anal_esil_pop (esil);
2273 char *src0 = r_anal_esil_pop (esil);
2274 char *src1 = NULL;
2275 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2276 r_anal_esil_push (esil, dst);
2277 ret = (!!esil_peek_n (esil, bits));
2278 src1 = r_anal_esil_pop (esil);
2279 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2280 d &= s;
2281 r_anal_esil_pushnum (esil, d);
2282 r_anal_esil_push (esil, dst);
2283 ret &= (!!esil_poke_n (esil, bits));
2284 } else {
2285 ret = false;
2286 }
2287 }
2288 if (!ret) {
2289 ERR ("esil_mem_andeq_n: invalid parameters");
2290 }
2291 free (dst);
2292 free (src0);
2293 free (src1);
2294 return ret;
2295 }
2296
esil_mem_andeq1(RAnalEsil * esil)2297 static bool esil_mem_andeq1(RAnalEsil *esil) {
2298 return esil_mem_andeq_n (esil, 8);
2299 }
esil_mem_andeq2(RAnalEsil * esil)2300 static bool esil_mem_andeq2(RAnalEsil *esil) {
2301 return esil_mem_andeq_n (esil, 16);
2302 }
esil_mem_andeq4(RAnalEsil * esil)2303 static bool esil_mem_andeq4(RAnalEsil *esil) {
2304 return esil_mem_andeq_n (esil, 32);
2305 }
esil_mem_andeq8(RAnalEsil * esil)2306 static bool esil_mem_andeq8(RAnalEsil *esil) {
2307 return esil_mem_andeq_n (esil, 64);
2308 }
esil_mem_andeq(RAnalEsil * esil)2309 static bool esil_mem_andeq(RAnalEsil *esil) {
2310 return esil_mem_andeq_n (esil, esil->anal->bits);
2311 }
2312
2313 /* ADDEQ */
2314
esil_mem_addeq_n(RAnalEsil * esil,int bits)2315 static bool esil_mem_addeq_n(RAnalEsil *esil, int bits) {
2316 bool ret = false;
2317 ut64 s, d;
2318 char *dst = r_anal_esil_pop (esil);
2319 char *src0 = r_anal_esil_pop (esil);
2320 char *src1 = NULL;
2321 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2322 r_anal_esil_push (esil, dst);
2323 ret = (!!esil_peek_n (esil, bits));
2324 src1 = r_anal_esil_pop (esil);
2325 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2326 d += s;
2327 r_anal_esil_pushnum (esil, d);
2328 r_anal_esil_push (esil, dst);
2329 ret &= (!!esil_poke_n (esil, bits));
2330 } else {
2331 ret = false;
2332 }
2333 }
2334 if (!ret) {
2335 ERR ("esil_mem_addeq_n: invalid parameters");
2336 }
2337 free (dst);
2338 free (src0);
2339 free (src1);
2340 return ret;
2341 }
2342
esil_mem_addeq1(RAnalEsil * esil)2343 static bool esil_mem_addeq1(RAnalEsil *esil) {
2344 return esil_mem_addeq_n (esil, 8);
2345 }
esil_mem_addeq2(RAnalEsil * esil)2346 static bool esil_mem_addeq2(RAnalEsil *esil) {
2347 return esil_mem_addeq_n (esil, 16);
2348 }
esil_mem_addeq4(RAnalEsil * esil)2349 static bool esil_mem_addeq4(RAnalEsil *esil) {
2350 return esil_mem_addeq_n (esil, 32);
2351 }
esil_mem_addeq8(RAnalEsil * esil)2352 static bool esil_mem_addeq8(RAnalEsil *esil) {
2353 return esil_mem_addeq_n (esil, 64);
2354 }
esil_mem_addeq(RAnalEsil * esil)2355 static bool esil_mem_addeq(RAnalEsil *esil) {
2356 return esil_mem_addeq_n (esil, esil->anal->bits);
2357 }
2358
2359 /* SUBEQ */
2360
esil_mem_subeq_n(RAnalEsil * esil,int bits)2361 static bool esil_mem_subeq_n(RAnalEsil *esil, int bits) {
2362 bool ret = false;
2363 ut64 s, d;
2364 char *dst = r_anal_esil_pop (esil);
2365 char *src0 = r_anal_esil_pop (esil);
2366 char *src1 = NULL;
2367 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2368 r_anal_esil_push (esil, dst);
2369 ret = (!!esil_peek_n (esil, bits));
2370 src1 = r_anal_esil_pop (esil);
2371 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2372 d -= s;
2373 r_anal_esil_pushnum (esil, d);
2374 r_anal_esil_push (esil, dst);
2375 ret &= (!!esil_poke_n (esil, bits));
2376 } else {
2377 ret = false;
2378 }
2379 }
2380 if (!ret) {
2381 ERR ("esil_mem_subeq_n: invalid parameters");
2382 }
2383 free (dst);
2384 free (src0);
2385 free (src1);
2386 return ret;
2387 }
2388
esil_mem_subeq1(RAnalEsil * esil)2389 static bool esil_mem_subeq1(RAnalEsil *esil) {
2390 return esil_mem_subeq_n (esil, 8);
2391 }
esil_mem_subeq2(RAnalEsil * esil)2392 static bool esil_mem_subeq2(RAnalEsil *esil) {
2393 return esil_mem_subeq_n (esil, 16);
2394 }
esil_mem_subeq4(RAnalEsil * esil)2395 static bool esil_mem_subeq4(RAnalEsil *esil) {
2396 return esil_mem_subeq_n (esil, 32);
2397 }
esil_mem_subeq8(RAnalEsil * esil)2398 static bool esil_mem_subeq8(RAnalEsil *esil) {
2399 return esil_mem_subeq_n (esil, 64);
2400 }
esil_mem_subeq(RAnalEsil * esil)2401 static bool esil_mem_subeq(RAnalEsil *esil) {
2402 return esil_mem_subeq_n (esil, esil->anal->bits);
2403 }
2404
2405 /* MODEQ */
2406
esil_mem_modeq_n(RAnalEsil * esil,int bits)2407 static bool esil_mem_modeq_n(RAnalEsil *esil, int bits) {
2408 bool ret = false;
2409 ut64 s, d;
2410 char *dst = r_anal_esil_pop (esil);
2411 char *src0 = r_anal_esil_pop (esil);
2412 char *src1 = NULL;
2413 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2414 if (s == 0) {
2415 ERR ("esil_mem_modeq4: Division by zero!");
2416 esil->trap = R_ANAL_TRAP_DIVBYZERO;
2417 esil->trap_code = 0;
2418 } else {
2419 r_anal_esil_push (esil, dst);
2420 ret = (!!esil_peek_n (esil, bits));
2421 src1 = r_anal_esil_pop (esil);
2422 if (src1 && r_anal_esil_get_parm (esil, src1, &d) && s >= 1) {
2423 r_anal_esil_pushnum (esil, d % s);
2424 d = d % s;
2425 r_anal_esil_pushnum (esil, d);
2426 r_anal_esil_push (esil, dst);
2427 ret &= (!!esil_poke_n (esil, bits));
2428 } else {
2429 ret = false;
2430 }
2431 }
2432 }
2433 if (!ret) {
2434 ERR ("esil_mem_modeq_n: invalid parameters");
2435 }
2436 free (dst);
2437 free (src0);
2438 free (src1);
2439 return ret;
2440 }
2441
esil_mem_modeq1(RAnalEsil * esil)2442 static bool esil_mem_modeq1(RAnalEsil *esil) {
2443 return esil_mem_modeq_n (esil, 8);
2444 }
esil_mem_modeq2(RAnalEsil * esil)2445 static bool esil_mem_modeq2(RAnalEsil *esil) {
2446 return esil_mem_modeq_n (esil, 16);
2447 }
esil_mem_modeq4(RAnalEsil * esil)2448 static bool esil_mem_modeq4(RAnalEsil *esil) {
2449 return esil_mem_modeq_n (esil, 32);
2450 }
esil_mem_modeq8(RAnalEsil * esil)2451 static bool esil_mem_modeq8(RAnalEsil *esil) {
2452 return esil_mem_modeq_n (esil, 64);
2453 }
esil_mem_modeq(RAnalEsil * esil)2454 static bool esil_mem_modeq(RAnalEsil *esil) {
2455 return esil_mem_modeq_n (esil, esil->anal->bits);
2456 }
2457
2458 /* DIVEQ */
2459
esil_mem_diveq_n(RAnalEsil * esil,int bits)2460 static bool esil_mem_diveq_n(RAnalEsil *esil, int bits) {
2461 bool ret = false;
2462 ut64 s, d;
2463 char *dst = r_anal_esil_pop (esil);
2464 char *src0 = r_anal_esil_pop (esil);
2465 char *src1 = NULL;
2466 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2467 if (s == 0) {
2468 ERR ("esil_mem_diveq8: Division by zero!");
2469 esil->trap = R_ANAL_TRAP_DIVBYZERO;
2470 esil->trap_code = 0;
2471 } else {
2472 r_anal_esil_push (esil, dst);
2473 ret = (!!esil_peek_n (esil, bits));
2474 src1 = r_anal_esil_pop (esil);
2475 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2476 d = d / s;
2477 r_anal_esil_pushnum (esil, d);
2478 r_anal_esil_push (esil, dst);
2479 ret &= (!!esil_poke_n (esil, bits));
2480 } else {
2481 ret = false;
2482 }
2483 }
2484 }
2485 if (!ret) {
2486 ERR ("esil_mem_diveq_n: invalid parameters");
2487 }
2488 free (dst);
2489 free (src0);
2490 free (src1);
2491 return ret;
2492 }
2493
esil_mem_diveq1(RAnalEsil * esil)2494 static bool esil_mem_diveq1(RAnalEsil *esil) {
2495 return esil_mem_diveq_n (esil, 8);
2496 }
esil_mem_diveq2(RAnalEsil * esil)2497 static bool esil_mem_diveq2(RAnalEsil *esil) {
2498 return esil_mem_diveq_n (esil, 16);
2499 }
esil_mem_diveq4(RAnalEsil * esil)2500 static bool esil_mem_diveq4(RAnalEsil *esil) {
2501 return esil_mem_diveq_n (esil, 32);
2502 }
esil_mem_diveq8(RAnalEsil * esil)2503 static bool esil_mem_diveq8(RAnalEsil *esil) {
2504 return esil_mem_diveq_n (esil, 64);
2505 }
esil_mem_diveq(RAnalEsil * esil)2506 static bool esil_mem_diveq(RAnalEsil *esil) {
2507 return esil_mem_diveq_n (esil, esil->anal->bits);
2508 }
2509
2510 /* MULEQ */
2511
esil_mem_muleq_n(RAnalEsil * esil,int bits,ut64 bitmask)2512 static bool esil_mem_muleq_n(RAnalEsil *esil, int bits, ut64 bitmask) {
2513 bool ret = false;
2514 ut64 s, d;
2515 char *dst = r_anal_esil_pop (esil);
2516 char *src0 = r_anal_esil_pop (esil);
2517 char *src1 = NULL;
2518 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2519 r_anal_esil_push (esil, dst);
2520 ret = (!!esil_peek_n (esil, bits));
2521 src1 = r_anal_esil_pop (esil);
2522 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2523 d *= s;
2524 r_anal_esil_pushnum (esil, d);
2525 r_anal_esil_push (esil, dst);
2526 ret &= (!!esil_poke_n (esil, bits));
2527 } else {
2528 ret = false;
2529 }
2530 }
2531 if (!ret) {
2532 ERR ("esil_mem_muleq_n: invalid parameters");
2533 }
2534 free (dst);
2535 free (src0);
2536 free (src1);
2537 return ret;
2538 }
2539
esil_mem_muleq1(RAnalEsil * esil)2540 static bool esil_mem_muleq1(RAnalEsil *esil) {
2541 return esil_mem_muleq_n (esil, 8, UT8_MAX);
2542 }
esil_mem_muleq2(RAnalEsil * esil)2543 static bool esil_mem_muleq2(RAnalEsil *esil) {
2544 return esil_mem_muleq_n (esil, 16, UT16_MAX);
2545 }
esil_mem_muleq4(RAnalEsil * esil)2546 static bool esil_mem_muleq4(RAnalEsil *esil) {
2547 return esil_mem_muleq_n (esil, 32, UT32_MAX);
2548 }
esil_mem_muleq8(RAnalEsil * esil)2549 static bool esil_mem_muleq8(RAnalEsil *esil) {
2550 return esil_mem_muleq_n (esil, 64, UT64_MAX);
2551 }
2552
esil_mem_muleq(RAnalEsil * esil)2553 static bool esil_mem_muleq(RAnalEsil *esil) {
2554 switch (esil->anal->bits) {
2555 case 64: return esil_mem_muleq8 (esil);
2556 case 32: return esil_mem_muleq4 (esil);
2557 case 16: return esil_mem_muleq2 (esil);
2558 case 8: return esil_mem_muleq1 (esil);
2559 }
2560 return 0;
2561 }
2562
2563 /* INCEQ */
2564
esil_mem_inceq_n(RAnalEsil * esil,int bits)2565 static bool esil_mem_inceq_n(RAnalEsil *esil, int bits) {
2566 bool ret = false;
2567 ut64 s;
2568 char *off = r_anal_esil_pop (esil);
2569 char *src = NULL;
2570 if (off) {
2571 r_anal_esil_push (esil, off);
2572 ret = (!!esil_peek_n (esil, bits));
2573 src = r_anal_esil_pop (esil);
2574 if (src && r_anal_esil_get_parm (esil, src, &s)) {
2575 esil->old = s;
2576 s++;
2577 esil->cur = s;
2578 esil->lastsz = bits;
2579 r_anal_esil_pushnum (esil, s);
2580 r_anal_esil_push (esil, off);
2581 ret &= (!!esil_poke_n (esil, bits));
2582 } else {
2583 ret = false;
2584 }
2585 }
2586 if (!ret) {
2587 ERR ("esil_mem_inceq_n: invalid parameters");
2588 }
2589 free (src);
2590 free (off);
2591 return ret;
2592 }
2593
esil_mem_inceq1(RAnalEsil * esil)2594 static bool esil_mem_inceq1(RAnalEsil *esil) {
2595 return esil_mem_inceq_n (esil, 8);
2596 }
esil_mem_inceq2(RAnalEsil * esil)2597 static bool esil_mem_inceq2(RAnalEsil *esil) {
2598 return esil_mem_inceq_n (esil, 16);
2599 }
esil_mem_inceq4(RAnalEsil * esil)2600 static bool esil_mem_inceq4(RAnalEsil *esil) {
2601 return esil_mem_inceq_n (esil, 32);
2602 }
esil_mem_inceq8(RAnalEsil * esil)2603 static bool esil_mem_inceq8(RAnalEsil *esil) {
2604 return esil_mem_inceq_n (esil, 64);
2605 }
esil_mem_inceq(RAnalEsil * esil)2606 static bool esil_mem_inceq(RAnalEsil *esil) {
2607 return esil_mem_inceq_n (esil, esil->anal->bits);
2608 }
2609
2610 /* DECEQ */
2611
esil_mem_deceq_n(RAnalEsil * esil,int bits)2612 static bool esil_mem_deceq_n(RAnalEsil *esil, int bits) {
2613 bool ret = false;
2614 ut64 s;
2615 char *off = r_anal_esil_pop (esil);
2616 char *src = NULL;
2617 if (off) {
2618 r_anal_esil_push (esil, off);
2619 ret = (!!esil_peek_n (esil, bits));
2620 src = r_anal_esil_pop (esil);
2621 if (src && r_anal_esil_get_parm (esil, src, &s)) {
2622 s--;
2623 r_anal_esil_pushnum (esil, s);
2624 r_anal_esil_push (esil, off);
2625 ret &= (!!esil_poke_n (esil, bits));
2626 } else {
2627 ret = false;
2628 }
2629 }
2630 if (!ret) {
2631 ERR ("esil_mem_deceq_n: invalid parameters");
2632 }
2633 free (src);
2634 free (off);
2635 return ret;
2636 }
2637
esil_mem_deceq1(RAnalEsil * esil)2638 static bool esil_mem_deceq1(RAnalEsil *esil) {
2639 return esil_mem_deceq_n (esil, 8);
2640 }
esil_mem_deceq2(RAnalEsil * esil)2641 static bool esil_mem_deceq2(RAnalEsil *esil) {
2642 return esil_mem_deceq_n (esil, 16);
2643 }
esil_mem_deceq4(RAnalEsil * esil)2644 static bool esil_mem_deceq4(RAnalEsil *esil) {
2645 return esil_mem_deceq_n (esil, 32);
2646 }
esil_mem_deceq8(RAnalEsil * esil)2647 static bool esil_mem_deceq8(RAnalEsil *esil) {
2648 return esil_mem_deceq_n (esil, 64);
2649 }
esil_mem_deceq(RAnalEsil * esil)2650 static bool esil_mem_deceq(RAnalEsil *esil) {
2651 return esil_mem_deceq_n (esil, esil->anal->bits);
2652 }
2653
2654 /* LSLEQ */
2655
esil_mem_lsleq_n(RAnalEsil * esil,int bits)2656 static bool esil_mem_lsleq_n(RAnalEsil *esil, int bits) {
2657 bool ret = false;
2658 ut64 s, d;
2659 char *dst = r_anal_esil_pop (esil);
2660 char *src0 = r_anal_esil_pop (esil);
2661 char *src1 = NULL;
2662 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2663 if (s > sizeof (ut64) * 8) {
2664 ERR ("esil_mem_lsleq_n: shift is too big");
2665 } else {
2666 r_anal_esil_push (esil, dst);
2667 ret = (!!esil_peek_n (esil, bits));
2668 src1 = r_anal_esil_pop (esil);
2669 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2670 if (s > 63) {
2671 d = 0;
2672 } else {
2673 d <<= s;
2674 }
2675 r_anal_esil_pushnum (esil, d);
2676 r_anal_esil_push (esil, dst);
2677 ret &= (!!esil_poke_n (esil, bits));
2678 } else {
2679 ret = false;
2680 }
2681 }
2682 }
2683 if (!ret) {
2684 ERR ("esil_mem_lsleq_n: invalid parameters");
2685 }
2686 free (dst);
2687 free (src0);
2688 free (src1);
2689 return ret;
2690 }
2691
esil_mem_lsleq1(RAnalEsil * esil)2692 static bool esil_mem_lsleq1(RAnalEsil *esil) {
2693 return esil_mem_lsleq_n (esil, 8);
2694 }
esil_mem_lsleq2(RAnalEsil * esil)2695 static bool esil_mem_lsleq2(RAnalEsil *esil) {
2696 return esil_mem_lsleq_n (esil, 16);
2697 }
esil_mem_lsleq4(RAnalEsil * esil)2698 static bool esil_mem_lsleq4(RAnalEsil *esil) {
2699 return esil_mem_lsleq_n (esil, 32);
2700 }
esil_mem_lsleq8(RAnalEsil * esil)2701 static bool esil_mem_lsleq8(RAnalEsil *esil) {
2702 return esil_mem_lsleq_n (esil, 64);
2703 }
esil_mem_lsleq(RAnalEsil * esil)2704 static bool esil_mem_lsleq(RAnalEsil *esil) {
2705 return esil_mem_lsleq_n (esil, esil->anal->bits);
2706 }
2707
2708 /* LSREQ */
2709
esil_mem_lsreq_n(RAnalEsil * esil,int bits)2710 static bool esil_mem_lsreq_n(RAnalEsil *esil, int bits) {
2711 bool ret = false;
2712 ut64 s, d;
2713 char *dst = r_anal_esil_pop (esil);
2714 char *src0 = r_anal_esil_pop (esil);
2715 char *src1 = NULL;
2716 if (src0 && r_anal_esil_get_parm (esil, src0, &s)) {
2717 r_anal_esil_push (esil, dst);
2718 ret = (!!esil_peek_n (esil, bits));
2719 src1 = r_anal_esil_pop (esil);
2720 if (src1 && r_anal_esil_get_parm (esil, src1, &d)) {
2721 d >>= s;
2722 r_anal_esil_pushnum (esil, d);
2723 r_anal_esil_push (esil, dst);
2724 ret &= (!!esil_poke_n (esil, bits));
2725 } else {
2726 ret = false;
2727 }
2728 }
2729 if (!ret) {
2730 ERR ("esil_mem_lsreq_n: invalid parameters");
2731 }
2732 free (dst);
2733 free (src0);
2734 free (src1);
2735 return ret;
2736 }
2737
esil_mem_lsreq1(RAnalEsil * esil)2738 static bool esil_mem_lsreq1(RAnalEsil *esil) {
2739 return esil_mem_lsreq_n (esil, 8);
2740 }
esil_mem_lsreq2(RAnalEsil * esil)2741 static bool esil_mem_lsreq2(RAnalEsil *esil) {
2742 return esil_mem_lsreq_n (esil, 16);
2743 }
esil_mem_lsreq4(RAnalEsil * esil)2744 static bool esil_mem_lsreq4(RAnalEsil *esil) {
2745 return esil_mem_lsreq_n (esil, 32);
2746 }
esil_mem_lsreq8(RAnalEsil * esil)2747 static bool esil_mem_lsreq8(RAnalEsil *esil) {
2748 return esil_mem_lsreq_n (esil, 64);
2749 }
esil_mem_lsreq(RAnalEsil * esil)2750 static bool esil_mem_lsreq(RAnalEsil *esil) {
2751 return esil_mem_lsreq_n (esil, esil->anal->bits);
2752 }
2753
2754 /* get value of register or memory reference and push the value */
esil_num(RAnalEsil * esil)2755 static bool esil_num(RAnalEsil *esil) {
2756 char *dup_me;
2757 ut64 dup;
2758 if (!esil) {
2759 return false;
2760 }
2761 if (!(dup_me = r_anal_esil_pop (esil))) {
2762 return false;
2763 }
2764 if (!r_anal_esil_get_parm (esil, dup_me, &dup)) {
2765 free (dup_me);
2766 return false;
2767 }
2768 free (dup_me);
2769 return r_anal_esil_pushnum (esil, dup);
2770 }
2771
2772 /* duplicate the last element in the stack */
esil_dup(RAnalEsil * esil)2773 static bool esil_dup(RAnalEsil *esil) {
2774 if (!esil || !esil->stack || esil->stackptr < 1 || esil->stackptr > (esil->stacksize - 1)) {
2775 return false;
2776 }
2777 return r_anal_esil_push (esil, esil->stack[esil->stackptr-1]);
2778 }
2779
esil_swap(RAnalEsil * esil)2780 static bool esil_swap(RAnalEsil *esil) {
2781 char *tmp;
2782 if (!esil || !esil->stack || esil->stackptr < 2) {
2783 return false;
2784 }
2785 if (!esil->stack[esil->stackptr-1] || !esil->stack[esil->stackptr-2]) {
2786 return false;
2787 }
2788 tmp = esil->stack[esil->stackptr-1];
2789 esil->stack[esil->stackptr-1] = esil->stack[esil->stackptr-2];
2790 esil->stack[esil->stackptr-2] = tmp;
2791 return true;
2792 }
2793
2794 // NOTE on following comparison functions:
2795 // The push to top of the stack is based on a
2796 // signed compare (as this causes least surprise to the users).
2797 // If an unsigned comparison is necessary, one must not use the
2798 // result pushed onto the top of the stack, but rather test the flags which
2799 // are set as a result of the compare.
2800
signed_compare_gt(ut64 a,ut64 b,ut64 size)2801 static int signed_compare_gt(ut64 a, ut64 b, ut64 size) {
2802 int result;
2803 switch (size) {
2804 case 1: result = (a & 1) > (b & 1);
2805 break;
2806 case 8: result = (st8) a > (st8) b;
2807 break;
2808 case 16: result = (st16) a > (st16) b;
2809 break;
2810 case 32: result = (st32) a > (st32) b;
2811 break;
2812 case 64:
2813 default: result = (st64) a > (st64) b;
2814 break;
2815 }
2816 return result;
2817 }
2818
esil_smaller(RAnalEsil * esil)2819 static bool esil_smaller(RAnalEsil *esil) { // 'dst < src' => 'src,dst,<'
2820 ut64 num, num2;
2821 bool ret = false;
2822 char *dst = r_anal_esil_pop (esil);
2823 char *src = r_anal_esil_pop (esil);
2824 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2825 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2826 esil->old = num;
2827 esil->cur = num - num2;
2828 ret = true;
2829 if (r_reg_get (esil->anal->reg, dst, -1)) {
2830 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2831 } else if (r_reg_get (esil->anal->reg, src, -1)) {
2832 esil->lastsz = esil_internal_sizeof_reg (esil, src);
2833 } else {
2834 // default size is set to 64 as internally operands are ut64
2835 esil->lastsz = 64;
2836 }
2837 r_anal_esil_pushnum (esil, (num != num2) &
2838 !signed_compare_gt (num, num2, esil->lastsz));
2839 }
2840 }
2841 free (dst);
2842 free (src);
2843 return ret;
2844 }
2845
esil_bigger(RAnalEsil * esil)2846 static bool esil_bigger(RAnalEsil *esil) { // 'dst > src' => 'src,dst,>'
2847 ut64 num, num2;
2848 bool ret = false;
2849 char *dst = r_anal_esil_pop (esil);
2850 char *src = r_anal_esil_pop (esil);
2851 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2852 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2853 esil->old = num;
2854 esil->cur = num - num2;
2855 ret = true;
2856 if (r_reg_get (esil->anal->reg, dst, -1)) {
2857 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2858 } else if (r_reg_get (esil->anal->reg, src, -1)) {
2859 esil->lastsz = esil_internal_sizeof_reg (esil, src);
2860 } else {
2861 // default size is set to 64 as internally operands are ut64
2862 esil->lastsz = 64;
2863 }
2864 r_anal_esil_pushnum (esil, signed_compare_gt (num, num2, esil->lastsz));
2865 }
2866 }
2867 free (dst);
2868 free (src);
2869 return ret;
2870 }
2871
esil_smaller_equal(RAnalEsil * esil)2872 static bool esil_smaller_equal(RAnalEsil *esil) { // 'dst <= src' => 'src,dst,<='
2873 ut64 num, num2;
2874 bool ret = false;
2875 char *dst = r_anal_esil_pop (esil);
2876 char *src = r_anal_esil_pop (esil);
2877 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2878 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2879 esil->old = num;
2880 esil->cur = num - num2;
2881 ret = true;
2882 if (r_reg_get (esil->anal->reg, dst, -1)) {
2883 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2884 } else if (r_reg_get (esil->anal->reg, src, -1)) {
2885 esil->lastsz = esil_internal_sizeof_reg (esil, src);
2886 } else {
2887 // default size is set to 64 as internally operands are ut64
2888 esil->lastsz = 64;
2889 }
2890 r_anal_esil_pushnum (esil, !signed_compare_gt (num, num2, esil->lastsz));
2891 }
2892 }
2893 free (dst);
2894 free (src);
2895 return ret;
2896 }
2897
esil_bigger_equal(RAnalEsil * esil)2898 static bool esil_bigger_equal(RAnalEsil *esil) { // 'dst >= src' => 'src,dst,>='
2899 ut64 num, num2;
2900 bool ret = false;
2901 char *dst = r_anal_esil_pop (esil);
2902 char *src = r_anal_esil_pop (esil);
2903 if (dst && r_anal_esil_get_parm (esil, dst, &num)) {
2904 if (src && r_anal_esil_get_parm (esil, src, &num2)) {
2905 esil->old = num;
2906 esil->cur = num - num2;
2907 ret = true;
2908 if (r_reg_get (esil->anal->reg, dst, -1)) {
2909 esil->lastsz = esil_internal_sizeof_reg (esil, dst);
2910 } else if (r_reg_get (esil->anal->reg, src, -1)) {
2911 esil->lastsz = esil_internal_sizeof_reg (esil, src);
2912 } else {
2913 // default size is set to 64 as internally operands are ut64
2914 esil->lastsz = 64;
2915 }
2916 r_anal_esil_pushnum (esil, (num == num2) |
2917 signed_compare_gt (num, num2, esil->lastsz));
2918 }
2919 }
2920 free (dst);
2921 free (src);
2922 return ret;
2923 }
2924
esil_set_jump_target(RAnalEsil * esil)2925 static bool esil_set_jump_target(RAnalEsil *esil) {
2926 bool ret = false;
2927 ut64 s;
2928 char *src = r_anal_esil_pop (esil);
2929 if (src && r_anal_esil_get_parm (esil, src, &s)) {
2930 esil->jump_target = s;
2931 esil->jump_target_set = 1;
2932 ret = true;
2933 } else {
2934 R_FREE (src);
2935 ERR ("esil_set_jump_target: empty stack");
2936 }
2937 free (src);
2938 return ret;
2939 }
2940
esil_set_jump_target_set(RAnalEsil * esil)2941 static bool esil_set_jump_target_set(RAnalEsil *esil) {
2942 bool ret = false;
2943 ut64 s;
2944 char *src = r_anal_esil_pop (esil);
2945 if (src && r_anal_esil_get_parm (esil, src, &s)) {
2946 esil->jump_target_set = s;
2947 ret = true;
2948 } else {
2949 R_FREE (src);
2950 ERR ("esil_set_jump_target_set: empty stack");
2951 }
2952 free (src);
2953 return ret;
2954 }
2955
esil_set_delay_slot(RAnalEsil * esil)2956 static bool esil_set_delay_slot(RAnalEsil *esil) {
2957 bool ret = false;
2958 ut64 s;
2959 char *src = r_anal_esil_pop (esil);
2960 if (src && r_anal_esil_get_parm (esil, src, &s)) {
2961 esil->delay = s;
2962 ret = true;
2963 } else {
2964 R_FREE (src);
2965 ERR ("esil_set_delay_slot: empty stack");
2966 }
2967 free (src);
2968 return ret;
2969 }
2970
esil_get_parm_float(RAnalEsil * esil,const char * str,double * num)2971 static int esil_get_parm_float(RAnalEsil *esil, const char *str, double *num) {
2972 return r_anal_esil_get_parm(esil, str, (ut64 *)num);
2973 }
2974
esil_pushnum_float(RAnalEsil * esil,double num)2975 static bool esil_pushnum_float(RAnalEsil *esil, double num) {
2976 RNumFloat n;
2977 n.f64 = num;
2978 return r_anal_esil_pushnum(esil, n.u64);
2979 }
2980
esil_is_nan(RAnalEsil * esil)2981 static bool esil_is_nan(RAnalEsil *esil) {
2982 bool ret = false;
2983 double s;
2984 char *src = r_anal_esil_pop(esil);
2985 if (src) {
2986 if (esil_get_parm_float(esil, src, &s)) {
2987 ret = r_anal_esil_pushnum(esil, isnan(s));
2988 } else {
2989 ERR("esil_is_nan: invalid parameters.");
2990 }
2991 free(src);
2992 } else {
2993 ERR("esil_is_nan: fail to get argument from stack.");
2994 }
2995 return ret;
2996 }
2997
esil_int_to_double(RAnalEsil * esil,int sign)2998 static bool esil_int_to_double(RAnalEsil *esil, int sign) {
2999 bool ret = false;
3000 RNumFloat s;
3001 char *src = r_anal_esil_pop(esil);
3002 if (src) {
3003 if (r_anal_esil_get_parm(esil, src, &s.u64)) {
3004 if (sign) {
3005 ret = esil_pushnum_float(esil, (double)(s.s64) * 1.0);
3006 } else {
3007 ret = esil_pushnum_float(esil, (double)(s.u64) * 1.0);
3008 }
3009 } else {
3010 ERR("esil_int_to_float: invalid parameters.");
3011 }
3012 free(src);
3013 } else {
3014 ERR("esil_int_to_float: fail to get argument from stack.");
3015 }
3016 return ret;
3017 }
3018
esil_signed_to_double(RAnalEsil * esil)3019 static bool esil_signed_to_double(RAnalEsil *esil) {
3020 return esil_int_to_double(esil, 1);
3021 }
3022
esil_unsigned_to_double(RAnalEsil * esil)3023 static bool esil_unsigned_to_double(RAnalEsil *esil) {
3024 return esil_int_to_double(esil, 0);
3025 }
3026
esil_double_to_int(RAnalEsil * esil)3027 static bool esil_double_to_int(RAnalEsil *esil) {
3028 bool ret = false;
3029 RNumFloat s;
3030 char *src = r_anal_esil_pop(esil);
3031 if (src) {
3032 if (esil_get_parm_float(esil, src, &s.f64)) {
3033 if (isnan(s.f64) || isinf(s.f64)) {
3034 ERR("esil_float_to_int: nan or inf detected.");
3035 }
3036 ret = r_anal_esil_pushnum(esil, (st64)(s.f64));
3037 } else {
3038 ERR("esil_float_to_int: invalid parameters.");
3039 }
3040 free(src);
3041 } else {
3042 ERR("esil_float_to_int: fail to get argument from stack.");
3043 }
3044 return ret;
3045 }
3046
esil_double_to_float(RAnalEsil * esil)3047 static bool esil_double_to_float(RAnalEsil *esil) {
3048 bool ret = false;
3049 RNumFloat d;
3050 RNumFloat f;
3051 ut64 s = 0;
3052 char *dst = r_anal_esil_pop(esil);
3053 char *src = r_anal_esil_pop(esil);
3054
3055 if (r_anal_esil_get_parm(esil, src, &s) && esil_get_parm_float(esil, dst, &d.f64)) {
3056 if (isnan(d.f64) || isinf(d.f64)) {
3057 ret = r_anal_esil_pushnum(esil, d.u64);
3058 } else if (s == 32) {
3059 f.f32 = (float)d.f64;
3060 ret = r_anal_esil_pushnum(esil, f.u32);
3061 } else if (s == 64) {
3062 ret = r_anal_esil_pushnum(esil, d.u64);
3063 /* TODO handle 80 bit and 128 bit floats */
3064 } else {
3065 ret = r_anal_esil_pushnum(esil, d.u64);
3066 }
3067 } else {
3068 ERR("esil_float_to_float: invalid parameters.");
3069 }
3070
3071 free(dst);
3072 free(src);
3073 return ret;
3074 }
3075
esil_float_to_double(RAnalEsil * esil)3076 static bool esil_float_to_double(RAnalEsil *esil) {
3077 bool ret = false;
3078 RNumFloat d;
3079 ut64 s = 0;
3080 char *dst = r_anal_esil_pop(esil);
3081 char *src = r_anal_esil_pop(esil);
3082
3083 if (r_anal_esil_get_parm(esil, src, &s) && esil_get_parm_float(esil, dst, &d.f64)) {
3084 if (isnan(d.f64) || isinf(d.f64)) {
3085 ret = esil_pushnum_float(esil, d.f64);
3086 } else if (s == 32) {
3087 ret = esil_pushnum_float(esil, (double)d.f32);
3088 } else if (s == 64) {
3089 ret = esil_pushnum_float(esil, d.f64);
3090 /* TODO handle 80 bit and 128 bit floats */
3091 } else {
3092 ret = esil_pushnum_float(esil, d.f64);
3093 }
3094 } else {
3095 ERR("esil_float_to_float: invalid parameters.");
3096 }
3097 free(dst);
3098 free(src);
3099 return ret;
3100 }
3101
esil_float_cmp(RAnalEsil * esil)3102 static bool esil_float_cmp(RAnalEsil *esil) {
3103 bool ret = false;
3104 double s, d;
3105 char *dst = r_anal_esil_pop(esil);
3106 char *src = r_anal_esil_pop(esil);
3107
3108 if (src && dst && esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3109 if (isnan(s) || isnan(d)) {
3110 ret = r_anal_esil_pushnum(esil, 0);
3111 } else {
3112 ret = r_anal_esil_pushnum(esil, fabs(s - d) <= DBL_EPSILON);
3113 }
3114 } else {
3115 ERR("esil_float_cmp: invalid parameters.");
3116 }
3117 free(dst);
3118 free(src);
3119 return ret;
3120 }
3121
esil_float_negcmp(RAnalEsil * esil)3122 static bool esil_float_negcmp(RAnalEsil *esil) {
3123 bool ret = false;
3124 double s, d;
3125 char *dst = r_anal_esil_pop(esil);
3126 char *src = r_anal_esil_pop(esil);
3127
3128 if (src && dst && esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3129 if (isnan(s) || isnan(d)) {
3130 ret = r_anal_esil_pushnum(esil, 0);
3131 } else {
3132 ret = r_anal_esil_pushnum(esil, fabs(s - d) >= DBL_EPSILON);
3133 }
3134 } else {
3135 ERR("esil_float_negcmp: invalid parameters.");
3136 }
3137 free(dst);
3138 free(src);
3139 return ret;
3140 }
3141
esil_float_less(RAnalEsil * esil)3142 static bool esil_float_less(RAnalEsil *esil) {
3143 bool ret = false;
3144 double s, d;
3145 char *dst = r_anal_esil_pop(esil);
3146 char *src = r_anal_esil_pop(esil);
3147
3148 if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3149 if (isnan(s) || isnan(d)) {
3150 ret = r_anal_esil_pushnum(esil, 0);
3151 } else {
3152 ret = r_anal_esil_pushnum(esil, d < s);
3153 }
3154 } else {
3155 ERR("esil_float_less: invalid parameters.");
3156 }
3157 free(dst);
3158 free(src);
3159 return ret;
3160 }
3161
esil_float_lesseq(RAnalEsil * esil)3162 static bool esil_float_lesseq(RAnalEsil *esil) {
3163 bool ret = false;
3164 double s, d;
3165 char *dst = r_anal_esil_pop(esil);
3166 char *src = r_anal_esil_pop(esil);
3167
3168 if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3169 if (isnan(s) || isnan(d)) {
3170 ret = r_anal_esil_pushnum(esil, 0);
3171 } else {
3172 ret = r_anal_esil_pushnum(esil, d <= s);
3173 }
3174 } else {
3175 ERR("esil_float_lesseq: invalid parameters.");
3176 }
3177 free(dst);
3178 free(src);
3179 return ret;
3180 }
3181
esil_float_add(RAnalEsil * esil)3182 static bool esil_float_add(RAnalEsil *esil) {
3183 bool ret = false;
3184 double s, d;
3185 char *dst = r_anal_esil_pop(esil);
3186 char *src = r_anal_esil_pop(esil);
3187
3188 if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3189 if (isnan(s)) {
3190 ret = esil_pushnum_float(esil, s);
3191 } else if (isnan(d)) {
3192 ret = esil_pushnum_float(esil, d);
3193 } else {
3194 feclearexcept(FE_OVERFLOW);
3195 double tmp = s + d;
3196 (void)(tmp); // suppress unused warning
3197 int raised = fetestexcept(FE_OVERFLOW);
3198 if (raised & FE_OVERFLOW) {
3199 ret = esil_pushnum_float(esil, NAN);
3200 } else {
3201 ret = esil_pushnum_float(esil, s + d);
3202 }
3203 }
3204 } else {
3205 ERR("esil_float_add: invalid parameters.");
3206 }
3207 free(dst);
3208 free(src);
3209 return ret;
3210 }
3211
esil_float_sub(RAnalEsil * esil)3212 static bool esil_float_sub(RAnalEsil *esil) {
3213 bool ret = false;
3214 double s, d;
3215 char *dst = r_anal_esil_pop(esil);
3216 char *src = r_anal_esil_pop(esil);
3217
3218 if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3219 if (isnan(s)) {
3220 ret = esil_pushnum_float(esil, s);
3221 } else if (isnan(d)) {
3222 ret = esil_pushnum_float(esil, d);
3223 } else {
3224 feclearexcept(FE_OVERFLOW);
3225 double tmp = d - s;
3226 (void)(tmp);
3227 int raised = fetestexcept(FE_OVERFLOW);
3228 if (raised & FE_OVERFLOW) {
3229 ret = esil_pushnum_float(esil, NAN);
3230 } else {
3231 ret = esil_pushnum_float(esil, d - s);
3232 }
3233 }
3234 } else {
3235 ERR("esil_float_sub: invalid parameters.");
3236 }
3237 free(dst);
3238 free(src);
3239 return ret;
3240 }
3241
esil_float_mul(RAnalEsil * esil)3242 static bool esil_float_mul(RAnalEsil *esil) {
3243 bool ret = false;
3244 double s, d;
3245 char *dst = r_anal_esil_pop(esil);
3246 char *src = r_anal_esil_pop(esil);
3247
3248 if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3249 if (isnan(s)) {
3250 ret = esil_pushnum_float(esil, s);
3251 } else if (isnan(d)) {
3252 ret = esil_pushnum_float(esil, d);
3253 } else {
3254 feclearexcept(FE_OVERFLOW);
3255 double tmp = s * d;
3256 (void)(tmp);
3257 int raised = fetestexcept(FE_OVERFLOW);
3258 if (raised & FE_OVERFLOW) {
3259 ret = esil_pushnum_float(esil, NAN);
3260 } else {
3261 ret = esil_pushnum_float(esil, s * d);
3262 }
3263 }
3264 } else {
3265 ERR("esil_float_mul: invalid parameters.");
3266 }
3267 free(dst);
3268 free(src);
3269 return ret;
3270 }
3271
esil_float_div(RAnalEsil * esil)3272 static bool esil_float_div(RAnalEsil *esil) {
3273 bool ret = false;
3274 double s, d;
3275 char *dst = r_anal_esil_pop(esil);
3276 char *src = r_anal_esil_pop(esil);
3277
3278 if (esil_get_parm_float(esil, src, &s) && esil_get_parm_float(esil, dst, &d)) {
3279 if (isnan(s)) {
3280 ret = esil_pushnum_float(esil, s);
3281 } else if (isnan(d)) {
3282 ret = esil_pushnum_float(esil, d);
3283 } else {
3284 feclearexcept(FE_OVERFLOW);
3285 double tmp = d / s;
3286 (void)(tmp);
3287 int raised = fetestexcept(FE_OVERFLOW);
3288 if (raised & FE_OVERFLOW) {
3289 ret = esil_pushnum_float(esil, NAN);
3290 } else {
3291 ret = esil_pushnum_float(esil, d / s);
3292 }
3293 }
3294 } else {
3295 ERR("esil_float_div: invalid parameters.");
3296 }
3297 free(dst);
3298 free(src);
3299 return ret;
3300 }
3301
esil_float_neg(RAnalEsil * esil)3302 static bool esil_float_neg(RAnalEsil *esil) {
3303 bool ret = false;
3304 double s;
3305 char *src = r_anal_esil_pop(esil);
3306
3307 if (src) {
3308 if (esil_get_parm_float(esil, src, &s)) {
3309 ret = esil_pushnum_float(esil, -s);
3310 } else {
3311 ERR("esil_float_neg: invalid parameters.");
3312 }
3313 free(src);
3314 } else {
3315 ERR("esil_float_neg: fail to get element from stack.");
3316 }
3317 return ret;
3318 }
3319
esil_float_ceil(RAnalEsil * esil)3320 static bool esil_float_ceil(RAnalEsil *esil) {
3321 bool ret = false;
3322 double s;
3323 char *src = r_anal_esil_pop(esil);
3324
3325 if (src) {
3326 if (esil_get_parm_float(esil, src, &s)) {
3327 if (isnan(s)) {
3328 ret = esil_pushnum_float(esil, s);
3329 } else {
3330 ret = esil_pushnum_float(esil, ceil(s));
3331 }
3332 } else {
3333 ERR("esil_float_ceil: invalid parameters.");
3334 }
3335 free(src);
3336 } else {
3337 ERR("esil_float_ceil: fail to get element from stack.");
3338 }
3339 return ret;
3340 }
3341
esil_float_floor(RAnalEsil * esil)3342 static bool esil_float_floor(RAnalEsil *esil) {
3343 bool ret = false;
3344 double s;
3345 char *src = r_anal_esil_pop(esil);
3346
3347 if (src) {
3348 if (esil_get_parm_float(esil, src, &s)) {
3349 if (isnan(s)) {
3350 ret = esil_pushnum_float(esil, s);
3351 } else {
3352 ret = esil_pushnum_float(esil, floor(s));
3353 }
3354 } else {
3355 ERR("esil_float_floor: invalid parameters.");
3356 }
3357 free(src);
3358 } else {
3359 ERR("esil_float_floor: fail to get element from stack.");
3360 }
3361
3362 return ret;
3363 }
3364
esil_float_round(RAnalEsil * esil)3365 static bool esil_float_round(RAnalEsil *esil) {
3366 bool ret = false;
3367 double s;
3368 char *src = r_anal_esil_pop(esil);
3369
3370 if (src) {
3371 if (esil_get_parm_float(esil, src, &s)) {
3372 if (isnan(s)) {
3373 ret = esil_pushnum_float(esil, s);
3374 } else {
3375 ret = esil_pushnum_float(esil, round(s));
3376 }
3377 } else {
3378 ERR("esil_float_round: invalid parameters.");
3379 }
3380 free(src);
3381 } else {
3382 ERR("esil_float_round: fail to get element from stack.");
3383 }
3384 return ret;
3385 }
3386
esil_float_sqrt(RAnalEsil * esil)3387 static bool esil_float_sqrt(RAnalEsil *esil) {
3388 bool ret = false;
3389 double s;
3390 char *src = r_anal_esil_pop(esil);
3391
3392 if (src) {
3393 if (esil_get_parm_float(esil, src, &s)) {
3394 if (isnan(s)) {
3395 ret = esil_pushnum_float(esil, s);
3396 } else {
3397 ret = esil_pushnum_float(esil, sqrt(s));
3398 }
3399 } else {
3400 ERR("esil_float_sqrt: invalid parameters.");
3401 }
3402 free(src);
3403 } else {
3404 ERR("esil_float_sqrt: fail to get element from stack.");
3405 }
3406 return ret;
3407 }
3408
iscommand(RAnalEsil * esil,const char * word,RAnalEsilOp ** op)3409 static bool iscommand(RAnalEsil *esil, const char *word, RAnalEsilOp **op) {
3410 RAnalEsilOp *eop = ht_pp_find (esil->ops, word, NULL);
3411 if (eop) {
3412 *op = eop;
3413 return true;
3414 }
3415 return false;
3416 }
3417
runword(RAnalEsil * esil,const char * word)3418 static bool runword(RAnalEsil *esil, const char *word) {
3419 RAnalEsilOp *op = NULL;
3420 if (!word) {
3421 return false;
3422 }
3423 esil->parse_goto_count--;
3424 if (esil->parse_goto_count < 1) {
3425 ERR ("ESIL infinite loop detected\n");
3426 esil->trap = 1; // INTERNAL ERROR
3427 esil->parse_stop = 1; // INTERNAL ERROR
3428 return false;
3429 }
3430
3431 // Don't push anything onto stack when processing if statements
3432 if (!strcmp (word, "?{") && esil->Reil) {
3433 esil->Reil->skip = esil->Reil->skip? 0: 1;
3434 if (esil->Reil->skip) {
3435 esil->Reil->cmd_count = 0;
3436 memset (esil->Reil->if_buf, 0, sizeof (esil->Reil->if_buf));
3437 }
3438 }
3439
3440 if (esil->Reil && esil->Reil->skip) {
3441 char *if_buf = esil->Reil->if_buf;
3442 size_t n = strlen (if_buf);
3443 snprintf (if_buf + n, sizeof (esil->Reil->if_buf) - n, "%s,", word);
3444 if (!strcmp (word, "}")) {
3445 r_anal_esil_pushnum (esil, esil->Reil->addr + esil->Reil->cmd_count + 1);
3446 r_anal_esil_parse (esil, esil->Reil->if_buf);
3447 } else if (iscommand (esil, word, &op)) {
3448 esil->Reil->cmd_count++;
3449 }
3450 return true;
3451 }
3452
3453 //eprintf ("WORD (%d) (%s)\n", esil->skip, word);
3454 if (!strcmp (word, "}{")) {
3455 if (esil->skip == 1) {
3456 esil->skip = 0;
3457 } else if (esil->skip == 0) { //this isn't perfect, but should work for valid esil
3458 esil->skip = 1;
3459 }
3460 return true;
3461 }
3462 if (!strcmp (word, "}")) {
3463 if (esil->skip) {
3464 esil->skip--;
3465 }
3466 return true;
3467 }
3468 if (esil->skip && strcmp(word, "?{")) {
3469 return true;
3470 }
3471
3472 if (iscommand (esil, word, &op)) {
3473 // run action
3474 if (op) {
3475 if (esil->cb.hook_command) {
3476 if (esil->cb.hook_command (esil, word)) {
3477 return 1; // XXX cannot return != 1
3478 }
3479 }
3480 esil->current_opstr = strdup (word);
3481 //so this is basically just sharing what's the operation with the operation
3482 //useful for wrappers
3483 const bool ret = op->code (esil);
3484 free (esil->current_opstr);
3485 esil->current_opstr = NULL;
3486 if (!ret) {
3487 if (esil->verbose) {
3488 eprintf ("%s returned 0\n", word);
3489 }
3490 }
3491 return ret;
3492 }
3493 }
3494 if (!*word || *word == ',') {
3495 // skip empty words
3496 return true;
3497 }
3498
3499 // push value
3500 if (!r_anal_esil_push (esil, word)) {
3501 ERR ("ESIL stack is full");
3502 esil->trap = 1;
3503 esil->trap_code = 1;
3504 }
3505 return true;
3506 }
3507
gotoWord(const char * str,int n)3508 static const char *gotoWord(const char *str, int n) {
3509 const char *ostr = str;
3510 int count = 0;
3511 while (*str) {
3512 if (count == n) {
3513 return ostr;
3514 }
3515 str++;
3516 if (*str == ',') {
3517 ostr = str + 1;
3518 count++;
3519 }
3520 }
3521 return NULL;
3522 }
3523
3524 /** evaluate an esil word and return the action to perform
3525 * TODO: Use `enum` here
3526 * 0: continue running the
3527 * 1: stop execution
3528 * 2: continue in loop
3529 * 3: normal continuation
3530 */
evalWord(RAnalEsil * esil,const char * ostr,const char ** str)3531 static int evalWord(RAnalEsil *esil, const char *ostr, const char **str) {
3532 r_return_val_if_fail (esil && str, 0);
3533 if (!*str) {
3534 return 0;
3535 }
3536 if ((*str)[0] && (*str)[1] == ',') {
3537 return 2;
3538 }
3539 if (esil->repeat) {
3540 return 0;
3541 }
3542 if (esil->parse_goto != -1) {
3543 // TODO: detect infinite loop??? how??
3544 *str = gotoWord (ostr, esil->parse_goto);
3545 if (*str) {
3546 esil->parse_goto = -1;
3547 return 2;
3548 }
3549 if (esil->verbose) {
3550 eprintf ("Cannot find word %d\n", esil->parse_goto);
3551 }
3552 return 1;
3553 }
3554 if (esil->parse_stop) {
3555 if (esil->parse_stop == 2) {
3556 eprintf ("[esil at 0x%08"PFMT64x"] TODO: %s\n", esil->address, *str + 1);
3557 }
3558 return 1;
3559 }
3560 return 3;
3561 }
3562
__stepOut(RAnalEsil * esil,const char * cmd)3563 static bool __stepOut(RAnalEsil *esil, const char *cmd) {
3564 static bool inCmdStep = false;
3565 if (cmd && esil && esil->cmd && !inCmdStep) {
3566 inCmdStep = true;
3567 if (esil->cmd (esil, cmd, esil->address, 0)) {
3568 inCmdStep = false;
3569 // if returns 1 we skip the impl
3570 return true;
3571 }
3572 inCmdStep = false;
3573 }
3574 return false;
3575 }
3576
r_anal_esil_parse(RAnalEsil * esil,const char * str)3577 R_API bool r_anal_esil_parse(RAnalEsil *esil, const char *str) {
3578 int wordi = 0;
3579 int dorunword;
3580 char word[64];
3581 const char *ostr = str;
3582 r_return_val_if_fail (esil && R_STR_ISNOTEMPTY (str), 0);
3583
3584 if (__stepOut (esil, esil->cmd_step)) {
3585 (void)__stepOut (esil, esil->cmd_step_out);
3586 return true;
3587 }
3588 const char *hashbang = strstr (str, "#!");
3589 esil->trap = 0;
3590 if (esil->cmd && esil->cmd_todo) {
3591 if (!strncmp (str, "TODO", 4)) {
3592 esil->cmd (esil, esil->cmd_todo, esil->address, 0);
3593 }
3594 }
3595 loop:
3596 esil->repeat = 0;
3597 esil->skip = 0;
3598 esil->parse_goto = -1;
3599 esil->parse_stop = 0;
3600 // memleak or failing aetr test. wat du
3601 // r_anal_esil_stack_free (esil);
3602 esil->parse_goto_count = esil->anal? esil->anal->esil_goto_limit: R_ANAL_ESIL_GOTO_LIMIT;
3603 str = ostr;
3604 repeat:
3605 wordi = 0;
3606 while (*str) {
3607 if (str == hashbang) {
3608 if (esil->anal && esil->anal->coreb.setab) {
3609 esil->anal->coreb.cmd (esil->anal->coreb.core, str + 2);
3610 }
3611 break;
3612 }
3613 if (wordi > 62) {
3614 ERR ("Invalid esil string");
3615 __stepOut (esil, esil->cmd_step_out);
3616 return -1;
3617 }
3618 dorunword = 0;
3619 if (*str == ';') {
3620 word[wordi] = 0;
3621 dorunword = 1;
3622 }
3623 if (*str == ',') {
3624 word[wordi] = 0;
3625 dorunword = 2;
3626 }
3627 if (dorunword) {
3628 if (*word) {
3629 if (!runword (esil, word)) {
3630 __stepOut (esil, esil->cmd_step_out);
3631 return 0;
3632 }
3633 word[wordi] = ',';
3634 wordi = 0;
3635 switch (evalWord (esil, ostr, &str)) {
3636 case 0: goto loop;
3637 case 1:
3638 __stepOut (esil, esil->cmd_step_out);
3639 return 0;
3640 case 2: continue;
3641 }
3642 if (dorunword == 1) {
3643 __stepOut (esil, esil->cmd_step_out);
3644 return 0;
3645 }
3646 }
3647 str++;
3648 }
3649 word[wordi++] = *str;
3650 //is *str is '\0' in the next iteration the condition will be true
3651 //reading beyond the boundaries
3652 if (*str) {
3653 str++;
3654 }
3655 }
3656 word[wordi] = 0;
3657 if (*word) {
3658 if (!runword (esil, word)) {
3659 __stepOut (esil, esil->cmd_step_out);
3660 return 0;
3661 }
3662 switch (evalWord (esil, ostr, &str)) {
3663 case 0: goto loop;
3664 case 1: __stepOut (esil, esil->cmd_step_out);
3665 return 0;
3666 case 2: goto repeat;
3667 }
3668 }
3669 __stepOut (esil, esil->cmd_step_out);
3670 return 1;
3671 }
3672
r_anal_esil_runword(RAnalEsil * esil,const char * word)3673 R_API bool r_anal_esil_runword(RAnalEsil *esil, const char *word) {
3674 const char *str = NULL;
3675 (void)runword (esil, word);
3676 if (*word) {
3677 if (!runword (esil, word)) {
3678 return false;
3679 }
3680 int ew = evalWord (esil, word, &str);
3681 eprintf ("ew %d\n", ew);
3682 eprintf ("--> %s\n", r_str_getf (str));
3683 }
3684 return true;
3685 }
3686
3687 //frees all elements from the stack, not the stack itself
3688 //rename to stack_empty() ?
r_anal_esil_stack_free(RAnalEsil * esil)3689 R_API void r_anal_esil_stack_free(RAnalEsil *esil) {
3690 int i;
3691 if (esil) {
3692 for (i = 0; i < esil->stackptr; i++) {
3693 R_FREE (esil->stack[i]);
3694 }
3695 esil->stackptr = 0;
3696 }
3697 }
3698
r_anal_esil_condition(RAnalEsil * esil,const char * str)3699 R_API int r_anal_esil_condition(RAnalEsil *esil, const char *str) {
3700 char *popped;
3701 int ret;
3702 if (!esil) {
3703 return false;
3704 }
3705 while (*str == ' ') {
3706 str++; // use proper string chop?
3707 }
3708 (void) r_anal_esil_parse (esil, str);
3709 popped = r_anal_esil_pop (esil);
3710 if (popped) {
3711 ut64 num;
3712 if (isregornum (esil, popped, &num)) {
3713 ret = !!num;
3714 } else {
3715 ret = 0;
3716 }
3717 free (popped);
3718 } else {
3719 eprintf ("Warning: Cannot pop because The ESIL stack is empty");
3720 return -1;
3721 }
3722 return ret;
3723 }
3724
r_anal_esil_setup_ops(RAnalEsil * esil)3725 static void r_anal_esil_setup_ops(RAnalEsil *esil) {
3726 #define OP(v, w, x, y, z) r_anal_esil_set_op (esil, v, w, x, y, z)
3727 #define OT_UNK R_ANAL_ESIL_OP_TYPE_UNKNOWN
3728 #define OT_CTR R_ANAL_ESIL_OP_TYPE_CONTROL_FLOW
3729 #define OT_MATH R_ANAL_ESIL_OP_TYPE_MATH
3730 #define OT_REGW R_ANAL_ESIL_OP_TYPE_REG_WRITE
3731 #define OT_MEMW R_ANAL_ESIL_OP_TYPE_MEM_WRITE
3732 #define OT_MEMR R_ANAL_ESIL_OP_TYPE_MEM_READ
3733
3734 OP ("$", esil_interrupt, 0, 1, OT_UNK); //hm, type seems a bit wrong
3735 OP ("()", esil_syscall, 0, 1, OT_UNK); //same
3736 OP ("$z", esil_zf, 1, 0, OT_UNK);
3737 OP ("$c", esil_cf, 1, 1, OT_UNK);
3738 OP ("$b", esil_bf, 1, 1, OT_UNK);
3739 OP ("$p", esil_pf, 1, 0, OT_UNK);
3740 OP ("$s", esil_sf, 1, 1, OT_UNK);
3741 OP ("$o", esil_of, 1, 1, OT_UNK);
3742 OP ("$ds", esil_ds, 1, 0, OT_UNK);
3743 OP ("$jt", esil_jt, 1, 0, OT_UNK);
3744 OP ("$js", esil_js, 1, 0, OT_UNK);
3745 OP ("$r", esil_rs, 1, 0, OT_UNK);
3746 OP ("$$", esil_address, 1, 0, OT_UNK);
3747 OP ("~", esil_signext, 1, 2, OT_MATH);
3748 OP ("~=", esil_signexteq, 0, 2, OT_MATH);
3749 OP ("==", esil_cmp, 0, 2, OT_MATH);
3750 OP ("<", esil_smaller, 1, 2, OT_MATH);
3751 OP (">", esil_bigger, 1, 2, OT_MATH);
3752 OP ("<=", esil_smaller_equal, 1, 2, OT_MATH);
3753 OP (">=", esil_bigger_equal, 1, 2, OT_MATH);
3754 OP ("?{", esil_if, 0, 1, OT_CTR);
3755 OP ("<<", esil_lsl, 1, 2, OT_MATH);
3756 OP ("<<=", esil_lsleq, 0, 2, OT_MATH | OT_REGW);
3757 OP (">>", esil_lsr, 1, 2, OT_MATH);
3758 OP (">>=", esil_lsreq, 0, 2, OT_MATH | OT_REGW);
3759 OP (">>>>", esil_asr, 1, 2, OT_MATH);
3760 OP (">>>>=", esil_asreq, 0, 2, OT_MATH | OT_REGW);
3761 OP (">>>", esil_ror, 1, 2, OT_MATH);
3762 OP ("<<<", esil_rol, 1, 2, OT_MATH);
3763 OP ("&", esil_and, 1, 2, OT_MATH);
3764 OP ("&=", esil_andeq, 0, 2, OT_MATH | OT_REGW);
3765 OP ("}", esil_nop, 0, 0, OT_CTR); // just to avoid push
3766 OP ("}{", esil_nop, 0, 0, OT_CTR);
3767 OP ("|", esil_or, 1, 2, OT_MATH);
3768 OP ("|=", esil_oreq, 0, 2, OT_MATH | OT_REGW);
3769 OP ("!", esil_neg, 1, 1, OT_MATH);
3770 OP ("!=", esil_negeq, 0, 1, OT_MATH | OT_REGW);
3771 OP ("=", esil_eq, 0, 2, OT_REGW);
3772 OP (":=", esil_weak_eq, 0, 2, OT_REGW);
3773 OP ("L*", esil_long_mul, 2, 2, OT_MATH);
3774 OP ("*", esil_mul, 1, 2, OT_MATH);
3775 OP ("*=", esil_muleq, 0, 2, OT_MATH | OT_REGW);
3776 OP ("^", esil_xor, 1, 2, OT_MATH);
3777 OP ("^=", esil_xoreq, 0, 2, OT_MATH | OT_REGW);
3778 OP ("+", esil_add, 1, 2, OT_MATH);
3779 OP ("+=", esil_addeq, 0, 2, OT_MATH | OT_REGW);
3780 OP ("++", esil_inc, 1, 1, OT_MATH);
3781 OP ("++=", esil_inceq, 0, 1, OT_MATH | OT_REGW);
3782 OP ("-", esil_sub, 1, 2, OT_MATH);
3783 OP ("-=", esil_subeq, 0, 2, OT_MATH | OT_REGW);
3784 OP ("--", esil_dec, 1, 1, OT_MATH);
3785 OP ("--=", esil_deceq, 0, 1, OT_MATH | OT_REGW);
3786 OP ("/", esil_div, 1, 2, OT_MATH);
3787 OP ("~/", esil_signed_div, 1, 2, OT_MATH);
3788 OP ("/=", esil_diveq, 0, 2, OT_MATH | OT_REGW);
3789 OP ("%", esil_mod, 1, 2, OT_MATH);
3790 OP ("~%", esil_signed_mod, 1, 2, OT_MATH);
3791 OP ("%=", esil_modeq, 0, 2, OT_MATH | OT_REGW);
3792 OP ("=[]", esil_poke, 0, 2, OT_MEMW);
3793 OP ("=[1]", esil_poke1, 0, 2, OT_MEMW);
3794 OP ("=[2]", esil_poke2, 0, 2, OT_MEMW);
3795 OP ("=[3]", esil_poke3, 0, 2, OT_MEMW);
3796 OP ("=[4]", esil_poke4, 0, 2, OT_MEMW);
3797 OP ("=[8]", esil_poke8, 0, 2, OT_MEMW);
3798 OP ("=[16]", esil_poke16, 0, 2, OT_MEMW);
3799 OP ("|=[]", esil_mem_oreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3800 OP ("|=[1]", esil_mem_oreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3801 OP ("|=[2]", esil_mem_oreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3802 OP ("|=[4]", esil_mem_oreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3803 OP ("|=[8]", esil_mem_oreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3804 OP ("^=[]", esil_mem_xoreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3805 OP ("^=[1]", esil_mem_xoreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3806 OP ("^=[2]", esil_mem_xoreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3807 OP ("^=[4]", esil_mem_xoreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3808 OP ("^=[8]", esil_mem_xoreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3809 OP ("&=[]", esil_mem_andeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3810 OP ("&=[1]", esil_mem_andeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3811 OP ("&=[2]", esil_mem_andeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3812 OP ("&=[4]", esil_mem_andeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3813 OP ("&=[8]", esil_mem_andeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3814 OP ("+=[]", esil_mem_addeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3815 OP ("+=[1]", esil_mem_addeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3816 OP ("+=[2]", esil_mem_addeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3817 OP ("+=[4]", esil_mem_addeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3818 OP ("+=[8]", esil_mem_addeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3819 OP ("-=[]", esil_mem_subeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3820 OP ("-=[1]", esil_mem_subeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3821 OP ("-=[2]", esil_mem_subeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3822 OP ("-=[4]", esil_mem_subeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3823 OP ("-=[8]", esil_mem_subeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3824 OP ("%=[]", esil_mem_modeq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3825 OP ("%=[1]", esil_mem_modeq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3826 OP ("%=[2]", esil_mem_modeq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3827 OP ("%=[4]", esil_mem_modeq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3828 OP ("%=[8]", esil_mem_modeq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3829 OP ("/=[]", esil_mem_diveq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3830 OP ("/=[1]", esil_mem_diveq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3831 OP ("/=[2]", esil_mem_diveq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3832 OP ("/=[4]", esil_mem_diveq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3833 OP ("/=[8]", esil_mem_diveq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3834 OP ("*=[]", esil_mem_muleq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3835 OP ("*=[1]", esil_mem_muleq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3836 OP ("*=[2]", esil_mem_muleq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3837 OP ("*=[4]", esil_mem_muleq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3838 OP ("*=[8]", esil_mem_muleq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3839 OP ("++=[]", esil_mem_inceq, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3840 OP ("++=[1]", esil_mem_inceq1, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3841 OP ("++=[2]", esil_mem_inceq2, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3842 OP ("++=[4]", esil_mem_inceq4, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3843 OP ("++=[8]", esil_mem_inceq8, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3844 OP ("--=[]", esil_mem_deceq, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3845 OP ("--=[1]", esil_mem_deceq1, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3846 OP ("--=[2]", esil_mem_deceq2, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3847 OP ("--=[4]", esil_mem_deceq4, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3848 OP ("--=[8]", esil_mem_deceq8, 0, 1, OT_MATH | OT_MEMR | OT_MEMW);
3849 OP ("<<=[]", esil_mem_lsleq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3850 OP ("<<=[1]", esil_mem_lsleq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3851 OP ("<<=[2]", esil_mem_lsleq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3852 OP ("<<=[4]", esil_mem_lsleq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3853 OP ("<<=[8]", esil_mem_lsleq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3854 OP (">>=[]", esil_mem_lsreq, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3855 OP (">>=[1]", esil_mem_lsreq1, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3856 OP (">>=[2]", esil_mem_lsreq2, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3857 OP (">>=[4]", esil_mem_lsreq4, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3858 OP (">>=[8]", esil_mem_lsreq8, 0, 2, OT_MATH | OT_MEMR | OT_MEMW);
3859 OP ("[]", esil_peek, 1, 1, OT_MEMR);
3860 OP ("[*]", esil_peek_some, 0, 0, OT_MEMR);
3861 OP ("=[*]", esil_poke_some, 0, 0, OT_MEMW);
3862 OP ("[1]", esil_peek1, 1, 1, OT_MEMR);
3863 OP ("[2]", esil_peek2, 1, 1, OT_MEMR);
3864 OP ("[3]", esil_peek3, 1, 1, OT_MEMR);
3865 OP ("[4]", esil_peek4, 1, 1, OT_MEMR);
3866 OP ("[8]", esil_peek8, 1, 1, OT_MEMR);
3867 OP ("[16]", esil_peek16, 1, 1, OT_MEMR);
3868 OP ("STACK", r_anal_esil_dumpstack, 0, 0, OT_UNK);
3869 OP ("REPEAT", esil_repeat, 0, 2, OT_CTR);
3870 OP ("POP", esil_pop, 0, 1, OT_UNK);
3871 OP ("TODO", esil_todo, 0, 0, OT_UNK);
3872 OP ("GOTO", esil_goto, 0, 1, OT_CTR);
3873 OP ("BREAK", esil_break, 0, 0, OT_CTR);
3874 OP ("CLEAR", esil_clear, 0, 0, OT_UNK);
3875 OP ("DUP", esil_dup, 1, 0, OT_UNK);
3876 OP ("NUM", esil_num, 1, 1, OT_UNK);
3877 OP ("SWAP", esil_swap, 2, 2, OT_UNK);
3878 OP ("TRAP", esil_trap, 0, 0, OT_UNK);
3879 OP ("BITS", esil_bits, 1, 0, OT_UNK);
3880 OP ("SETJT", esil_set_jump_target, 0, 1, OT_UNK);
3881 OP ("SETJTS", esil_set_jump_target_set, 0, 1, OT_UNK);
3882 OP ("SETD", esil_set_delay_slot, 0, 1, OT_UNK);
3883
3884 /* we all float down here */
3885 OP ("NAN", esil_is_nan, 1, 1, OT_MATH);
3886 OP ("I2D", esil_signed_to_double, 1, 1, OT_MATH);
3887 OP ("S2D", esil_signed_to_double, 1, 1, OT_MATH);
3888 OP ("U2D", esil_unsigned_to_double, 1, 1, OT_MATH);
3889 OP ("D2I", esil_double_to_int, 1, 1, OT_MATH);
3890 OP ("D2F", esil_double_to_float, 1, 2, OT_MATH);
3891 OP ("F2D", esil_float_to_double, 1, 2, OT_MATH);
3892 OP ("F==", esil_float_cmp, 1, 2, OT_MATH);
3893 OP ("F!=", esil_float_negcmp, 1, 2, OT_MATH);
3894 OP ("F<", esil_float_less, 1, 2, OT_MATH);
3895 OP ("F<=", esil_float_lesseq, 1, 2, OT_MATH);
3896 OP ("F+", esil_float_add, 1, 2, OT_MATH);
3897 OP ("F-", esil_float_sub, 1, 2, OT_MATH);
3898 OP ("F*", esil_float_mul, 1, 2, OT_MATH);
3899 OP ("F/", esil_float_div, 1, 2, OT_MATH);
3900 OP ("-F", esil_float_neg, 1, 1, OT_MATH);
3901 OP ("CEIL", esil_float_ceil, 1, 1, OT_MATH);
3902 OP ("FLOOR", esil_float_floor, 1, 1, OT_MATH);
3903 OP ("ROUND", esil_float_round, 1, 1, OT_MATH);
3904 OP ("SQRT", esil_float_sqrt, 1, 1, OT_MATH);
3905
3906 }
3907
3908 /* register callbacks using this anal module. */
r_anal_esil_setup(RAnalEsil * esil,RAnal * anal,int romem,int stats,int nonull)3909 R_API bool r_anal_esil_setup(RAnalEsil *esil, RAnal *anal, int romem, int stats, int nonull) {
3910 r_return_val_if_fail (esil, false);
3911 //esil->debug = 0;
3912 esil->anal = anal;
3913 esil->parse_goto_count = anal->esil_goto_limit;
3914 esil->trap = 0;
3915 esil->trap_code = 0;
3916 //esil->user = NULL;
3917 esil->cb.reg_read = internal_esil_reg_read;
3918 esil->cb.mem_read = internal_esil_mem_read;
3919
3920 if (nonull) {
3921 // this is very questionable, most platforms allow accessing NULL
3922 // never writes zero to PC, BP, SP, why? because writing
3923 // zeros to these registers is equivalent to accessing NULL
3924 // pointer somehow
3925 esil->cb.reg_write = internal_esil_reg_write_no_null;
3926 esil->cb.mem_read = internal_esil_mem_read_no_null;
3927 esil->cb.mem_write = internal_esil_mem_write_no_null;
3928 } else {
3929 esil->cb.reg_write = internal_esil_reg_write;
3930 esil->cb.mem_read = internal_esil_mem_read;
3931 esil->cb.mem_write = internal_esil_mem_write;
3932 }
3933 r_anal_esil_mem_ro (esil, romem);
3934 r_anal_esil_stats (esil, stats);
3935 r_anal_esil_setup_ops (esil);
3936
3937 return (anal->cur && anal->cur->esil_init)
3938 ? anal->cur->esil_init (esil): true;
3939 }
3940