* Fix push immediate opcode analysis in basic x86 analysis
* Import simple arm assembler * Some fixes for the brainfuck disassembler plugin
This commit is contained in:
parent
3455c738df
commit
183dffcd6b
13 changed files with 265 additions and 41 deletions
1
TODO
1
TODO
|
|
@ -10,6 +10,7 @@ Questions
|
|||
=========
|
||||
* Merge r_vm into r_anal ?
|
||||
* Merge r_vm into r_parse ?
|
||||
* Add rabin2 .! calls into r_core api? r_core_rabin_import(core, "rIs") ?
|
||||
|
||||
0.6 RELEASE
|
||||
===========
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ int main(int argc, char *argv[])
|
|||
return 0;
|
||||
}
|
||||
if (!r_asm_set_bits (a, bits))
|
||||
eprintf ("cannot set bits (triying with 32)\n");
|
||||
eprintf ("WARNING: cannot set asm backend to %d bits\n", bits);
|
||||
|
||||
if (file) {
|
||||
char *content;
|
||||
|
|
|
|||
26
doc/fortunes
26
doc/fortunes
|
|
@ -1,12 +1,12 @@
|
|||
Do you want to perform more than one search at a time? '> /k0 keyword1', '> /k1 keyword2' and '> /r 0-1'
|
||||
Debugger commands are prefixed with '!' because they are accessed via the io plugin system() hook
|
||||
Isn't your disassembly pretty enought? Try changing values with 'eval asm.'
|
||||
Isn't your disassembly pretty enought? Try changing values with 'e asm.'
|
||||
Did you setup your ~/.radarerc today?
|
||||
You can mark an offset in visual mode with the cursor and the ',' key. Later press '.' to go back
|
||||
You can debug a program from the graph view (ag command) using standard radare commands
|
||||
Before entering a 'call' you can identify the arguments passed to it using the 'pm xxi' command
|
||||
Use the '[' and ']' keys in visual mode to adjust the screen width (scr.width)
|
||||
Choose your architecture by typing: 'eval asm.arch=ppc' (or arm, java, m68k, intel, intel16 or intel64)
|
||||
Choose your architecture by typing: 'e asm.arch=ppc' (or arm, java, m68k, intel, intel16 or intel64)
|
||||
Move between your search hits in visual mode using the 'f' and 'F' keys
|
||||
Run python scripts with the python hack plugin. ('H python <filename>' command)
|
||||
Run LUA scripts with the lua hack plugin. ('H lua <filename>' command)
|
||||
|
|
@ -49,29 +49,29 @@ Walk inside your seek history with the 'u' command (undo), and 'U' for redo
|
|||
Use hasher to calculate hashes of portion blocks of a file
|
||||
Use zoom.byte=entropy and press 'z' in visual mode to zoom out to see the entropy of the whole file
|
||||
Use zoom.byte=printable in zoom mode (z key in visual mode) to find strings
|
||||
Set colors to your screen with 'eval scr.color=true'
|
||||
Set colors to your screen with 'e scr.color=true'
|
||||
Press 'C' in visual mode to toggle colors
|
||||
Trace the register changes when debugging with trace.cmtregs
|
||||
Move the comments to the right changing their margin with eval asm.cmtmargin
|
||||
Move the comments to the right changing their margin with e asm.cmtmargin
|
||||
Execute a command on the visual prompt with cmd.vprompt
|
||||
Reduce the delta where flag resolving by address is used with cfg.delta
|
||||
Disable these messages with eval cfg.fortunes=false in your ~/.radarerc
|
||||
Show offsets in graphs with 'eval graph.offset = true'
|
||||
Disable these messages with e cfg.fortunes=false in your ~/.radarerc
|
||||
Show offsets in graphs with 'e graph.offset = true'
|
||||
Follow a flag in disassembly view (avoids to disasemble out of the visibility of the flag) with asm.follow
|
||||
Execute a command every time a breakpoint is hitted with 'eval cmd.bp = !my-program'
|
||||
Disassemble in intel syntax with eval asm.syntax = intel
|
||||
Execute a command every time a breakpoint is hitted with 'e cmd.bp = !my-program'
|
||||
Disassemble in intel syntax with e asm.syntax = intel
|
||||
Change the UID of the debugged process with child.uid (requires root)
|
||||
Enable full backtrace with dbg.fullbt
|
||||
Manually modify the DRX registers of the child process with '!dr' command
|
||||
What do you want to debug today?
|
||||
Sniff your favorite libusb-based application with LD_PRELOAD=/usr/lib/libusbsniff.so ./your-program
|
||||
Use '!rsc spcc' to parse structures in memory using C programs
|
||||
Find cp850 strings with 'eval cfg.encoding=cp850' and '/s'
|
||||
Find cp850 strings with 'e cfg.encoding=cp850' and '/s'
|
||||
Enhace your graphs by increasing the size of the block and graph.depth eval variable
|
||||
Control the height of the terminal on serial consoles with eval scr.height
|
||||
Use eval file.id=true and eval file.flag=true in your ~/.radarerc to get symbols, strings, .. when loading
|
||||
Disassemble unsupported architectures with external objdump defined in eval asm.objdump. Use 'pd' command.
|
||||
Emulate the base address of a file with eval file.baddr
|
||||
Control the height of the terminal on serial consoles with e scr.height
|
||||
Use e file.id=true and e file.flag=true in your ~/.radarerc to get symbols, strings, .. when loading
|
||||
Disassemble unsupported architectures with external objdump defined in e asm.objdump. Use 'pd' command.
|
||||
Emulate the base address of a file with e file.baddr
|
||||
Dump the class header information with 'javasm -c <file.class>'. Plugind by radare if file.id=true
|
||||
Use gradare if you prefer simple frontend for gui users
|
||||
Feedback, bug reports, patches, ideas are welcome to the mailing list at radare.nopcode.org
|
||||
|
|
|
|||
|
|
@ -295,6 +295,12 @@ static int myaop(RAnal *anal, RAnalOp *aop, ut64 addr, const ut8 *data, int len)
|
|||
aop->ref = 0; // TODO value of register here! get_offset
|
||||
aop->stackptr = 4;
|
||||
break;
|
||||
case 0x6a: // push $7
|
||||
aop->type = R_ANAL_OP_TYPE_PUSH;
|
||||
aop->ref = buf[1];
|
||||
aop->stackptr = 4;
|
||||
break;
|
||||
break;
|
||||
case 0x5a:
|
||||
case 0x5b:
|
||||
case 0x5c:
|
||||
|
|
|
|||
216
libr/asm/arch/arm/armass.c
Normal file
216
libr/asm/arch/arm/armass.c
Normal file
|
|
@ -0,0 +1,216 @@
|
|||
/* radare - LGPL - Copyright 2010 pancake<@nopcode.org> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
|
||||
typedef struct {
|
||||
int o;
|
||||
char op[32];
|
||||
char *a0, *a1, *a2;
|
||||
} ArmOpcode;
|
||||
|
||||
typedef struct {
|
||||
const char *name;
|
||||
int code;
|
||||
int type;
|
||||
} ArmOp;
|
||||
|
||||
enum {
|
||||
TYPE_MOV = 1,
|
||||
TYPE_TST = 2,
|
||||
TYPE_SWI = 3,
|
||||
TYPE_BRA = 4,
|
||||
TYPE_ARI = 5,
|
||||
};
|
||||
|
||||
static ArmOp ops[] = {
|
||||
{ "adc", 0xa000, TYPE_ARI },
|
||||
{ "adcs", 0xb000, TYPE_ARI },
|
||||
{ "add", 0x8000, TYPE_ARI },
|
||||
{ "adds", 0x9000, TYPE_ARI },
|
||||
{ "sub", 0x4000, TYPE_ARI },
|
||||
{ "subs", 0x5000, TYPE_ARI },
|
||||
{ "sbc", 0xc000, TYPE_ARI },
|
||||
{ "sbcs", 0xd000, TYPE_ARI },
|
||||
{ "rsb", 0x6000, TYPE_ARI },
|
||||
{ "rsbs", 0x7000, TYPE_ARI },
|
||||
{ "rsc", 0xe000, TYPE_ARI },
|
||||
{ "rscs", 0xf000, TYPE_ARI },
|
||||
|
||||
{ "bl", 0xb, TYPE_BRA },
|
||||
{ "bx", 0xb, TYPE_BRA },
|
||||
{ "b", 0xa, TYPE_BRA },
|
||||
|
||||
{ "str", 0x4, TYPE_MOV },
|
||||
|
||||
{ "mov", 0x3, TYPE_MOV },
|
||||
{ "mvn", 0, TYPE_MOV },
|
||||
{ "svc", 0xf, TYPE_SWI }, // ???
|
||||
|
||||
{ "and", 0x0, TYPE_TST },
|
||||
{ "ands", 0x1000, TYPE_TST },
|
||||
{ "eor", 0x2000, TYPE_TST },
|
||||
{ "eors", 0x3000, TYPE_TST },
|
||||
{ "orr", 0x0, TYPE_TST },
|
||||
{ "bic", 0x0, TYPE_TST },
|
||||
|
||||
{ "cmp", 0x0, TYPE_TST },
|
||||
{ "cmn", 0x0, TYPE_TST },
|
||||
{ "teq", 0x0, TYPE_TST },
|
||||
{ "tst", 0xe1, TYPE_TST },
|
||||
NULL
|
||||
};
|
||||
|
||||
static int getnum(const char *str) {
|
||||
while (str&&(*str=='$'||*str=='#'))
|
||||
str++;
|
||||
if (*str=='0'&&str[1]=='x') {
|
||||
int x;
|
||||
if(sscanf(str+2, "%x", &x))
|
||||
return x;
|
||||
}
|
||||
return atoi(str);
|
||||
}
|
||||
|
||||
static int getreg(const char *str) {
|
||||
if (!str)
|
||||
return 0;
|
||||
if (!strcmp(str, "pc"))
|
||||
return 15;
|
||||
if (!strcmp(str, "lr"))
|
||||
return 14;
|
||||
if (!strcmp(str, "sp"))
|
||||
return 13;
|
||||
if (!strcmp(str, "ip"))
|
||||
return 12;
|
||||
if (!strcmp(str, "fp"))
|
||||
return 11;
|
||||
if (!strcmp(str, "sl"))
|
||||
return 10;
|
||||
if (*str=='r')
|
||||
return atoi (str+1);
|
||||
return 0; // XXX
|
||||
}
|
||||
|
||||
static int getshift(const char *str) {
|
||||
if(!str) return 0;
|
||||
while (str&&*str&&!atoi(str))
|
||||
str++;
|
||||
return atoi(str)/2;
|
||||
}
|
||||
|
||||
static void arm_opcode_parse(ArmOpcode *ao, const char *str) {
|
||||
memset (ao, 0, sizeof (ArmOpcode));
|
||||
strncpy (ao->op, str, sizeof(ao->op));
|
||||
ao->a0 = strchr (ao->op, ' ');
|
||||
if (ao->a0) {
|
||||
*ao->a0 = 0;
|
||||
ao->a1 = strchr (++ao->a0, ',');
|
||||
if (ao->a1) {
|
||||
*ao->a1 = 0;
|
||||
ao->a2 = strchr (++ao->a1, ',');
|
||||
if (ao->a2) {
|
||||
*ao->a2 = 0;
|
||||
ao->a2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (ao->a0&&*ao->a0==' ') ao->a0++;
|
||||
while (ao->a1&&*ao->a1==' ') ao->a1++;
|
||||
while (ao->a2&&*ao->a2==' ') ao->a2++;
|
||||
}
|
||||
|
||||
static int arm_opcode_cond(ArmOpcode *ao, int delta) {
|
||||
const char *conds[] = {
|
||||
"eq", "ne", "cs", "cc", "mi", "pl", "vs", "vc",
|
||||
"hi", "ls", "ge", "lt", "gt", "le", "al", "nv", 0
|
||||
};
|
||||
int i, cond = 14; // 'always' is default
|
||||
char *c = ao->op+delta;
|
||||
for(i=0;conds[i];i++) {
|
||||
if (!strcmp(c, conds[i])) {
|
||||
cond = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
ao->o |= cond<<4;
|
||||
}
|
||||
|
||||
static int arm_opcode_name(ArmOpcode *ao) {
|
||||
int i;
|
||||
for (i=0;ops[i].name;i++) {
|
||||
if (!memcmp(ao->op, ops[i].name, strlen (ops[i].name))) {
|
||||
ao->o = (ops[i].code);//<<24;
|
||||
arm_opcode_cond(ao, strlen(ops[i].name));
|
||||
switch(ops[i].type) {
|
||||
case TYPE_BRA:
|
||||
// XXX: Needs to calc (eip-off-8)>>2
|
||||
ao->o |= getnum(ao->a0)<<24;
|
||||
break;
|
||||
case TYPE_SWI:
|
||||
ao->o |= getnum(ao->a0)<<24;
|
||||
break;
|
||||
case TYPE_ARI:
|
||||
ao->o |= getreg(ao->a0)<<20;
|
||||
ao->o |= getreg(ao->a1)<<8;
|
||||
ao->o |= getreg(ao->a2)<<24;
|
||||
break;
|
||||
case TYPE_MOV:
|
||||
ao->o |= getreg(ao->a0)<<20;
|
||||
ao->o |= getnum(ao->a1)<<24;
|
||||
break;
|
||||
case TYPE_TST:
|
||||
ao->o |= getreg(ao->a0)<<20;
|
||||
ao->o |= getreg(ao->a1)<<24;
|
||||
ao->o |= getshift(ao->a2)<<16; // shift
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// XXX: check endian stuff
|
||||
int armass_assemble(const char *str) {
|
||||
ArmOpcode aop = {0};
|
||||
arm_opcode_parse (&aop, str);
|
||||
if (!arm_opcode_name (&aop)) {
|
||||
printf ("Unknown opcode\n");
|
||||
return -1;
|
||||
}
|
||||
////printf ("PARSE (%s) (%s)(%s)(%s)\n", aop.op, aop.a0, aop.a1, aop.a2);
|
||||
return aop.o;
|
||||
}
|
||||
|
||||
#ifdef MAIN
|
||||
void display(const char *str) {
|
||||
char cmd[32];
|
||||
int op = armass_assemble(str);
|
||||
printf("%08x %s\n", op, str);
|
||||
snprintf(cmd, sizeof(cmd), "rasm2 -d -a arm %08x", op);
|
||||
system(cmd);
|
||||
}
|
||||
|
||||
main() {
|
||||
#if 0
|
||||
display("mov r0, 33");
|
||||
display("mov r1, 33");
|
||||
display("movne r0, 33");
|
||||
display("tst r0, r1, lsl #2");
|
||||
display("svc 0x80");
|
||||
display("sub r3, r1, r2");
|
||||
display("add r0, r1, r2");
|
||||
display("mov fp, 0");
|
||||
#endif
|
||||
display("str r0, 33");
|
||||
display("bx 33");
|
||||
#if 0
|
||||
display("b 0x123");
|
||||
display("bl 0x123");
|
||||
display("blt 0x123"); // XXX: not supported
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
|
@ -1,5 +1,6 @@
|
|||
OBJ_ARM=asm_arm.o
|
||||
OBJ_ARM+=../arch/arm/gnu/arm-dis.o
|
||||
OBJ_ARM+=../arch/arm/armass.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_ARM}
|
||||
TARGET_ARM=asm_arm.${EXT_SO}
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
|
|
@ -79,6 +80,15 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut6
|
|||
return aop->inst_len;
|
||||
}
|
||||
|
||||
int armass_assemble(const char *str);
|
||||
static int assemble(RAsm *a, RAsmAop *aop, const char *buf) {
|
||||
int op = armass_assemble(buf);
|
||||
if (op==-1)
|
||||
return -1;
|
||||
r_mem_copyendian (aop->buf, &op, 4, a->big_endian);
|
||||
return (a->bits/8);
|
||||
}
|
||||
|
||||
RAsmPlugin r_asm_plugin_arm = {
|
||||
.name = "arm",
|
||||
.arch = "arm",
|
||||
|
|
@ -87,7 +97,7 @@ RAsmPlugin r_asm_plugin_arm = {
|
|||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
.assemble = NULL
|
||||
.assemble = &assemble
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - GPL3 - Copyright 2009 pancake <youterm.com> - nibble<.ds@gmail.com> */
|
||||
/* radare - GPL3 - Copyright 2009-2010 pancake <youterm.com> - nibble<.ds@gmail.com> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -8,8 +8,7 @@
|
|||
#include <r_asm.h>
|
||||
|
||||
|
||||
static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len)
|
||||
{
|
||||
static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut64 len) {
|
||||
int i;
|
||||
char *buf_cp, *b;
|
||||
|
||||
|
|
@ -64,9 +63,9 @@ static int disassemble(struct r_asm_t *a, struct r_asm_aop_t *aop, ut8 *buf, ut6
|
|||
|
||||
RAsmPlugin r_asm_plugin_bf = {
|
||||
.name = "bf",
|
||||
.arch = "brainfuck",
|
||||
.bits = (int[]){ 8, 0 },
|
||||
.desc = "BF disassembly plugin",
|
||||
.arch = "bf",
|
||||
.bits = (int[]){ 8, 16, 32, 0 }, // dummy
|
||||
.desc = "Brainfuck disassembly plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.disassemble = &disassemble,
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - GPL3 - Copyright 2009 nibble<.ds@gmail.com> */
|
||||
/* radare - GPL3 - Copyright 2009-2010 pancake<nopcode.org> nibble<.ds@gmail.com> */
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
|
@ -36,13 +36,9 @@ static int assemble(struct r_asm_t *a, struct r_asm_aop_t *aop, const char *buf)
|
|||
}
|
||||
}
|
||||
}
|
||||
aop->inst_len = Assemble((char*)buf, a->pc, &asm_obj, oattempt, oconstsize, aop->buf_err);
|
||||
if (aop->inst_len < 0)
|
||||
aop->inst_len = 0;
|
||||
|
||||
aop->inst_len = R_MAX (0, Assemble((char*)buf, a->pc, &asm_obj, oattempt, oconstsize, aop->buf_err));
|
||||
if (aop->inst_len > 0)
|
||||
memcpy(aop->buf, asm_obj.code, aop->inst_len<=R_ASM_BUFSIZE?aop->inst_len:R_ASM_BUFSIZE);
|
||||
|
||||
memcpy (aop->buf, asm_obj.code, R_MIN(aop->inst_len, R_ASM_BUFSIZE));
|
||||
return aop->inst_len;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1389,11 +1389,10 @@ static int cmd_print(void *data, const char *input) {
|
|||
int l, len = core->blocksize;
|
||||
ut32 tbs = core->blocksize;
|
||||
|
||||
/* XXX: This is only for pd/pD ??? */
|
||||
/* XXX: pd must change bs too */
|
||||
/* TODO: Change also blocksize for 'pd'.. */
|
||||
if (input[0] && input[1]) {
|
||||
l = (int) r_num_math (core->num, input+2);
|
||||
// exceptions are: disasm and memoryfmt */
|
||||
/* except disasm and memoryfmt (pd, pm) */
|
||||
if (input[0] != 'd' && input[0] != 'm') {
|
||||
if (l>0) len = l;
|
||||
if (l>tbs) r_core_block_size (core, l);
|
||||
|
|
|
|||
|
|
@ -539,10 +539,9 @@ reaccept:
|
|||
//pipe_stdout_to_tmp_file((char*)&buf, (char*)ptr+5);
|
||||
strcpy((char*)buf, "/tmp/.out");
|
||||
pipefd = r_cons_pipe_open ((const char *)buf, 0);
|
||||
eprintf("SYSTEM(%s)\n", ptr+6);
|
||||
//eprintf("SYSTEM(%s)\n", ptr+6);
|
||||
system((const char*)ptr+6);
|
||||
r_cons_pipe_close (pipefd);
|
||||
|
||||
{
|
||||
FILE *fd = fopen((char*)buf, "r");
|
||||
i = 0;
|
||||
|
|
|
|||
|
|
@ -3,11 +3,7 @@
|
|||
#include "r_core.h"
|
||||
#include "r_socket.h"
|
||||
|
||||
/* TODO: Move inside r_core */
|
||||
static const int endian = 0;
|
||||
//static int rtr_n = 0;
|
||||
//static struct rtr_host_t rtr_host[RTR_MAX_HOSTS];
|
||||
|
||||
#define endian core->assembler->big_endian
|
||||
#define rtr_n core->rtr_n
|
||||
#define rtr_host core->rtr_host
|
||||
|
||||
|
|
@ -77,7 +73,7 @@ R_API void r_core_rtr_add(RCore *core, const char *_input) {
|
|||
char input[1024], *host = NULL, *file = NULL, *ptr = NULL, buf[1024];
|
||||
int proto, port, fd, i;
|
||||
|
||||
strncpy (input, _input, 1020);
|
||||
strncpy (input, _input, sizeof (input)-4);
|
||||
/* Parse uri */
|
||||
if ((ptr = strstr(input, "tcp://"))) {
|
||||
proto = RTR_PROT_TCP;
|
||||
|
|
@ -127,7 +123,7 @@ R_API void r_core_rtr_add(RCore *core, const char *_input) {
|
|||
/* read */
|
||||
eprintf ("waiting... "); fflush(stdout);
|
||||
r_socket_read (fd, (ut8*)buf, 5);
|
||||
r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, endian);
|
||||
r_mem_copyendian ((ut8 *)&i, (ut8*)buf+1, 4, core->assembler->big_endian);
|
||||
if (buf[0] != (char)(RTR_RAP_OPEN|RTR_RAP_REPLY) || i<= 0) {
|
||||
eprintf ("Error: Wrong reply\n");
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -46,10 +46,11 @@ R_API int r_syscall_setup(RSyscall *ctx, const char *arch, const char *os) {
|
|||
if (!strcmp (arch, "arm")) {
|
||||
if (!strcmp (os, "linux"))
|
||||
ctx->sysptr = syscalls_linux_arm;
|
||||
else
|
||||
if (!strcmp (os, "macos") || !strcmp (os, "darwin"))
|
||||
ctx->sysptr = syscalls_darwin_arm;
|
||||
else {
|
||||
eprintf ("r_syscall_setup: Unknown arch '%s'\n", arch);
|
||||
eprintf ("r_syscall_setup: Unknown OS '%s'\n", os);
|
||||
return R_FALSE;
|
||||
}
|
||||
} else
|
||||
|
|
|
|||
Loading…
Reference in a new issue