mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-24 13:49:50 +00:00
New flag rasm2 -c CPU. pointer hints, fix analysis of x86-16 jmps
Add ahp (pointer hints) Add rasm2 -c flag to select cpu (wip for arm) rasm2 -e toggles instead of setting Fix analysis of absolute jumps in x86-16 Push and pops are now magenta \o/
This commit is contained in:
parent
6efdfd0e7a
commit
ef781cbadd
@ -29,8 +29,9 @@ static int rasm_show_help(int v) {
|
||||
printf ("Usage: rasm2 [-CdDehLBvw] [-a arch] [-b bits] [-o addr] [-s syntax]\n"
|
||||
" [-f file] [-F fil:ter] [-l len] 'code'|hexpairs|-\n");
|
||||
if (v)
|
||||
printf (" -a [arch] Set assemble/disassemble plugin (RASM2_ARCH)\n"
|
||||
printf (" -a [arch] Set architecture to assemble/disassemble (see -L)\n"
|
||||
" -b [bits] Set cpu register size (8, 16, 32, 64) (RASM2_BITS)\n"
|
||||
" -c [cpu] Select specific CPU (depends on arch)\n"
|
||||
" -C Output in C format\n"
|
||||
" -d, -D Disassemble from hexpair bytes (-D show hexpairs)\n"
|
||||
" -e Use big endian instead of little endian\n"
|
||||
@ -154,7 +155,7 @@ int main(int argc, char *argv[]) {
|
||||
const char *env_arch = r_sys_getenv ("RASM2_ARCH");
|
||||
const char *env_bits = r_sys_getenv ("RASM2_BITS");
|
||||
char buf[R_ASM_BUFSIZE];
|
||||
char *arch = NULL, *file = NULL, *filters = NULL, *kernel = NULL;
|
||||
char *arch = NULL, *file = NULL, *filters = NULL, *kernel = NULL, *cpu = NULL;
|
||||
ut64 offset = 0;
|
||||
int dis = 0, ascii = 0, bin = 0, ret = 0, bits = 32, c, whatsop = 0;
|
||||
ut64 len = 0, idx = 0;
|
||||
@ -169,7 +170,8 @@ int main(int argc, char *argv[]) {
|
||||
return rasm_show_help (0);
|
||||
|
||||
r_asm_use (a, R_SYS_ARCH);
|
||||
while ((c = getopt (argc, argv, "k:DCeva:b:s:do:Bl:hLf:F:w")) != -1) {
|
||||
r_asm_set_big_endian (a, R_FALSE);
|
||||
while ((c = getopt (argc, argv, "k:DCc:eva:b:s:do:Bl:hLf:F:w")) != -1) {
|
||||
switch (c) {
|
||||
case 'k':
|
||||
kernel = optarg;
|
||||
@ -183,6 +185,9 @@ int main(int argc, char *argv[]) {
|
||||
case 'F':
|
||||
filters = optarg;
|
||||
break;
|
||||
case 'c':
|
||||
cpu = optarg;
|
||||
break;
|
||||
case 'C':
|
||||
coutput = R_TRUE;
|
||||
break;
|
||||
@ -213,7 +218,7 @@ int main(int argc, char *argv[]) {
|
||||
r_asm_list (a);
|
||||
exit (1);
|
||||
case 'e':
|
||||
r_asm_set_big_endian (a, R_TRUE);
|
||||
r_asm_set_big_endian (a, !!!a->big_endian);
|
||||
break;
|
||||
case 'v':
|
||||
return blob_version ("rasm2");
|
||||
@ -241,6 +246,7 @@ int main(int argc, char *argv[]) {
|
||||
eprintf ("rasm2: Cannot find asm.x86 plugin\n");
|
||||
return 0;
|
||||
}
|
||||
r_asm_set_cpu (a, cpu);
|
||||
r_asm_set_bits (a, (env_bits && *env_bits)? atoi (env_bits): bits);
|
||||
a->syscall = r_syscall_new ();
|
||||
r_syscall_setup (a->syscall, arch, kernel, bits);
|
||||
|
@ -13,6 +13,11 @@ R_API void r_anal_hint_del (RAnal *a, ut64 addr) {
|
||||
if (hint) r_list_delete_data (a->hints, hint);
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_pointer (RAnal *a, ut64 addr, ut64 ptr) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, 0);
|
||||
hint->ptr = ptr;
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_arch (RAnal *a, ut64 addr, int size, const char *arch) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, size);
|
||||
free (hint->arch);
|
||||
@ -50,7 +55,7 @@ R_API RAnalHint *r_anal_hint_at (RAnal *a, ut64 from, int size) {
|
||||
RListIter *iter;
|
||||
if (size>0)
|
||||
r_list_foreach (a->hints, iter, hint) {
|
||||
if (from == hint->from && (!size|| (to == hint->to)))
|
||||
if (from == hint->from && (!size || (to == hint->to)))
|
||||
return hint;
|
||||
}
|
||||
return NULL;
|
||||
@ -81,11 +86,13 @@ R_API RAnalHint *r_anal_hint_get(RAnal *anal, ut64 addr) {
|
||||
r_list_foreach (anal->hints, iter, hint) {
|
||||
if (addr >= hint->from && addr < hint->to) {
|
||||
if (!res) res = R_NEW0 (RAnalHint);
|
||||
#define SETRET(x) if(hint->x)res->x=hint->x
|
||||
SETRET(arch);
|
||||
#define SETRETS(x) if(hint->x) res->x=strdup(hint->x);
|
||||
#define SETRET(x) if(hint->x) res->x=hint->x
|
||||
SETRETS(arch);
|
||||
SETRET(bits);
|
||||
SETRET(opcode);
|
||||
SETRET(analstr);
|
||||
SETRET(ptr);
|
||||
SETRETS(opcode);
|
||||
SETRETS(analstr);
|
||||
SETRET(length);
|
||||
}
|
||||
}
|
||||
|
@ -66,6 +66,7 @@ static int getarg(char *src, struct ud *u, int idx) {
|
||||
st64 n;
|
||||
src[0] = 0;
|
||||
switch (op->type) {
|
||||
case UD_OP_PTR:
|
||||
case UD_OP_CONST:
|
||||
case UD_OP_JIMM:
|
||||
case UD_OP_IMM:
|
||||
@ -82,9 +83,6 @@ static int getarg(char *src, struct ud *u, int idx) {
|
||||
if (idx>=0 && idx<UD_REG_TAB_SIZE)
|
||||
strcpy (src, ud_reg_tab[op->base - UD_R_AL]);
|
||||
break;
|
||||
case UD_OP_PTR:
|
||||
strcpy (src, "ptr");
|
||||
break;
|
||||
case UD_OP_MEM:
|
||||
n = getval (op);
|
||||
// TODO ->scale
|
||||
@ -105,6 +103,12 @@ static int getarg(char *src, struct ud *u, int idx) {
|
||||
|
||||
static st64 getval(ud_operand_t *op) {
|
||||
int bits = op->size;
|
||||
switch (op->type) {
|
||||
case UD_OP_PTR:
|
||||
return (op->lval.ptr.seg<<4) | (op->lval.ptr.off & 0xFFFF);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
switch (bits) {
|
||||
case 8: return (char)op->lval.sbyte;
|
||||
case 16: return (short) op->lval.uword;
|
||||
@ -300,6 +304,25 @@ int x86_udis86_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len)
|
||||
op->type = R_ANAL_OP_TYPE_UJMP;
|
||||
} else {
|
||||
op->type = R_ANAL_OP_TYPE_JMP;
|
||||
#if 0
|
||||
{
|
||||
ut16 a = (op->lval.ptr.seg & 0xFFFF);
|
||||
ut16 b = (op->lval.ptr.off);
|
||||
switch (op->size) {
|
||||
case 32:
|
||||
sprintf (src, "%04x:%04x", a, b & 0xFFFF);
|
||||
break;
|
||||
case 48:
|
||||
sprintf (src, "%04x:%04x", a, b);
|
||||
break;
|
||||
default:
|
||||
eprintf ("FUCK YOU\n");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (u.operand[0].type==UD_OP_PTR) {
|
||||
op->jump = getval (&u.operand[0]);
|
||||
}else
|
||||
op->jump = addr + oplen + getval (&u.operand[0]);
|
||||
}
|
||||
break;
|
||||
|
@ -150,7 +150,7 @@ enum opcode_sentinel_enum
|
||||
SENTINEL_GENERIC_START
|
||||
} opcode_sentinels;
|
||||
|
||||
#define UNDEFINED_INSTRUCTION " ; <UNDEFINED> instruction: %0-31x"
|
||||
#define UNDEFINED_INSTRUCTION " ; <UNDEFINED> instruction: %0-31x"
|
||||
#define UNPREDICTABLE_INSTRUCTION " ; <UNPREDICTABLE>"
|
||||
|
||||
/* Common coprocessor opcodes shared between Arm and Thumb-2. */
|
||||
@ -1939,6 +1939,7 @@ print_insn_coprocessor (bfd_vma pc,
|
||||
unsigned long allowed_arches = private_data->features.coproc;
|
||||
int cond;
|
||||
|
||||
//allowed_arches = ARM_EXT_V5T;
|
||||
for (insn = coprocessor_opcodes; insn->assembler; insn++)
|
||||
{
|
||||
unsigned long u_reg = 16;
|
||||
@ -4732,6 +4733,7 @@ is_mapping_symbol (struct disassemble_info *info, int n,
|
||||
/* Try to infer the code type (ARM or Thumb) from a mapping symbol.
|
||||
Returns nonzero if *MAP_TYPE was set. */
|
||||
|
||||
#if 0
|
||||
static int
|
||||
get_map_sym_type (struct disassemble_info *info,
|
||||
int n,
|
||||
@ -4754,6 +4756,7 @@ get_sym_code_type (struct disassemble_info *info,
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Given a bfd_mach_arm_XXX value, this function fills in the fields
|
||||
of the supplied arm_feature_set structure with bitmasks indicating
|
||||
@ -4772,6 +4775,7 @@ select_arm_features (unsigned long mach,
|
||||
features->coproc = (CEXT) | FPU_FPA; \
|
||||
return
|
||||
|
||||
//printf ("ARM FEATURES %d\n", mach);
|
||||
switch (mach)
|
||||
{
|
||||
case bfd_mach_arm_2: ARM_ARCH_V2;
|
||||
@ -4813,6 +4817,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||
bfd_boolean found = FALSE;
|
||||
struct arm_private_data *private_data;
|
||||
|
||||
//printf ("-> %d\n", info->mach);
|
||||
if (info->disassembler_options)
|
||||
{
|
||||
parse_disassembler_options (info->disassembler_options);
|
||||
@ -4826,6 +4831,7 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||
{
|
||||
static struct arm_private_data private;
|
||||
|
||||
#if 0
|
||||
if ((info->flags & USER_SPECIFIED_MACHINE_TYPE) == 0)
|
||||
/* If the user did not use the -m command line switch then default to
|
||||
disassembling all types of ARM instruction.
|
||||
@ -4846,11 +4852,13 @@ print_insn (bfd_vma pc, struct disassemble_info *info, bfd_boolean little)
|
||||
"unknown" arm architecture which is compatible with any ARM
|
||||
instruction. */
|
||||
info->mach = bfd_mach_arm_unknown;
|
||||
#endif
|
||||
|
||||
/* Compute the architecture bitmask from the machine number.
|
||||
Note: This assumes that the machine number will not change
|
||||
during disassembly.... */
|
||||
info->mach = bfd_mach_arm_5TE;
|
||||
//info->mach = bfd_mach_arm_5TE;
|
||||
//printf ("MACH %d\n", info->mach);
|
||||
select_arm_features (info->mach, &private.features);
|
||||
|
||||
private.has_mapping_symbols = -1;
|
||||
@ -5049,6 +5057,10 @@ info->mach = bfd_mach_arm_5TE;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (info->bytes_per_line==2) {
|
||||
force_thumb = 1;
|
||||
info->bytes_per_line = 4;
|
||||
}
|
||||
if (force_thumb)
|
||||
is_thumb = TRUE;
|
||||
|
||||
|
@ -259,7 +259,7 @@ static int has_bits(RAsmPlugin *h, int bits) {
|
||||
|
||||
R_API void r_asm_set_cpu(RAsm *a, const char *cpu) {
|
||||
free (a->cpu);
|
||||
a->cpu = strdup (cpu);
|
||||
a->cpu = cpu? strdup (cpu): NULL;
|
||||
}
|
||||
|
||||
R_API int r_asm_set_bits(RAsm *a, int bits) {
|
||||
@ -270,8 +270,8 @@ R_API int r_asm_set_bits(RAsm *a, int bits) {
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_asm_set_big_endian(RAsm *a, int boolean) {
|
||||
a->big_endian = boolean;
|
||||
R_API int r_asm_set_big_endian(RAsm *a, int b) {
|
||||
a->big_endian = b;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,62 @@
|
||||
#include <r_asm.h>
|
||||
#include "dis-asm.h"
|
||||
#include "../arch/arm/arm.h"
|
||||
#include "../arch/arm/gnu/arm.h"
|
||||
|
||||
#if 0
|
||||
#define ARM_ARCH_OPT(N, V, DF) { N, sizeof (N) - 1, V, DF }
|
||||
struct arm_arch_option_table {
|
||||
const char name;
|
||||
int namelen;
|
||||
int arch;
|
||||
int fpu;
|
||||
};
|
||||
static const struct arm_arch_option_table arm_archs[] = {
|
||||
ARM_ARCH_OPT ("all", ARM_ANY, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv1", ARM_ARCH_V1, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2", ARM_ARCH_V2, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2a", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv2s", ARM_ARCH_V2S, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv3", ARM_ARCH_V3, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv3m", ARM_ARCH_V3M, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4", ARM_ARCH_V4, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4xm", ARM_ARCH_V4xM, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4t", ARM_ARCH_V4T, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv4txm", ARM_ARCH_V4TxM, FPU_ARCH_FPA),
|
||||
ARM_ARCH_OPT ("armv5", ARM_ARCH_V5, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5t", ARM_ARCH_V5T, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5txm", ARM_ARCH_V5TxM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5te", ARM_ARCH_V5TE, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5texp", ARM_ARCH_V5TExP, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv5tej", ARM_ARCH_V5TEJ, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6", ARM_ARCH_V6, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6j", ARM_ARCH_V6, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6k", ARM_ARCH_V6K, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6z", ARM_ARCH_V6Z, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zk", ARM_ARCH_V6ZK, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6t2", ARM_ARCH_V6T2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6kt2", ARM_ARCH_V6KT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zt2", ARM_ARCH_V6ZT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6zkt2", ARM_ARCH_V6ZKT2, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6-m", ARM_ARCH_V6M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv6s-m", ARM_ARCH_V6SM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7", ARM_ARCH_V7, FPU_ARCH_VFP),
|
||||
/* The official spelling of the ARMv7 profile variants is the dashed form.
|
||||
Accept the non-dashed form for compatibility with old toolchains. */
|
||||
ARM_ARCH_OPT ("armv7a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-a", ARM_ARCH_V7A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-r", ARM_ARCH_V7R, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7-m", ARM_ARCH_V7M, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv7e-m", ARM_ARCH_V7EM, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("armv8-a", ARM_ARCH_V8A, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("xscale", ARM_ARCH_XSCALE, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("iwmmxt", ARM_ARCH_IWMMXT, FPU_ARCH_VFP),
|
||||
ARM_ARCH_OPT ("iwmmxt2", ARM_ARCH_IWMMXT2,FPU_ARCH_VFP),
|
||||
{ NULL, 0, ARM_ARCH_NONE, ARM_ARCH_NONE }
|
||||
};
|
||||
#endif
|
||||
|
||||
static int arm_mode = 0;
|
||||
static unsigned long Offset = 0;
|
||||
@ -54,23 +110,32 @@ static int buf_fprintf(void *stream, const char *format, ...) {
|
||||
}
|
||||
|
||||
static int disassemble(RAsm *a, RAsmOp *op, const ut8 *buf, int len) {
|
||||
static char *oldcpu = NULL;
|
||||
static int oldcpucode = 0;
|
||||
int cpucode = 0;
|
||||
struct disassemble_info obj;
|
||||
|
||||
if (len<(a->bits/8)) return -1;
|
||||
buf_global = op->buf_asm;
|
||||
Offset = a->pc;
|
||||
//// if (a->bits==64)
|
||||
memcpy (bytes, buf, 4); // TODO handle thumb
|
||||
|
||||
/* prepare disassembler */
|
||||
memset (&obj,'\0', sizeof (struct disassemble_info));
|
||||
arm_mode = a->bits;
|
||||
//obj.arch = ARM_EXT_V1|ARM_EXT_V4T|ARM_EXT_V5;
|
||||
/* TODO: set arch */
|
||||
obj.arch = UT32_MAX;
|
||||
obj.mach = UT32_MAX;
|
||||
obj.arch = 0;
|
||||
obj.mach = 0;
|
||||
|
||||
cpucode = oldcpucode;
|
||||
/* select cpu */
|
||||
if (a->cpu) {
|
||||
if (oldcpu != a->cpu) {
|
||||
cpucode = atoi (a->cpu);
|
||||
if (!strcmp ("v5j", a->cpu))
|
||||
cpucode = 9;
|
||||
}
|
||||
}
|
||||
obj.arch = 0;
|
||||
obj.mach = cpucode;
|
||||
oldcpucode = cpucode;
|
||||
|
||||
obj.buffer = bytes;
|
||||
obj.read_memory_func = &arm_buffer_read_memory;
|
||||
|
@ -62,7 +62,6 @@ static int check(RBinArch *arch) {
|
||||
static RList* sections(RBinArch *arch) {
|
||||
RList *ret = NULL;
|
||||
RBinSection *ptr = NULL;
|
||||
int i;
|
||||
|
||||
if (!(ret = r_list_new ()))
|
||||
return NULL;
|
||||
|
@ -13,8 +13,8 @@ R_API void r_cons_pal_init(const char *foo) {
|
||||
cons->pal.b0x7f = Color_YELLOW;
|
||||
cons->pal.b0xff = Color_RED;
|
||||
cons->pal.btext = Color_MAGENTA;
|
||||
cons->pal.push = Color_YELLOW;
|
||||
cons->pal.pop = Color_BYELLOW;
|
||||
cons->pal.push = Color_MAGENTA;
|
||||
cons->pal.pop = Color_BMAGENTA;
|
||||
cons->pal.nop = Color_BLUE;
|
||||
cons->pal.jmp = Color_GREEN;
|
||||
cons->pal.call = Color_BGREEN;
|
||||
|
@ -21,6 +21,7 @@ R_API void r_core_anal_hint_list (RAnal *a, int mode) {
|
||||
HINTCMD (length, "ahl %d");
|
||||
HINTCMD (opcode, "aho %s");
|
||||
HINTCMD (opcode, "ahs %s");
|
||||
HINTCMD (opcode, "ahp %s");
|
||||
break;
|
||||
case 'j':
|
||||
r_cons_printf ("%s{\"from\":%"PFMT64d",\"to\":%"PFMT64d,
|
||||
@ -30,6 +31,7 @@ R_API void r_core_anal_hint_list (RAnal *a, int mode) {
|
||||
if (hint->length) r_cons_printf (",\"length\":%d", hint->length);
|
||||
if (hint->opcode) r_cons_printf (",\"opcode\":\"%s\"", hint->opcode);
|
||||
if (hint->analstr) r_cons_printf (",\"analstr\":\"%s\"", hint->analstr);
|
||||
if (hint->ptr) r_cons_printf (",\"ptr\":\"0x%"PFMT64x"x\"", hint->ptr);
|
||||
r_cons_printf ("}");
|
||||
break;
|
||||
default:
|
||||
|
@ -207,9 +207,13 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops) {
|
||||
int ret, i, idx;
|
||||
RAsmOp asmop;
|
||||
RAnalOp op;
|
||||
|
||||
ut64 addr;
|
||||
RAnalHint *hint;
|
||||
for (i=idx=ret=0; idx<len && (!nops|| (nops&&i<nops)); i++, idx+=ret) {
|
||||
r_asm_set_pc (core->assembler, core->offset+idx);
|
||||
addr = core->offset+idx;
|
||||
// TODO: use more anal hints
|
||||
hint = r_anal_hint_get (core->anal, addr);
|
||||
r_asm_set_pc (core->assembler, addr);
|
||||
ret = r_asm_disassemble (core->assembler, &asmop, buf+idx, len-idx);
|
||||
ret = r_anal_op (core->anal, &op, core->offset+idx, buf + idx, len-idx);
|
||||
if (ret<1) {
|
||||
@ -219,8 +223,10 @@ static void r_core_anal_bytes (RCore *core, const ut8 *buf, int len, int nops) {
|
||||
}
|
||||
|
||||
r_cons_printf ("opcode: %s\n", asmop.buf_asm);
|
||||
if (hint && hint->opcode)
|
||||
r_cons_printf ("ophint: %s\n", hint->opcode);
|
||||
r_cons_printf ("addr: 0x%08"PFMT64x"\n", core->offset+idx);
|
||||
r_cons_printf ("size: %d\n", op.length);
|
||||
r_cons_printf ("size: %d\n", (hint&&hint->length)?hint->length: op.length);
|
||||
r_cons_printf ("type: %d (%s)\n", op.type, optypestr (op.type)); // TODO: string
|
||||
if (op.esil)
|
||||
r_cons_printf ("esil: %s\n", op.esil);
|
||||
@ -901,7 +907,9 @@ static int cmd_anal(void *data, const char *input) {
|
||||
" ah* offset # list hints in radare commands format\n"
|
||||
" aha ppc 51 # set arch for a range of N bytes\n"
|
||||
" ahb 16 @ $$ # force 16bit for current instruction\n"
|
||||
" ahl 4 32 # set opcode size=4 for range of 32 bytes\n"
|
||||
" ahc 0x804804 # override call/jump address\n"
|
||||
" ahf 0x804840 # override fallback address for call\n"
|
||||
" ahl 4 # set opcode size=4\n"
|
||||
" aho foo a0,33 # replace opcode string\n"
|
||||
" ahs eax+=3 # set vm analysis string\n"
|
||||
);
|
||||
@ -926,8 +934,18 @@ R_API int r_core_hint(RCore *core, ut64 addr) {
|
||||
r_anal_hint_free (hint);
|
||||
#endif
|
||||
case 'a': // set arch
|
||||
{
|
||||
const char *arch = input+3;
|
||||
int sz = 1;
|
||||
char *p = strchr (input+3, ' ');
|
||||
if (p) {
|
||||
*p = 0;
|
||||
sz = atoi (p+1);
|
||||
}
|
||||
if (arch && *arch)
|
||||
r_anal_hint_set_arch (core->anal, core->offset,
|
||||
1, input+2);
|
||||
sz, arch);
|
||||
}
|
||||
break;
|
||||
case 'b': // set bits
|
||||
r_anal_hint_set_bits (core->anal, core->offset,
|
||||
@ -952,6 +970,9 @@ R_API int r_core_hint(RCore *core, ut64 addr) {
|
||||
1, atoi (input+2));
|
||||
break;
|
||||
#endif
|
||||
case 'p':
|
||||
r_anal_hint_set_pointer (core->anal, core->offset, r_num_math (core->num, input+2));
|
||||
break;
|
||||
case '*':
|
||||
case 'j':
|
||||
case '\0':
|
||||
|
@ -407,6 +407,13 @@ static int config_asmlineswidth_callback(void *user, void *data) {
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int config_asmcpu_callback(void *user, void *data) {
|
||||
RCore *core = (RCore *) user;
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
r_asm_set_cpu (core->assembler, node->value);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int config_asmarch_callback(void *user, void *data) {
|
||||
RCore *core = (RCore *) user;
|
||||
RConfigNode *node = (RConfigNode *) data;
|
||||
@ -523,6 +530,8 @@ r_config_set (cfg, "asm.arch", R_SYS_ARCH);
|
||||
r_config_desc (cfg, "asm.os", "Select operating system (kernel) (linux, darwin, w32,..)");
|
||||
r_config_set_cb (cfg, "asm.arch", R_SYS_ARCH, &config_asmarch_callback);
|
||||
r_config_desc (cfg, "asm.arch", "Set the arch to be usedd by asm");
|
||||
r_config_set_cb (cfg, "asm.cpu", R_SYS_ARCH, &config_asmcpu_callback);
|
||||
r_config_desc (cfg, "asm.cpu", "Set the kind of asm.arch cpu");
|
||||
// XXX: not portable
|
||||
r_parse_use (core->parser, "x86.pseudo");
|
||||
r_config_set_cb (cfg, "asm.parser", "x86.pseudo", &config_asmparser_callback);
|
||||
|
@ -68,7 +68,6 @@ static void printoffset(ut64 off, int show_color, int invert, int opt) {
|
||||
|
||||
// int l is for lines
|
||||
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l, int invbreak, int cbytes) {
|
||||
/* hints */
|
||||
RAnalHint *hint = NULL;
|
||||
const char *pal_comment = core->cons->pal.comment;
|
||||
/* other */
|
||||
@ -283,7 +282,7 @@ toro:
|
||||
else r_cons_printf ("; %s XREF 0x%08"PFMT64x" (%s)\n",
|
||||
refi->type==R_ANAL_REF_TYPE_CODE?"CODE (JMP)":
|
||||
refi->type==R_ANAL_REF_TYPE_CALL?"CODE (CALL)":"DATA", refi->addr,
|
||||
fun?fun->name:"unk");
|
||||
fun?fun->name: "unk");
|
||||
}
|
||||
r_list_free (xrefs);
|
||||
}
|
||||
@ -370,7 +369,7 @@ toro:
|
||||
if (atabs) {
|
||||
int n, i = 0;
|
||||
char *t, *b = asmop.buf_asm;
|
||||
for (;*b;b++,i++) {
|
||||
for (; *b; b++, i++) {
|
||||
if (*b!=' ') continue;
|
||||
n = (10-i);
|
||||
t = strdup (b+1); //XXX slow!
|
||||
@ -388,8 +387,10 @@ toro:
|
||||
r_anal_op_fini (&analop);
|
||||
if (!lastfail)
|
||||
r_anal_op (core->anal, &analop, at, buf+idx, (int)(len-idx));
|
||||
if (hint && hint->length)
|
||||
analop.length = hint->length;
|
||||
if (hint) {
|
||||
if (hint->length) analop.length = hint->length;
|
||||
if (hint->ptr) analop.ptr = hint->ptr;
|
||||
}
|
||||
{
|
||||
RAnalValue *src;
|
||||
switch (analop.type) {
|
||||
@ -441,18 +442,17 @@ toro:
|
||||
}
|
||||
}
|
||||
if (show_comments && show_cmtflgrefs) {
|
||||
RFlagItem *item;
|
||||
switch (analop.type) {
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
case R_ANAL_OP_TYPE_CJMP:
|
||||
case R_ANAL_OP_TYPE_CALL:
|
||||
{
|
||||
RFlagItem *item = r_flag_get_i (core->flags, analop.jump);
|
||||
item = r_flag_get_i (core->flags, analop.jump);
|
||||
if (item && item->comment) {
|
||||
if (show_color) r_cons_strcat (pal_comment);
|
||||
r_cons_printf (" ; ref to %s: %s\n", item->name, item->comment);
|
||||
if (show_color) r_cons_strcat (Color_RESET);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -646,6 +646,8 @@ toro:
|
||||
case R_ANAL_OP_TYPE_NOT:
|
||||
case R_ANAL_OP_TYPE_SHL:
|
||||
case R_ANAL_OP_TYPE_SHR:
|
||||
case R_ANAL_OP_TYPE_ROL:
|
||||
case R_ANAL_OP_TYPE_ROR:
|
||||
r_cons_strcat (color_bin);
|
||||
break;
|
||||
case R_ANAL_OP_TYPE_JMP:
|
||||
@ -835,9 +837,8 @@ toro:
|
||||
ut32 word4 = 0;
|
||||
int ret;
|
||||
if (core->assembler->bits==64) {
|
||||
ret = r_io_read_at (core->io, analop.ptr,
|
||||
(void *)&word8, sizeof (word8))
|
||||
== sizeof (word8);
|
||||
ret = r_io_read_at (core->io, analop.ptr, (void *)&word8,
|
||||
sizeof (word8)) == sizeof (word8);
|
||||
} else {
|
||||
ret = r_io_read_at (core->io, analop.ptr,
|
||||
(void *)&word4, sizeof (word4))
|
||||
@ -848,7 +849,14 @@ toro:
|
||||
if (ret) {
|
||||
RMetaItem *mi2 = r_meta_find (core->anal->meta, word8,
|
||||
R_META_TYPE_ANY, R_META_WHERE_HERE);
|
||||
if (!mi2) {
|
||||
if (mi2) {
|
||||
if (mi2->type == R_META_TYPE_STRING) {
|
||||
char *str = r_str_unscape (mi2->str);
|
||||
r_cons_printf (" (at=0x%08"PFMT64x") (len=%"PFMT64d
|
||||
") \"%s\" ", word8, mi2->size, str);
|
||||
free (str);
|
||||
} else r_cons_printf ("unknown type '%c'\n", mi2->type);
|
||||
} else {
|
||||
mi2 = r_meta_find (core->anal->meta, (ut64)analop.ptr,
|
||||
R_META_TYPE_ANY, R_META_WHERE_HERE);
|
||||
if (mi2) {
|
||||
@ -858,13 +866,6 @@ toro:
|
||||
free (str);
|
||||
} else r_cons_printf (" ; 0x%08x [0x%"PFMT64x"]",
|
||||
word8, analop.ptr);
|
||||
} else {
|
||||
if (mi2->type == R_META_TYPE_STRING) {
|
||||
char *str = r_str_unscape (mi2->str);
|
||||
r_cons_printf (" (at=0x%08"PFMT64x") (len=%"PFMT64d
|
||||
") \"%s\" ", word8, mi2->size, str);
|
||||
free (str);
|
||||
} else r_cons_printf ("unknown type '%c'\n", mi2->type);
|
||||
}
|
||||
} else {
|
||||
st64 sref = analop.ptr;
|
||||
@ -927,7 +928,7 @@ toro:
|
||||
goto toro;
|
||||
}
|
||||
#endif
|
||||
if(oldbits) {
|
||||
if (oldbits) {
|
||||
r_config_set_i (core->config, "asm.bits", oldbits);
|
||||
oldbits = 0;
|
||||
}
|
||||
@ -977,16 +978,16 @@ R_API int r_core_print_disasm_json(RCore *core, ut64 addr, ut8 *buf, int len) {
|
||||
}
|
||||
|
||||
R_API int r_core_print_disasm_instructions (RCore *core, int len, int l) {
|
||||
RAsmOp asmop;
|
||||
char *opstr, *tmpopstr;
|
||||
int i, j, ret, err = 0;
|
||||
int decode = r_config_get_i (core->config, "asm.decode");
|
||||
const ut8 *buf = core->block;
|
||||
int bs = core->blocksize;
|
||||
RAnalHint *hint = NULL;
|
||||
char *opstr, *tmpopstr;
|
||||
int i, j, ret, err = 0;
|
||||
RAnalOp analop = {0};
|
||||
RAnalFunction *f;
|
||||
RAnalHint *hint = NULL;
|
||||
int decode = r_config_get_i (core->config, "asm.decode");
|
||||
int oldbits = 0;
|
||||
RAsmOp asmop;
|
||||
ut64 at;
|
||||
|
||||
if (len>core->blocksize)
|
||||
|
@ -508,6 +508,7 @@ typedef struct r_anal_t {
|
||||
typedef struct r_anal_hint_t {
|
||||
ut64 from;
|
||||
ut64 to;
|
||||
ut64 ptr;
|
||||
char *arch;
|
||||
char *opcode;
|
||||
char *analstr;
|
||||
@ -531,7 +532,7 @@ typedef struct r_anal_value_t {
|
||||
typedef struct r_anal_op_t {
|
||||
char *mnemonic; /* mnemonic */
|
||||
ut64 addr; /* address */
|
||||
int type; /* type of opcode */
|
||||
ut64 type; /* type of opcode */
|
||||
int stackop; /* operation on stack? */
|
||||
int cond; /* condition type */
|
||||
int length; /* length in bytes of opcode */
|
||||
@ -881,6 +882,7 @@ R_API void r_anal_hint_set_arch (RAnal *a, ut64 addr, int size, const char *arch
|
||||
R_API void r_anal_hint_set_length (RAnal *a, ut64 addr, int size, int length);
|
||||
R_API void r_anal_hint_set_opcode (RAnal *a, ut64 addr, int size, const char *str);
|
||||
R_API void r_anal_hint_set_analstr (RAnal *a, ut64 addr, int size, const char *str);
|
||||
R_API void r_anal_hint_set_pointer (RAnal *a, ut64 addr, ut64 jump);
|
||||
|
||||
R_API int r_anal_esil_eval(RAnal *anal, const char *str);
|
||||
|
||||
|
@ -80,10 +80,10 @@ typedef struct {
|
||||
|
||||
#define _RAsmPlugin struct r_asm_plugin_t
|
||||
typedef struct r_asm_t {
|
||||
const char *cpu;
|
||||
int bits;
|
||||
int big_endian;
|
||||
int syntax;
|
||||
char *cpu;
|
||||
int bits;
|
||||
int big_endian;
|
||||
int syntax;
|
||||
ut64 pc;
|
||||
void *user;
|
||||
_RAsmPlugin *cur;
|
||||
@ -124,6 +124,7 @@ R_API int r_asm_add(RAsm *a, RAsmPlugin *foo);
|
||||
R_API int r_asm_setup(RAsm *a, const char *arch, int bits, int big_endian);
|
||||
R_API int r_asm_use(RAsm *a, const char *name);
|
||||
R_API int r_asm_set_bits(RAsm *a, int bits);
|
||||
R_API void r_asm_set_cpu(RAsm *a, const char *cpu);
|
||||
R_API int r_asm_set_big_endian(RAsm *a, int boolean);
|
||||
R_API int r_asm_set_syntax(RAsm *a, int syntax);
|
||||
R_API int r_asm_set_pc(RAsm *a, ut64 pc);
|
||||
|
Loading…
Reference in New Issue
Block a user