static int rap__read(struct r_io_t *io, RIODesc *fd, ut8 *buf, int count) { RSocket *s = RIORAP_FD (fd); int ret; int i = (int)count; ut8 tmp[5]; if (count>RMT_MAX) count = RMT_MAX; // send tmp[0] = RMT_READ; r_mem_copyendian (tmp+1, (ut8*)&count, 4, ENDIAN); r_socket_write (s, tmp, 5); r_socket_flush (s); // recv ret = r_socket_read_block (s, tmp, 5); if (ret != 5 || tmp[0] != (RMT_READ|RMT_REPLY)) { eprintf ("rap__read: Unexpected rap read reply " "(%d=0x%02x) expected (%d=0x%02x)\n", ret, tmp[0], 2, (RMT_READ|RMT_REPLY)); return -1; } r_mem_copyendian ((ut8*)&i, tmp+1, 4, ENDIAN); if (i>count) { eprintf ("rap__read: Unexpected data size %d\n", i); return -1; } r_socket_read_block (s, buf, i); return count; }
static int check_bytes(const ut8* bytes, ut64 sz) { const ut8 *h; ut8 buf[4]; int off, ret = R_FALSE; if (!bytes || sz < 0x300) { return R_FALSE; } memcpy (&off, bytes+4*sizeof (int), sizeof (int)); r_mem_copyendian ((ut8*)&off, (ut8*)&off, sizeof(int), !LIL_ENDIAN); h = bytes; if (sz>=0x300 && !memcmp (h, "\xca\xfe\xba\xbe", 4)) { memcpy (&off, h+4*sizeof (int), sizeof (int)); r_mem_copyendian ((ut8*)&off, (ut8*)&off, sizeof(int), !LIL_ENDIAN); if (off > 0 && off < sz) { memcpy (buf, h+off, 4); if (!memcmp (buf, "\xce\xfa\xed\xfe", 4) || !memcmp (buf, "\xfe\xed\xfa\xce", 4) || !memcmp (buf, "\xfe\xed\xfa\xcf", 4) || !memcmp (buf, "\xcf\xfa\xed\xfe", 4)) ret = R_TRUE; } } return ret; }
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) { ut64 len, check_len; int i, j, k, tsize, endian, m = 1; if (!b || b->empty) return 0; if (addr == R_BUF_CUR) addr = b->cur; else addr -= b->base; if (addr == UT64_MAX || addr > b->length) return -1; tsize = 2; for (i = len = 0; i < n; i++) for (j = 0; fmt[j]; j++) { switch (fmt[j]) { case '0'...'9': if (m == 1) m = r_num_get (NULL, &fmt[j]); continue; case 's': tsize = 2; endian = 1; break; case 'S': tsize = 2; endian = 0; break; case 'i': tsize = 4; endian = 1; break; case 'I': tsize = 4; endian = 0; break; case 'l': tsize = 8; endian = 1; break; case 'L': tsize = 8; endian = 0; break; case 'c': tsize = 1; endian = 1; break; default: return -1; } /* Avoid read/write out of bound. tsize and m are not user controled, then don't need to check possible overflow. */ if (!UT64_ADD (&check_len, len, tsize*m)) return -1; if (!UT64_ADD (&check_len, check_len, addr)) return -1; if (check_len > b->length) { return check_len; // return -1; } for (k = 0; k < m; k++) { if (write) { r_mem_copyendian ( (ut8*)&buf[addr+len+(k*tsize)], (ut8*)&b->buf[len+(k*tsize)], tsize, endian); } else { r_mem_copyendian ( (ut8*)&buf[len+(k*tsize)], (ut8*)&b->buf[addr+len+(k*tsize)], tsize, endian); } } len += tsize*m; m = 1; } b->cur = addr + len; return len; }
R_API void r_core_rtr_cmd(RCore *core, const char *input) { char bufw[1024], bufr[8]; const char *cmd = NULL, *cmd_output = NULL; int i, cmd_len, fd = atoi (input); if (*input==':' && !strchr (input+1, ':')) { r_core_cmdf (core, "o rap://%s", input); return; } if (fd != 0) { if (rtr_host[rtr_n].fd) for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd && rtr_n < RTR_MAX_HOSTS - 1; rtr_n++); if (!(cmd = strchr (input, ' '))) { eprintf ("Error\n"); return; } } else cmd = input; if (!rtr_host[rtr_n].fd){ eprintf ("Error: Unknown host\n"); core->num->value = 1; // fail return; } if (!rtr_host[rtr_n].proto == RTR_PROT_RAP){ eprintf ("Error: Not a rap:// host\n"); return; } core->num->value = 0; // that's fine if (!strlen (cmd)) { // just check if we can connect r_socket_close (rtr_host[rtr_n].fd); return; } /* send */ bufw[0] = RTR_RAP_CMD; i = strlen (cmd) + 1; r_mem_copyendian ((ut8*)bufw+1, (ut8*)&i, 4, endian); memcpy (bufw+5, cmd, i); r_socket_write (rtr_host[rtr_n].fd, bufw, 5+i); /* read */ r_socket_read (rtr_host[rtr_n].fd, (ut8*)bufr, 5); if (bufr[0] != (char)(RTR_RAP_CMD|RTR_RAP_REPLY)) { eprintf ("Error: Wrong reply\n"); return; } r_mem_copyendian ((ut8*)&cmd_len, (ut8*)bufr+1, 4, endian); cmd_output = malloc (cmd_len); if (!cmd_output) { eprintf ("Error: Allocating cmd output\n"); return; } r_socket_read (rtr_host[rtr_n].fd, (ut8*)cmd_output, cmd_len); r_cons_printf ("%s\n", cmd_output); free ((void *)cmd_output); }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret, i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else op = RMT_CMD; buf[0] = op; i = strlen (command)+1; if (i>RMT_MAX) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); // read ret = r_socket_read_block (s, buf, 5); if (ret != 5) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); if (i == -1) return -1; ret = 0; ptr = (char *)malloc (i); if (ptr) { int ir, tr = 0; do { ir = r_socket_read_block (s, (ut8*)ptr+tr, i-tr); if (ir>0) tr += ir; else break; } while (tr<i); // TODO: use io->printf() with support for \x00 ptr[i] = 0; if (io->printf) { io->printf ("%s", ptr); j = i; } else j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
// XXX: This is wrong, some opcodes are 32bit in thumb mode static int assemble(RAsm *a, RAsmOp *op, const char *buf) { int opcode = armass_assemble (buf, a->pc, (a->bits==16)?1:0); if (opcode==-1) return -1; if (a->bits==32) r_mem_copyendian (op->buf, (void *)&opcode, 4, a->big_endian); else r_mem_copyendian (op->buf, (void *)&opcode, 2, a->big_endian); return (a->bits/8); }
R_API void r_core_rtr_cmd(RCore *core, const char *input) { char bufw[1024], bufr[8]; const char *cmd = NULL, *cmd_output = NULL; int i, cmd_len, fd = atoi (input); if (fd != 0) { if (rtr_host[rtr_n].fd) for (rtr_n = 0; rtr_host[rtr_n].fd->fd != fd && rtr_n < RTR_MAX_HOSTS; rtr_n++); if (!(cmd = strchr (input, ' '))) { eprintf ("Error\n"); return; } } else cmd = input; if (!rtr_host[rtr_n].fd){ eprintf ("Error: Unknown host\n"); return; } if (!rtr_host[rtr_n].proto == RTR_PROT_RAP){ eprintf ("Error: Not a rap:// host\n"); return; } /* send */ bufw[0] = RTR_RAP_CMD; i = strlen (cmd) + 1; r_mem_copyendian ((ut8*)bufw+1, (ut8*)&i, 4, endian); memcpy (bufw+5, cmd, i); r_socket_write (rtr_host[rtr_n].fd, bufw, 5+i); /* read */ r_socket_read (rtr_host[rtr_n].fd, (ut8*)bufr, 5); if (bufr[0] != (char)(RTR_RAP_CMD|RTR_RAP_REPLY)) { eprintf ("Error: Wrong reply\n"); return; } r_mem_copyendian ((ut8*)&cmd_len, (ut8*)bufr+1, 4, endian); if (i == 0) return; if (i < 0) { eprintf ("Error: cmd length < 0\n"); return; } cmd_output = malloc (cmd_len); if (!cmd_output) { eprintf ("Error: Allocating cmd output\n"); return; } r_socket_read (rtr_host[rtr_n].fd, (ut8*)cmd_output, cmd_len); r_cons_printf ("%s\n", cmd_output); free ((void *)cmd_output); }
static int rap__system(RIO *io, RIODesc *fd, const char *command) { RSocket *s = RIORAP_FD (fd); ut8 buf[RMT_MAX]; char *ptr; int op, ret, i, j = 0; // send if (*command=='!') { op = RMT_SYSTEM; command++; } else op = RMT_CMD; buf[0] = op; i = strlen (command); if (i>RMT_MAX) { eprintf ("Command too long\n"); return -1; } r_mem_copyendian (buf+1, (ut8*)&i, 4, ENDIAN); memcpy (buf+5, command, i); r_socket_write (s, buf, i+5); r_socket_flush (s); // read ret = r_socket_read_block (s, buf, 5); if (ret != 5) return -1; if (buf[0] != (op | RMT_REPLY)) { eprintf ("Unexpected system reply\n"); return -1; } r_mem_copyendian ((ut8*)&i, buf+1, 4, ENDIAN); if (i == -1) return -1; ret = 0; if (i>RMT_MAX) { ret = i-RMT_MAX; i = RMT_MAX; } ptr = (char *)malloc (i); if (ptr) { r_socket_read_block (s, (ut8*)ptr, i); j = write (1, ptr, i); free (ptr); } /* Clean */ if (ret > 0) { ret -= r_socket_read (s, (ut8*)buf, RMT_MAX); } return i-j; }
R_API int r_reg_set_double(RReg *reg, RRegItem *item, long double value) { long double vld = 0.0f; ut8 *src; if (!item) { eprintf ("r_reg_set_value: item is NULL\n"); return R_FALSE; } switch (item->size) { case 80: r_mem_copyendian ( (ut8*)&vld, (ut8*)&value, 10, !reg->big_endian); src = (ut8*)&vld; break; default: eprintf ("r_reg_set_double : Bit size %d not supported\n", item->size); return R_FALSE; } if (reg->regset[item->type].arena->size - BITS2BYTES (item->offset) - BITS2BYTES(item->size)>=0) { r_mem_copybits (reg->regset[item->type].arena->bytes+ BITS2BYTES (item->offset), src, item->size); return R_TRUE; } eprintf ("r_reg_set_value: Cannot set %s to %Lf\n", item->name, value); return R_FALSE; }
static int format_output (char mode, ut64 n) { char *str = (char*) &n; char strbits[65]; if (flags & 2) r_mem_copyendian ((ut8*) str, (ut8*) str, 4, 0); switch (mode) { case 'I': printf ("%"PFMT64d"\n", n); break; case '0': printf ("0x%"PFMT64x"\n", n); break; case 'F': printf ("%ff\n", (float)(ut32)n); break; case 'B': if (n) { r_num_to_bits (strbits, n); printf ("%sb\n", strbits); } else printf ("0b\n"); break; case 'O': printf ("%"PFMT64o"\n", n); break; } return R_TRUE; }
static int assemble(RAsm *a, RAsmOp *op, const char *buf) { int opcode = armass_assemble (buf, a->pc, true); if (opcode==-1) return -1; r_mem_copyendian (op->buf, (void *)&opcode, 2, a->big_endian); return armthumb_length (opcode); }
R_API ut64 r_num_htonq(ut64 value) { ut64 ret = value; #if LIL_ENDIAN r_mem_copyendian ((ut8*)&ret, (ut8*)&value, 8, 0); #endif return ret; }
R_API ut64 r_mem_get_num(const ut8 *b, int size, int endian) { ut16 n16; ut32 n32; ut64 n64; switch (size) { case 1: return b[0]; case 2: r_mem_copyendian ((ut8*)&n16, b, 2, endian); return (ut64)n16; case 4: r_mem_copyendian ((ut8*)&n32, b, 4, endian); return (ut64)n32; case 8: r_mem_copyendian ((ut8*)&n64, b, 8, endian); return (ut64)n64; } return 0LL; }
// TODO: SEE: R_API ut64 r_reg_get_value(RReg *reg, RRegItem *item) { .. dupped code? R_API int r_mem_set_num (ut8 *dest, int dest_size, ut64 num, int endian) { int num4; short num2; switch (dest_size) { case 1: dest[0] = (ut8) num; break; case 2: num2 = (short)num; r_mem_copyendian (dest, (const ut8*)&num2, 2, endian); break; case 4: num4 = (int)num; r_mem_copyendian (dest, (const ut8*)&num4, 4, endian); break; case 8: r_mem_copyendian (dest, (const ut8*)&num, 8, endian); break; default: return R_FALSE; } return R_TRUE; }
static int format_output (char mode, const char *s) { ut64 n = r_num_math (num, s); const char *str = (char*) &n; char strbits[65]; if (flags & 2) { /* swap endian */ ut32 n2 = (n>>32)? 8:4; r_mem_copyendian ((ut8*) str, (ut8*) str, n2, 0); }
static ut32 getshift(const char *str) { char type[128]; char arg[128]; char *space; ut32 i=0, shift=0; const char *shifts[] = { "LSL", "LSR", "ASR", "ROR", 0, "RRX" // alias for ROR #0 }; strncpy (type, str, sizeof (type)-1); // handle RRX alias case if (!strcasecmp (type, shifts[5])) { shift = 6; } // all other shift types else { // split the string into type and arg space = strchr (type, ' '); if (!space) return 0; *space = 0; strncpy (arg, ++space, sizeof(arg)-1); for (i=0; shifts[i]; i++) { if (!strcasecmp (type, shifts[i])) { shift = 1; break; } } if (!shift) return 0; shift = (i*2); if ((i = getreg (arg)) != -1) { shift |= 1; i = i<<4; } else { i = getnum (arg); // ensure only the bottom 5 bits are used i &= 0x1f; if (!i) i = 32; i = (i*8); } } i += shift; i = i << 4; r_mem_copyendian ((ut8*)&shift, (const ut8*)&i, sizeof (ut32), 0); return shift; }
static ut32 getshift(const char *str) { char type[128]; char arg[128]; char *space; ut32 i=0, shift=0; const char *shifts[] = { "LSL", "LSR", "ASR", "ROR", 0, "RRX" // alias for ROR #0 }; strncpy (type, str, sizeof (type)-1); // XXX strcaecmp is probably unportable if (!strcasecmp (type, shifts[5])) { // handle RRX alias case shift = 6; } else { // all other shift types space = strchr (type, ' '); if (!space) return 0; *space = 0; strncpy (arg, ++space, sizeof(arg)-1); for (i=0; shifts[i]; i++) { if (!strcasecmp (type, shifts[i])) { shift = 1; break; } } if (!shift) return 0; shift = (i*2); if ((i = getreg (arg)) != -1) { i<<=8; // set reg // i|=1; // use reg i |= (1<<4); // bitshift i|=shift<<4; // set shift mode if (shift == 6) i|=(1<<20); } else { i = getnum (arg); // ensure only the bottom 5 bits are used i &= 0x1f; if (!i) i = 32; i = (i*8); i |= shift; // lsl, ror, ... i = i << 4; } } r_mem_copyendian ((ut8*)&shift, (const ut8*)&i, sizeof (ut32), 0); return shift; }
// TODO: cleanup this ugly code R_API int r_reg_set_value(RReg *reg, RRegItem *item, ut64 value) { ut64 v64; ut32 v32; ut16 v16; ut8 v8, *src; if (!item) { eprintf ("r_reg_set_value: item is NULL\n"); return R_FALSE; } switch (item->size) { case 64: r_mem_copyendian ( (ut8*)&v64, (ut8*)&value, 8, !reg->big_endian); src = (ut8*)&v64; break; case 32: r_mem_copyendian ( (ut8*)&v32, (ut8*)&value, 4, !reg->big_endian); src = (ut8*)&v32; break; case 16: r_mem_copyendian ( (ut8*)&v16, (ut8*)&value, 2, !reg->big_endian); src = (ut8*)&v16; break; case 8: v8 = (ut8)value; src = (ut8*)&v8; break; case 1: if (value) { ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8); int bit = (item->offset%8); ut8 mask = (1<<bit); buf[0] = (buf[0] &(0xff^mask)) | mask; } else { ut8 * buf = reg->regset[item->type].arena->bytes + (item->offset/8); int bit = (item->offset%8); ut8 mask = 0xff^(1<<bit); buf[0] = (buf[0] & mask) | 0; } return R_TRUE; default: eprintf ("r_reg_set_value: Bit size %d not supported\n", item->size); return R_FALSE; } if (reg->regset[item->type].arena->size - BITS2BYTES (item->offset) - BITS2BYTES(item->size)>=0) { r_mem_copybits (reg->regset[item->type].arena->bytes+ BITS2BYTES (item->offset), src, item->size); return R_TRUE; } eprintf ("r_reg_set_value: Cannot set %s to 0x%"PFMT64x"\n", item->name, value); return R_FALSE; }
static ut64 rap__lseek(struct r_io_t *io, RIODesc *fd, ut64 offset, int whence) { RSocket *s = RIORAP_FD (fd); int ret; ut8 tmp[10]; // query tmp[0] = RMT_SEEK; tmp[1] = (ut8)whence; r_mem_copyendian (tmp+2, (ut8*)&offset, 8, ENDIAN); r_socket_write (s, &tmp, 10); r_socket_flush (s); // get reply ret = r_socket_read_block (s, (ut8*)&tmp, 9); if (ret!=9) return -1; if (tmp[0] != (RMT_SEEK | RMT_REPLY)) { eprintf ("Unexpected lseek reply\n"); return -1; } r_mem_copyendian ((ut8 *)&offset, tmp+1, 8, !ENDIAN); return offset; }
static int check(RBinArch *arch) { int off, ret = R_FALSE; if (arch && arch->buf && arch->buf->buf && arch->buf->length>10) if (!memcmp (arch->buf->buf, "\xca\xfe\xba\xbe", 4)) { ut16 major = (arch->buf->buf[8]<<8) | arch->buf->buf[7]; memcpy (&off, arch->buf->buf+4*sizeof(int), sizeof(int)); r_mem_copyendian ((ut8*)&off, (ut8*)&off, sizeof(int), !LIL_ENDIAN); ret = R_TRUE; } return ret; }
static int check(RBinFile *arch) { int off, ret = R_FALSE; if (arch && arch->buf && arch->buf->buf && arch->buf->length>10) if (!memcmp (arch->buf->buf, "\xca\xfe\xba\xbe", 4)) { memcpy (&off, arch->buf->buf+4*sizeof(int), sizeof(int)); r_mem_copyendian ((ut8*)&off, (ut8*)&off, sizeof(int), !LIL_ENDIAN); // TODO: FIND __TEXT ret = R_TRUE; } return ret; }
static int assemble(RAsm *a, RAsmOp *op, const char *buf) { const int is_thumb = a->bits==16? 1: 0; int opsize; ut32 opcode = armass_assemble (buf, a->pc, is_thumb); if (opcode==UT32_MAX) return -1; if (is_thumb) { const int o = opcode>>16; opsize = (o&0x80 && ((o&0xe0)==0xe0))? 4: 2; r_mem_copyendian (op->buf, (void *)&opcode, opsize, a->big_endian); } else {
R_API ut64 r_io_read_i(RIO *io, ut64 addr, int sz, int endian) { ut64 ret = 0LL; int err; ut8 buf[8]; if (sz > 8) sz = 8; if (sz < 0) sz = 1; err = r_io_read_at (io, addr, buf, sz); if (err == sz) r_mem_copyendian ((ut8*)&ret, buf, sz, endian); else return -1; //else perror("Cannot read"); return ret; }
static int r_buf_fcpy_at (RBuffer *b, ut64 addr, ut8 *buf, const char *fmt, int n, int write) { int i, j, k, len, tsize, endian, m = 1; if (addr == R_BUF_CUR) addr = b->cur; else addr -= b->base; if (addr == UT64_MAX || addr > b->length) return -1; for (i = len = 0; i < n; i++) for (j = 0; fmt[j]; j++) { if (len > b->length) return -1; switch (fmt[j]) { case '0'...'9': if (m == 1) m = r_num_get (NULL, &fmt[j]); continue; case 's': tsize = 2; endian = 1; break; case 'S': tsize = 2; endian = 0; break; case 'i': tsize = 4; endian = 1; break; case 'I': tsize = 4; endian = 0; break; case 'l': tsize = 8; endian = 1; break; case 'L': tsize = 8; endian = 0; break; case 'c': tsize = 1; endian = 1; break; default: return -1; } for (k = 0; k < m; k++) { if (write) r_mem_copyendian( (ut8*)&buf[addr+len+k*tsize], (ut8*)&b->buf[len+k*tsize], tsize, endian); else r_mem_copyendian( (ut8*)&buf[len+k*tsize], (ut8*)&b->buf[addr+len+k*tsize], tsize, endian); } len += m*tsize; m = 1; } b->cur = addr + len; return len; }
static int check_bytes(const ut8 *buf, ut64 length) { int off, ret = R_FALSE; int version = 0; if (buf && length>10) if (!memcmp (buf, "\xca\xfe\xba\xbe", 4)) { memcpy (&off, buf+4*sizeof(int), sizeof(int)); version = buf[6] | (buf[7] <<8); if (version <1024) // IT's A MACH0! return R_FALSE; r_mem_copyendian ((ut8*)&off, (ut8*)&off, sizeof(int), !LIL_ENDIAN); ret = R_TRUE; } return ret; }
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) { ut8 buf2[4]; struct arm_insn *arminsn = arm_new(); arm_set_pc (arminsn, a->pc); arm_set_thumb (arminsn, a->bits == 16); if (a->big_endian && a->bits == 32) { r_mem_copyendian (buf2, buf, 4, 0); arm_set_input_buffer (arminsn, buf2); } else { arm_set_input_buffer (arminsn, buf); } op->size = arm_disasm_one_insn (arminsn); strncpy (op->buf_asm, arm_insn_asm (arminsn), R_ASM_BUFSIZE); strncpy (op->buf_hex, arm_insn_hex (arminsn), R_ASM_BUFSIZE); arm_free (arminsn); return op->size; }
static int check(RBinArch *arch) { int off, ret = R_FALSE; if (arch && arch->buf && arch->buf->buf) if (!memcmp (arch->buf->buf, "\xca\xfe\xba\xbe", 4)) { ret = R_TRUE; memcpy (&off, arch->buf->buf+4*sizeof(int), sizeof(int)); r_mem_copyendian ((ut8*)&off, (ut8*)&off, sizeof(int), !LIL_ENDIAN); if (off > 0 && off < arch->buf->length) { memmove (arch->buf->buf, arch->buf->buf+off, 4); if ( !memcmp (arch->buf->buf, "\xce\xfa\xed\xfe", 4) || !memcmp (arch->buf->buf, "\xfe\xed\xfa\xce", 4) || !memcmp (arch->buf->buf, "\xfe\xed\xfa\xcf", 4) || !memcmp (arch->buf->buf, "\xcf\xfa\xed\xfe", 4)) ret = R_FALSE; } } return ret; }
static void h8300_anal_jmp(RAnalOp *op, ut64 addr, const ut8 *buf) { ut16 ad; switch (buf[0]) { case H8300_JMP_1: op->type = R_ANAL_OP_TYPE_UJMP; break; case H8300_JMP_2: op->type = R_ANAL_OP_TYPE_JMP; r_mem_copyendian((ut8*)&ad, buf + 2, sizeof(ut16), !LIL_ENDIAN); op->jump = ad; break; case H8300_JMP_3: op->type = R_ANAL_OP_TYPE_UJMP; op->jump = buf[1]; break; } }
static void h8300_anal_jsr(RAnalOp *op, ut64 addr, const ut8 *buf) { ut16 ad; switch (buf[0]) { case H8300_JSR_1: op->type = R_ANAL_OP_TYPE_UCALL; break; case H8300_JSR_2: op->type = R_ANAL_OP_TYPE_CALL; r_mem_copyendian((ut8*)&ad, buf + 2, sizeof(ut16), !LIL_ENDIAN); op->jump = ad; op->fail = addr + 4; break; case H8300_JSR_3: op->type = R_ANAL_OP_TYPE_UCALL; op->jump = buf[1]; break; } }
static int riscv_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) { const int no_alias = 1; struct riscv_opcode *o = NULL; insn_t word = 0; int xlen = anal->bits; op->size = 4; op->addr = addr; op->type = R_ANAL_OP_TYPE_UNK; r_mem_copyendian ((void*)&word, (const void*)data, sizeof (word), true); o = get_opcode (word); if (word == UT64_MAX) { op->type = R_ANAL_OP_TYPE_ILL; return -1; } if (!o || !o->name) return op->size; for(; o < &riscv_opcodes[NUMOPCODES]; o++) { // XXX ASAN segfault if ( !(o->match_func)(o, word) ) continue; if ( no_alias && (o->pinfo & INSN_ALIAS) ) continue; if ( isdigit (o->subset[0]) && atoi (o->subset) != xlen) continue; else { break; } } if (!o || !o->name) { return -1; } // branch/jumps/calls/rets if (is_any ("jal")) { // decide wether it's ret or call int rd = (word >> OP_SH_RD) & OP_MASK_RD; op->type = (rd == 0) ? R_ANAL_OP_TYPE_RET: R_ANAL_OP_TYPE_CALL; op->jump = EXTRACT_UJTYPE_IMM (word) + addr; op->fail = addr + 4; } else if (is_any ("jr")) {