mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-24 16:23:49 +00:00
* Add 'avrr' and 'avrc' commands to setup vm regs
* Many minor random fixes * RVm api has an own architecture description file - r_vm_set_arch(vm, arch, bits); - add x86-16, x86-32, x86-64, arm-32
This commit is contained in:
parent
4d50a86855
commit
8f6bdc3560
8
TODO
8
TODO
@ -60,15 +60,9 @@ TODO edu
|
||||
|
||||
TODO pancake
|
||||
------------
|
||||
* r_asm must provide a template configuration file for r_vm
|
||||
- r_asm must provide evaluable strings as internal representation (microcode)
|
||||
* Import r_vm register values from flags or from r_debug->r_reg
|
||||
- r_vm must use mmu cache when emulating code
|
||||
- use the one from r_io? and deprecate vm->mmu_cache?
|
||||
- as r_debug does for r_reg
|
||||
.-----------------.
|
||||
| r_asm > r_vm |
|
||||
| r_debug > r_reg |
|
||||
`-----------------'
|
||||
{
|
||||
* Implement RAnalCall (analyze function arguments, return values, propagate types..)
|
||||
- define number of arguments for given function
|
||||
|
@ -347,7 +347,7 @@ static void r_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len,
|
||||
switch (analop.type) {
|
||||
case R_ANAL_OP_TYPE_SWI:
|
||||
{
|
||||
int eax = (int)r_vm_reg_get (core->vm, "eax");
|
||||
int eax = (int)r_vm_reg_get (core->vm, core->vm->cpu.ret); //"eax");
|
||||
RSyscallItem *si = r_syscall_get (core->syscall, eax, (int)analop.value);
|
||||
if (si) {
|
||||
//DEBUG r_cons_printf (" ; sc[0x%x][%d]=%s(", (int)analop.value, eax, si->name);
|
||||
@ -2050,6 +2050,8 @@ static int cmd_anal(void *data, const char *input) {
|
||||
" avx N ; execute N instructions from cur seek\n"
|
||||
" av- ; restart vm using asm.arch\n"
|
||||
" avr eax ; show register eax\n"
|
||||
" avrr eax ; set return register\n" // TODO .merge avrr and avrc
|
||||
" avrc eip esp ebp ; set basic cpu registers PC, SP, BP\n"
|
||||
" avra ; show register aliases\n"
|
||||
" avra al eax=0xff ; define 'get' alias for register 'al'\n"
|
||||
" avrt ; list valid register types\n"
|
||||
@ -2742,7 +2744,7 @@ static int cmd_meta(void *data, const char *input) {
|
||||
case ' ':
|
||||
{
|
||||
int size;
|
||||
const char *fmt= NULL;
|
||||
const char *fmt = NULL;
|
||||
const char *ptr, *name = input+2;
|
||||
ptr = strchr (name, ' ');
|
||||
if (ptr) {
|
||||
@ -2940,6 +2942,7 @@ static int r_core_cmd_pipe(RCore *core, char *radare_cmd, char *shell_cmd) {
|
||||
return status;
|
||||
#else
|
||||
#warning r_core_cmd_pipe UNIMPLEMENTED FOR THIS PLATFORM
|
||||
eprintf ("r_core_cmd_pipe: unimplemented for this platform\n");
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
|
@ -115,6 +115,7 @@ static int config_asmarch_callback(void *user, void *data) {
|
||||
if (!r_syscall_setup (core->syscall, node->value,
|
||||
r_config_get (core->config, "asm.os")))
|
||||
eprintf ("asm.arch: Cannot setup syscall os/arch for '%s'\n", node->value);
|
||||
r_vm_set_arch (core->vm, node->value, core->assembler->bits);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
@ -143,6 +144,8 @@ static int config_asm_bits_callback(void *user, void *data) {
|
||||
}
|
||||
if (!r_anal_set_bits (core->anal, node->i_value))
|
||||
eprintf ("asm.arch: Cannot setup '%i' bits analysis engine\n", (int)node->i_value);
|
||||
if(core->assembler->cur)
|
||||
r_vm_set_arch (core->vm, core->assembler->cur->name, node->i_value);
|
||||
// TODO: change debugger backend bit profile here
|
||||
return ret;
|
||||
}
|
||||
|
@ -87,7 +87,6 @@ typedef struct r_asm_plugin_t {
|
||||
int *bits;
|
||||
int (*init)(void *user);
|
||||
int (*fini)(void *user);
|
||||
const char *(*profile)();
|
||||
int (*disassemble)(RAsm *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len);
|
||||
int (*assemble)(RAsm *a, struct r_asm_aop_t *aop, const char *buf);
|
||||
RAsmModifyCallback modify;
|
||||
|
@ -83,9 +83,11 @@ static ut64 r_vm_get_math(struct r_vm_t *vm, const char *str);
|
||||
R_API void r_vm_print(struct r_vm_t *vm, int type);
|
||||
R_API int r_vm_import(struct r_vm_t *vm, int in_vm);
|
||||
R_API void r_vm_cpu_call(struct r_vm_t *vm, ut64 addr);
|
||||
R_API int r_vm_set_arch(RVm *vm, const char *name, int bits);
|
||||
R_API RVm *r_vm_new();
|
||||
R_API void r_vm_reset(RVm *vm);
|
||||
R_API int r_vm_init(struct r_vm_t *vm, int init);
|
||||
R_API int r_vm_cmd_eval(RVm *vm, const char *cmd);
|
||||
R_API int r_vm_eval_cmp(struct r_vm_t *vm, const char *str);
|
||||
R_API int r_vm_eval_eq(struct r_vm_t *vm, const char *str, const char *val);
|
||||
R_API int r_vm_eval_single(struct r_vm_t *vm, const char *str);
|
||||
|
@ -24,7 +24,7 @@ R_API struct r_io_t *r_io_new() {
|
||||
}
|
||||
|
||||
R_API int r_io_is_listener(RIO *io) {
|
||||
if (io->plugin->listener)
|
||||
if (io && io->plugin && io->plugin->listener)
|
||||
return io->plugin->listener (io);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ R_API int r_syscall_setup_file(RSyscall *ctx, const char *path) {
|
||||
|
||||
R_API RSyscallItem *r_syscall_get(RSyscall *ctx, int num, int swi) {
|
||||
int i;
|
||||
for (i=0; ctx->sysptr[i].num; i++) {
|
||||
for (i=0; ctx->sysptr[i].name; i++) {
|
||||
if (num == ctx->sysptr[i].num && \
|
||||
(swi == -1 || swi == ctx->sysptr[i].swi))
|
||||
return &ctx->sysptr[i];
|
||||
|
@ -1,6 +1,9 @@
|
||||
NAME=r_vm
|
||||
DEPS=r_util
|
||||
|
||||
OBJ=vm.o mmu.o reg.o extra.o setup.o stack.o op.o
|
||||
OBJ=p/plugins.h vm.o mmu.o reg.o extra.o setup.o stack.o op.o
|
||||
|
||||
include ../rules.mk
|
||||
|
||||
p/plugins.h:
|
||||
cd p && ${MAKE} plugins.h
|
||||
|
13
libr/vm/op.c
13
libr/vm/op.c
@ -1,4 +1,4 @@
|
||||
/* radare - LGPL - Copyright 2008-2009 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2008-2010 pancake<nopcode.org> */
|
||||
|
||||
#include "r_vm.h"
|
||||
|
||||
@ -24,6 +24,7 @@ R_API int r_vm_op_eval(struct r_vm_t *vm, const char *str) {
|
||||
memcpy(s, str, len);
|
||||
r_str_subchr (s, ',', 0);
|
||||
r_str_subchr (s, '\t', 0);
|
||||
r_str_subchr (s, '#', 0);
|
||||
|
||||
nargs = r_str_word_set0(s);
|
||||
arg0 = r_str_word_get0(s, 0);
|
||||
@ -80,7 +81,7 @@ R_API int r_vm_op_eval(struct r_vm_t *vm, const char *str) {
|
||||
}
|
||||
|
||||
/* TODO : Allow to remove and so on */
|
||||
R_API int r_vm_op_cmd(struct r_vm_t *vm, const char *op) {
|
||||
R_API int r_vm_op_cmd(RVm *vm, const char *op) {
|
||||
char *cmd, *ptr;
|
||||
int len = strlen (op)+1;
|
||||
if (*op==' ')
|
||||
@ -89,9 +90,13 @@ R_API int r_vm_op_cmd(struct r_vm_t *vm, const char *op) {
|
||||
memcpy (cmd, op, len);
|
||||
ptr = strchr (cmd, ' ');
|
||||
if (ptr) {
|
||||
// XXX: merge those two functions in one
|
||||
ptr[0]='\0';
|
||||
// eprintf("vm: opcode '%s' added\n", cmd);
|
||||
r_vm_op_add (vm, cmd, ptr+1);
|
||||
if (!memcmp (op, "avo", 3)) {
|
||||
r_vm_op_add (vm, cmd, ptr+1);
|
||||
if (vm->log)
|
||||
eprintf("vm: opcode '%s' added\n", cmd);
|
||||
} else r_vm_cmd_reg (vm, op);
|
||||
} else r_vm_cmd_op_help ();
|
||||
return 0;
|
||||
}
|
||||
|
15
libr/vm/p/Makefile
Normal file
15
libr/vm/p/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
PLUGINS=x86.16 x86.32 x86.64 arm.32
|
||||
|
||||
all: plugins.h
|
||||
|
||||
plugins.h:
|
||||
:> plugins.h
|
||||
for a in ${PLUGINS} ; do \
|
||||
echo "static const char *vmprofile_$${a} = \\" | sed -e 's,\.,_,g' > $${a}.h ; \
|
||||
cat $${a}.vm | sed -e 's,^,\t",' -e 's,\.,_,g' -e 's,$$,\\n",g' >> $${a}.h ; \
|
||||
echo ";" >> $${a}.h ; \
|
||||
echo "#include \"$${a}.h\"" >> plugins.h ; \
|
||||
done
|
||||
|
||||
clean:
|
||||
rm -f *.h
|
31
libr/vm/p/arm.32.vm
Normal file
31
libr/vm/p/arm.32.vm
Normal file
@ -0,0 +1,31 @@
|
||||
avr+ r0 int32
|
||||
avr+ r1 int32
|
||||
avr+ r2 int32
|
||||
avr+ r3 int32
|
||||
avr+ r4 int32
|
||||
avr+ r5 int32
|
||||
avr+ r6 int32
|
||||
avr+ r7 int32
|
||||
avr+ r8 int32
|
||||
avr+ r9 int32
|
||||
avr+ r10 int32
|
||||
avr+ r11 int32
|
||||
avr+ r12 int32
|
||||
avr+ r13 int32
|
||||
avr+ r14 int32
|
||||
avr+ r15 int32
|
||||
avra pc r15
|
||||
avra sp r14
|
||||
avo mov $1=$2
|
||||
avo cmp tmp=$1,$1-=$2,$1=tmp
|
||||
avo sub $1=$2-$3
|
||||
avo add $1=$2+$3
|
||||
avo strb $2=$1
|
||||
avo bne jnz $1
|
||||
avo beq jz $1
|
||||
avo b jmp $1
|
||||
avo bl call $1
|
||||
avo svc int $1
|
||||
avrc pc sp bp
|
||||
avrf zf
|
||||
avrr r0
|
29
libr/vm/p/x86.16.vm
Normal file
29
libr/vm/p/x86.16.vm
Normal file
@ -0,0 +1,29 @@
|
||||
avo mov $1=$2
|
||||
avo lea $1=$2
|
||||
avo add $1=$1+$2
|
||||
avo sub $1=$1-$2
|
||||
avo jmp eip=$1
|
||||
avo push esp=esp-4,[esp]=$1
|
||||
avo pop $1=[esp],esp=esp+4
|
||||
avo call esp=esp-4,[esp]=eip+$$$,eip=$1
|
||||
avo ret eip=[esp],esp=esp+4
|
||||
avr+ eax int32
|
||||
avr+ ebx int32
|
||||
avr+ ecx int32
|
||||
avr+ edx int32
|
||||
avr+ esi int32
|
||||
avr+ edi int32
|
||||
avr+ eip int32
|
||||
avr+ esp int32
|
||||
avr+ ebp int32
|
||||
avr+ ax int16
|
||||
avr+ zf bit
|
||||
avr+ cf bit
|
||||
avra ax ax=eax&0xffff eax=eax>16,eax=eax<16 eax=eax|ax
|
||||
avr+ al int8
|
||||
avr+ ah int8
|
||||
avra al al=eax&0xff al=al&0xff,eax=eax>16,eax=eax<16,eax=eax|al
|
||||
avra ah ah=eax&0xff00,ah=ah>8 eax=eax&0xFFFF00ff,ah=ah<8,eax=eax|ah,ah=ah>8
|
||||
avrc eip esp ebp
|
||||
avrf zf
|
||||
avrr eax
|
30
libr/vm/p/x86.32.vm
Normal file
30
libr/vm/p/x86.32.vm
Normal file
@ -0,0 +1,30 @@
|
||||
avo mov $1=$2
|
||||
avo lea $1=$2
|
||||
avo add $1=$1+$2
|
||||
avo sub $1=$1-$2
|
||||
avo jmp eip=$1
|
||||
avo cmp tmp=$1,$1-=$2,$1=tmp
|
||||
avo push esp=esp-4,[esp]=$1
|
||||
avo pop $1=[esp],esp=esp+4
|
||||
avo call esp=esp-4,[esp]=eip+$$$,eip=$1
|
||||
avo ret eip=[esp],esp=esp+4
|
||||
avr+ eax int32
|
||||
avr+ ebx int32
|
||||
avr+ ecx int32
|
||||
avr+ edx int32
|
||||
avr+ esi int32
|
||||
avr+ edi int32
|
||||
avr+ eip int32
|
||||
avr+ esp int32
|
||||
avr+ ebp int32
|
||||
avr+ ax int16
|
||||
avr+ zf bit
|
||||
avr+ cf bit
|
||||
avra ax ax=eax&0xffff eax=eax>16,eax=eax<16 eax=eax|ax
|
||||
avr+ al int8
|
||||
avr+ ah int8
|
||||
avra al al=eax&0xff al=al&0xff,eax=eax>16,eax=eax<16,eax=eax|al
|
||||
avra ah ah=eax&0xff00,ah=ah>8 eax=eax&0xFFFF00ff,ah=ah<8,eax=eax|ah,ah=ah>8
|
||||
avrc eip esp ebp
|
||||
avrf zf
|
||||
avrr eax
|
30
libr/vm/p/x86.64.vm
Normal file
30
libr/vm/p/x86.64.vm
Normal file
@ -0,0 +1,30 @@
|
||||
avo mov $1=$2
|
||||
avo lea $1=$2
|
||||
avo add $1=$1+$2
|
||||
avo sub $1=$1-$2
|
||||
avo jmp rip=$1
|
||||
avo push rsp=rsp-4,[rsp]=$1
|
||||
avo pop $1=[rsp],rsp=rsp+4
|
||||
avo call rsp=esp-4,[rsp]=rip+$$$,rip=$1
|
||||
avo ret rip=[rsp],rsp=rsp+4
|
||||
avr+ rax int64
|
||||
avr+ rbx int64
|
||||
avr+ rcx int64
|
||||
avr+ rdx int64
|
||||
avr+ rsi int64
|
||||
avr+ rdi int64
|
||||
avr+ rip int64
|
||||
avr+ rsp int64
|
||||
avr+ rbp int64
|
||||
avr+ eax int32
|
||||
avr+ ax int16
|
||||
avr+ zf bit
|
||||
avr+ cf bit
|
||||
avra ax ax=eax&0xffff eax=eax>16,eax=eax<16 eax=eax|ax
|
||||
avr+ al int8
|
||||
avr+ ah int8
|
||||
avra al al=eax&0xff al=al&0xff,rax=eax>16,eax=eax<16,eax=eax|al
|
||||
avra ah ah=eax&0xff00,ah=ah>8 eax=eax&0xFFFF00ff,ah=ah<8,eax=eax|ah,ah=ah>8
|
||||
avrc rip rsp rbp
|
||||
avrf zf
|
||||
avrr rax
|
@ -63,6 +63,7 @@ R_API int r_vm_reg_del(struct r_vm_t *vm, const char *name) {
|
||||
R_API int r_vm_reg_set(struct r_vm_t *vm, const char *name, ut64 value) {
|
||||
struct list_head *pos;
|
||||
|
||||
if(name)
|
||||
list_for_each(pos, &vm->regs) {
|
||||
struct r_vm_reg_t *r = list_entry(pos, struct r_vm_reg_t, list);
|
||||
if (!strcmp(name, r->name)) {
|
||||
@ -118,24 +119,59 @@ int r_vm_reg_alias(struct r_vm_t *vm, const char *name, const char *get, const c
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
fprintf(stderr, "Register '%s' not defined.\n", name);
|
||||
eprintf ("Register '%s' not defined.\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API int r_vm_cmd_eval(RVm *vm, const char *cmd) {
|
||||
char *next;
|
||||
do {
|
||||
next = strchr (cmd,'\n');
|
||||
if (next) {
|
||||
*next=0;
|
||||
next++;
|
||||
}
|
||||
if (strlen(cmd)>2)
|
||||
r_vm_cmd_reg (vm, cmd+2);
|
||||
cmd = next;
|
||||
} while (next);
|
||||
return 1;
|
||||
}
|
||||
|
||||
R_API int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str) {
|
||||
char *str, *ptr;
|
||||
int len;
|
||||
|
||||
len = strlen(_str)+1;
|
||||
str = alloca(len);
|
||||
memcpy(str, _str, len);
|
||||
len = strlen (_str)+1;
|
||||
str = alloca (len);
|
||||
memcpy (str, _str, len);
|
||||
|
||||
if (str==NULL || str[0]=='\0') {
|
||||
/* show all registers */
|
||||
r_vm_print(vm, -1);
|
||||
r_vm_print (vm, -1);
|
||||
return 0;
|
||||
}
|
||||
if (str[0]=='o') {
|
||||
r_vm_cmd_op (vm, str+2);
|
||||
return 0;
|
||||
}
|
||||
strcpy(str, str+1);
|
||||
switch(str[0]) {
|
||||
case 'r':
|
||||
r_vm_setup_ret (vm, str+2);
|
||||
break;
|
||||
case 'c':
|
||||
{
|
||||
char *sp, *bp, *pc = str+2;
|
||||
sp = strchr(pc, ' ');
|
||||
if (!sp) return 0;
|
||||
*sp=0;sp++;
|
||||
bp = strchr(sp, ' ');
|
||||
if (!sp) return 0;
|
||||
*bp=0;bp++;
|
||||
r_vm_setup_cpu (vm, pc, sp, bp);
|
||||
}
|
||||
break;
|
||||
case 'a':
|
||||
if (str[1]==' ') {
|
||||
char *get,*set;
|
||||
@ -174,6 +210,9 @@ R_API int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str) {
|
||||
INIT_LIST_HEAD(&vm->regs); // XXX Memory leak
|
||||
else r_vm_reg_del(vm, str);
|
||||
break;
|
||||
case 'f':
|
||||
r_vm_setup_flags(vm, str+2);
|
||||
break;
|
||||
default:
|
||||
for(;str&&*str==' ';str=str+1);
|
||||
ptr = strchr(str, '=');
|
||||
@ -191,7 +230,7 @@ R_API int r_vm_cmd_reg(struct r_vm_t *vm, const char *_str) {
|
||||
r_vm_print(vm, r_vm_reg_type_i(str+1));
|
||||
} else {
|
||||
/* show single registers */
|
||||
printf("%s = 0x%08"PFMT64x"\n", str, r_vm_reg_get(vm, str));
|
||||
eprintf("%s = 0x%08"PFMT64x"\n", str, r_vm_reg_get(vm, str));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
143
libr/vm/vm.c
143
libr/vm/vm.c
@ -1,6 +1,7 @@
|
||||
/* radare - LGPL - Copyright 2008-2010 pancake<nopcode.org> */
|
||||
|
||||
#include "r_vm.h"
|
||||
#include "p/plugins.h"
|
||||
|
||||
/* TODO: move into r_vm_t */
|
||||
int vm_arch = -1;
|
||||
@ -14,8 +15,8 @@ static ut64 r_vm_get_value(struct r_vm_t *vm, const char *str) {
|
||||
struct aop_t aop;
|
||||
char w[32];
|
||||
if (str[2]=='$') { // $$$
|
||||
ret = r_vm_reg_get(vm, vm->cpu.pc);
|
||||
arch_aop(ret , config.block,&aop);
|
||||
ret = r_vm_reg_get (vm, vm->cpu.pc);
|
||||
arch_aop (ret , config.block, &aop);
|
||||
return aop.length;
|
||||
} else // $$
|
||||
return config.seek;
|
||||
@ -23,11 +24,11 @@ static ut64 r_vm_get_value(struct r_vm_t *vm, const char *str) {
|
||||
}
|
||||
|
||||
if (str[0]=='0' && str[1]=='x')
|
||||
sscanf(str, "0x%"PFMT64x"", &ret);
|
||||
sscanf (str, "0x%"PFMT64x"", &ret);
|
||||
else
|
||||
if (str[0]>='0' && str[0]<='9')
|
||||
sscanf(str, "%"PFMT64d"", &ret);
|
||||
else ret = r_vm_reg_get(vm, str);
|
||||
sscanf (str, "%"PFMT64d"", &ret);
|
||||
else ret = r_vm_reg_get (vm, str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -100,10 +101,10 @@ R_API void r_vm_print(RVm *vm, int type) {
|
||||
list_for_each (pos, &vm->regs) {
|
||||
struct r_vm_reg_t *r = list_entry(pos, struct r_vm_reg_t, list);
|
||||
if (type == -2) {
|
||||
printf("f vm.%s @ 0x%08"PFMT64x"\n", r->name, r->value);
|
||||
eprintf("f vm.%s @ 0x%08"PFMT64x"\n", r->name, r->value);
|
||||
} else {
|
||||
if (type == -1 || type == r->type)
|
||||
printf(".%s\t%s = 0x%08"PFMT64x"\n",
|
||||
eprintf(".%s\t%s = 0x%08"PFMT64x"\n",
|
||||
r_vm_reg_type(r->type), r->name,
|
||||
(r->get!=NULL)?r_vm_reg_get(vm, r->name):r->value);
|
||||
}
|
||||
@ -135,9 +136,9 @@ R_API ut64 r_vm_reg_get(struct r_vm_t *vm, const char *name) {
|
||||
if (name[len-1]==']')
|
||||
len--;
|
||||
|
||||
list_for_each(pos, &vm->regs) {
|
||||
struct r_vm_reg_t *r = list_entry(pos, struct r_vm_reg_t, list);
|
||||
if (!strncmp(name, r->name, len)) {
|
||||
list_for_each (pos, &vm->regs) {
|
||||
RVmReg *r = list_entry(pos, struct r_vm_reg_t, list);
|
||||
if (!strncmp (name, r->name, len)) {
|
||||
if (vm->rec==NULL && r->get != NULL) {
|
||||
vm->rec = r;
|
||||
r_vm_eval(vm, r->get);
|
||||
@ -175,11 +176,47 @@ R_API void r_vm_cpu_call(struct r_vm_t *vm, ut64 addr) {
|
||||
|
||||
R_API RVm *r_vm_new() {
|
||||
RVm *vm = R_NEW (RVm);
|
||||
r_vm_init (vm, 1);
|
||||
if (vm) r_vm_init (vm, 1);
|
||||
return vm;
|
||||
}
|
||||
|
||||
R_API int r_vm_init(struct r_vm_t *vm, int init) {
|
||||
|
||||
R_API int r_vm_set_arch(RVm *vm, const char *name, int bits) {
|
||||
const char *profile = NULL;
|
||||
if (strstr (name, "x86")) {
|
||||
switch (bits) {
|
||||
case 16:
|
||||
profile = vmprofile_x86_16;
|
||||
break;
|
||||
case 32:
|
||||
profile = vmprofile_x86_32;
|
||||
break;
|
||||
case 64:
|
||||
profile = vmprofile_x86_64;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
if (strstr (name, "arm")) {
|
||||
switch (bits) {
|
||||
case 16:
|
||||
//profile = vmprofile_arm_16;
|
||||
break;
|
||||
case 32:
|
||||
profile = vmprofile_arm_32;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (profile) {
|
||||
char *str = strdup (profile);
|
||||
r_vm_init (vm, 2);
|
||||
r_vm_cmd_eval (vm, str);
|
||||
free (str);
|
||||
} else eprintf ("No profile found for '%s' %d\n", name, bits);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// This is conceptually rotten
|
||||
R_API int r_vm_init(RVm *vm, int init) {
|
||||
#if 0
|
||||
if (config.arch != vm_arch)
|
||||
init = 1;
|
||||
@ -191,80 +228,16 @@ R_API int r_vm_init(struct r_vm_t *vm, int init) {
|
||||
INIT_LIST_HEAD (&vm->regs);
|
||||
INIT_LIST_HEAD (&vm->ops);
|
||||
memset (&vm->cpu, '\0', sizeof(RVmCpu));
|
||||
if (init==2)
|
||||
return 0;
|
||||
}
|
||||
|
||||
//vm_mmu_real(vm, config_get_i("vm.realio"));
|
||||
/* vm_dbg_arch_x86_nregs */
|
||||
/* XXX: this is hardcoded ..should be moved outside or as in plugins */
|
||||
switch (1) { //config.arch) {
|
||||
#if 0
|
||||
case ARCH_X86_64:
|
||||
vm_reg_add("rax", R_VMREG_INT64, 0);
|
||||
vm_reg_add("rbx", R_VMREG_INT64, 0);
|
||||
vm_reg_add("rcx", R_VMREG_INT64, 0);
|
||||
vm_reg_add("rdx", R_VMREG_INT64, 0);
|
||||
vm_reg_add("rdi", R_VMREG_INT64, 0);
|
||||
vm_reg_add("rsi", R_VMREG_INT64, 0);
|
||||
vm_reg_add("rip", R_VMREG_INT64, 0);
|
||||
case ARCH_X86:
|
||||
#endif
|
||||
default:
|
||||
//fprintf(stderr,"R_VM: Initialized\n");
|
||||
r_vm_op_add(vm,"mov", "$1=$2");
|
||||
r_vm_op_add(vm,"lea", "$1=$2");
|
||||
r_vm_op_add(vm,"add", "$1=$1+$2");
|
||||
r_vm_op_add(vm,"sub", "$1=$1-$2");
|
||||
r_vm_op_add(vm,"jmp", "eip=$1");
|
||||
r_vm_op_add(vm,"push", "esp=esp-4,[esp]=$1");
|
||||
r_vm_op_add(vm,"pop", "$1=[esp],esp=esp+4");
|
||||
r_vm_op_add(vm,"call", "esp=esp-4,[esp]=eip+$$$,eip=$1");
|
||||
r_vm_op_add(vm,"ret", "eip=[esp],esp=esp+4");
|
||||
|
||||
r_vm_reg_add(vm,"eax", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"ax", R_VMREG_INT16, 0);
|
||||
r_vm_reg_alias(vm, "ax","ax=eax&0xffff", "eax=eax>16,eax=eax<16,eax=eax|ax");
|
||||
r_vm_reg_add(vm,"al", R_VMREG_INT8, 0);
|
||||
r_vm_reg_alias(vm, "al","al=eax&0xff", "al=al&0xff,eax=eax>16,eax=eax<16,eax=eax|al");
|
||||
r_vm_reg_add(vm,"ah", R_VMREG_INT8, 0);
|
||||
r_vm_reg_alias(vm, "ah","ah=eax&0xff00,ah=ah>8", "eax=eax&0xFFFF00ff,ah=ah<8,eax=eax|ah,ah=ah>8");
|
||||
r_vm_reg_add(vm,"ebx", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"ecx", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"edx", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"esi", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"edi", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"eip", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"esp", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"ebp", R_VMREG_INT32, 0);
|
||||
r_vm_reg_add(vm,"zf", R_VMREG_BIT, 0);
|
||||
r_vm_reg_add(vm,"cf", R_VMREG_BIT, 0); // ...
|
||||
|
||||
r_vm_setup_cpu(vm, "eip", "esp", "ebp");
|
||||
r_vm_setup_flags(vm, "zf");
|
||||
//vm_setup_call("[ebp-4]", "[ebp-8]", "[ebp-12]", "edx");
|
||||
r_vm_setup_fastcall(vm, "eax", "ebx", "ecx", "edx");
|
||||
//vm_setup_loop("ecx");
|
||||
//vm_setup_copy("esi", "edi");
|
||||
r_vm_setup_ret(vm, "eax");
|
||||
// TODO: do the same for fpregs and mmregs
|
||||
#if 0
|
||||
if (init) // XXX
|
||||
r_vm_arch_x86_init(vm);
|
||||
#endif
|
||||
break;
|
||||
#if 0
|
||||
case ARCH_MIPS:
|
||||
#if 0
|
||||
vm_nregs = vm_arch_mips_nregs;
|
||||
vm_regs = vm_arch_mips_regs;
|
||||
vm_regs_str = vm_arch_mips_regs_str;
|
||||
#endif
|
||||
// TODO: do the same for fpregs and mmregs
|
||||
if (init)
|
||||
vm_arch_mips_init();
|
||||
break;
|
||||
//vm_regs = NULL;
|
||||
#endif
|
||||
}
|
||||
//vm_setup_call("[ebp-4]", "[ebp-8]", "[ebp-12]", "edx");
|
||||
r_vm_setup_fastcall (vm, "eax", "ebx", "ecx", "edx");
|
||||
//vm_setup_loop("ecx");
|
||||
//vm_setup_copy("esi", "edi");
|
||||
// TODO: do the same for fpregs and mmregs
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -408,6 +381,7 @@ R_API int r_vm_eval_single(RVm *vm, const char *str) {
|
||||
ptr = alloca(len);
|
||||
memcpy(ptr, str, len);
|
||||
|
||||
//eprintf("EVAL(%s)\n", str);
|
||||
/* TODO: sync with r1 */
|
||||
eq = strchr(ptr, '=');
|
||||
if (eq) {
|
||||
@ -593,7 +567,8 @@ R_API int r_vm_cmd_op(RVm *vm, const char *op) {
|
||||
ptr = strchr (cmd, ' ');
|
||||
if (ptr) {
|
||||
ptr[0]='\0';
|
||||
eprintf ("vm: opcode '%s' added\n", cmd);
|
||||
if(vm->log)
|
||||
eprintf ("vm: opcode '%s' added\n", cmd);
|
||||
r_vm_op_add (vm, cmd, ptr+1);
|
||||
} else r_vm_cmd_op_help ();
|
||||
return 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user