* Enhacements for rarun2

- add 'timeout' directive
  - directives can now be passed in arguments
  - support more than 3 args for launching
  - show default config file in help
* Added test suite for r_egg
  - Fix nested conditional and loops
  - Some situations can result in broken code
  - Code needs a huge cleanup
* Varioues fixes for x86.nz plugin to make r_egg happy
* Install python plugins into dist-packages only
  - site-packages is not the right place
* Add R2_LIBDIR and R2_PREFIX constants
* Honor LIBDIR in sdbpath for r_syscall
* Fix rabin2 -h for -C
This commit is contained in:
pancake 2011-10-24 04:35:42 +02:00
parent 0e98ad3b37
commit 1f7f9dc036
31 changed files with 606 additions and 130 deletions

2
TODO
View File

@ -7,8 +7,8 @@
====[[ 0.9 ]]====
* rasm2 must support binary creation help message or so.. rabin2 integration must be easier
* Add support for 'expect' like foo in rarun2
- add support for exectimeout in rarun2
* TODO: make elf/pe get_os() and others return const and not strdup
* 'ao' must be for bytes count, not bytes
* asm.pseudo for brainfuck

View File

@ -54,7 +54,7 @@ static int rabin_show_help() {
" -a [arch_bits] set arch (x86_32, arm_32, x86_64)\n"
" -b [addr] override baddr\n"
" -c [fmt:C:D] create [elf,mach0,pe] with Code and Data hexpairs (see -a)\n"
" -C [fmt:C:D] list classes\n"
" -C list classes\n"
" -p [patchfile] patch file (see man rabin2)\n"
" -e entrypoint\n"
" -f [str] select sub-bin named str\n"

View File

@ -5,11 +5,13 @@
#include <unistd.h>
#include <fcntl.h>
#include <r_util.h>
#if __UNIX__
#include <signal.h>
#endif
#define NARGS (sizeof (_args)/sizeof(*_args))
static char *_args[512] = {NULL};
static char *_arg0 = NULL;
static char *_arg1 = NULL;
static char *_arg2 = NULL;
static char *_arg3 = NULL;
static char *_program = NULL;
static char *_stdin = NULL;
static char *_stdout = NULL;
@ -22,6 +24,7 @@ static char *_seteuid = NULL;
static char *_setgid = NULL;
static char *_setegid = NULL;
static char *_input = NULL;
static int _timeout = 0;
static void parseline (char *b) {
char *e = strchr (b, '=');
@ -30,7 +33,7 @@ static void parseline (char *b) {
*e++ = 0;
if (*e=='$') e = r_sys_getenv (e);
if (e == NULL) return;
if (!strcmp (b, "program")) _program = strdup (e);
if (!strcmp (b, "program")) _args[0] = _program = strdup (e);
else if (!strcmp (b, "stdout")) _stdout = strdup (e);
else if (!strcmp (b, "stdin")) _stdin = strdup (e);
else if (!strcmp (b, "input")) _input = strdup (e);
@ -41,14 +44,16 @@ static void parseline (char *b) {
else if (!strcmp (b, "seteuid")) _seteuid = strdup (e);
else if (!strcmp (b, "setgid")) _setgid = strdup (e);
else if (!strcmp (b, "setegid")) _setegid = strdup (e);
else if (!strcmp (b, "arg0")) _arg0 = strdup (e);
else if (!strcmp (b, "arg1")) _arg1 = strdup (e);
else if (!strcmp (b, "arg2")) _arg2 = strdup (e);
else if (!strcmp (b, "arg3")) _arg3 = strdup (e);
else if (!memcmp (b, "arg", 3)) {
int n = atoi (b+3);
if (n>=0 && n<NARGS) {
_args[n] = strdup (e);
} else fprintf (stderr, "Out of bounds args index: %d\n", n);
} else if (!strcmp (b, "timeout")) _timeout = atoi (e);
else if (!strcmp (b, "setenv")) {
char *v = strchr (e, '=');
if (v) {
*v++=0;
*v++ = 0;
r_sys_setenv (e, v);
}
}
@ -67,7 +72,6 @@ static void parseinput (char *s) {
#endif
static int runfile () {
int ret;
if (!_program) {
printf ("No program rule defined\n");
return 1;
@ -109,30 +113,65 @@ static int runfile () {
r_sys_setenv ("LD_PRELOAD", _preload);
#endif
}
ret = execl (_program, _program, _arg0, NULL);
printf ("RETURN VALUE = %d\n", ret);
return 0;
if (_timeout) {
#if __UNIX__
int mypid = getpid ();
if (!fork ()) {
sleep (_timeout);
if (!kill (mypid, 0))
fprintf (stderr, "\nInterrupted by timeout\n");
kill (mypid, SIGKILL);
exit (0);
}
#else
eprintf ("timeout not supported for this platform\n");
#endif
}
exit (execv (_program, _args));
}
int main(int argc, char **argv) {
int i;
FILE *fd;
char *file, buf[1024];
if (argc==1 || !strcmp (argv[1], "-h")) {
printf ("Usage: rarun2 [script.rr2]\n");
fprintf (stderr, "Usage: rarun2 [''|script.rr2] [options ...]\n"
"> options are file directives:\n");
printf (
"program=/bin/ls\n"
"arg1=/bin\n"
"# arg#=...\n"
"setenv=FOO=BAR\n"
"timeout=3\n"
"# stdout=foo.txt\n"
"# stdin=input.txt\n"
"# input=input.txt\n"
"# chdir=/\n"
"# chroot=/mnt/chroot\n"
"# preload=/lib/libfoo.so\n"
"# setuid=2000\n"
"# seteuid=2000\n"
"# setgid=2001\n"
"# setegid=2001\n");
return 1;
}
file = argv[1];
fd = fopen (file, "r");
if (!fd) {
fprintf (stderr, "Cannot open %s\n", file);
return 1;
if (*file) {
fd = fopen (file, "r");
if (!fd) {
fprintf (stderr, "Cannot open %s\n", file);
return 1;
}
for (;;) {
fgets (buf, sizeof (buf)-1, fd);
if (feof (fd)) break;
buf[strlen (buf)-1] = 0;
parseline (buf);
}
fclose (fd);
} else {
for (i=2; i<argc; i++)
parseline (argv[i]);
}
for (;;) {
fgets (buf, sizeof (buf)-1, fd);
if (feof (fd)) break;
buf[strlen (buf)-1] = 0;
parseline (buf);
}
fclose (fd);
return runfile ();
}

3
binr/rarun2/timeout Normal file
View File

@ -0,0 +1,3 @@
program=/usr/bin/find
arg0=/
timeout=2

View File

@ -381,6 +381,7 @@ R_API RAsmCode* r_asm_massemble(RAsm *a, const char *buf) {
if (stage != 2) {
*ptr = 0;
snprintf (food, sizeof (food), "0x%"PFMT64x"", off);
// TODO: warning when redefined
r_asm_code_set_equ (acode, ptr_start, food);
}
ptr_start = ptr + 1;

View File

@ -24,13 +24,15 @@ static int jop (ut64 addr, ut8 *data, ut8 a, ut8 b, const char *arg) {
if (!isnum (arg))
return 0;
dst32 = num - addr;
d = num - addr;
d = num - addr; // obey sign
#if 0
if (d>-127 && d<127) {
d-=2;
data[l++] = a;
data[l++] = (char)d;
return 2;
}
#endif
data[l++] = 0x0f;
data[l++] = b;
dst32 -= 6;
@ -133,10 +135,26 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
arg++;
pfx = 0;
if (delta) {
data[l++] = 0x83;
data[l++] = 0x40 | getreg (arg); // XXX: hardcoded
data[l++] = getnum (delta+1);
data[l++] = getnum (arg2);
int n = getnum (arg2);
int d = getnum (delta+1);
int r = getreg (arg);
if (d<127 && d>-127) {
data[l++] = 0x83;
data[l++] = 0x40 | getreg (arg); // XXX: hardcoded
data[l++] = getnum (delta+1);
data[l++] = getnum (arg2);
} else {
ut8 *ptr = (ut8 *)&d;
data[l++] = 0x83;
data[l++] = 0x80|r;
data[l++] = ptr[0];
data[l++] = ptr[1];
data[l++] = ptr[2];
data[l++] = ptr[3];
// XXX: for big numbere here
data[l++] = n;
}
return l;
}
} else pfx = 0xc0;
@ -172,25 +190,34 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
int pfx;
if (*arg=='[') {
char *delta = strchr (arg+1, '+');
if (!delta) delta = strchr (arg+1,'-');
arg++;
parg0 = 1;
pfx = 0;
if (delta) {
int n = getnum (arg2);
if (n>127 || n<-127) {
ut8 *ptr = (ut8 *)&n;
int d = getnum (delta+1);
int r = getreg (arg);
if (d<127 && d>-127) {
data[l++] = 0x83;
data[l++] = 0x6d; // XXX hardcoded
data[l++] = d;
data[l++] = n;
} else {
ut8 *ptr = (ut8 *)&d;
data[l++] = 0x81;
data[l++] = 0x68; //pfx | getreg (arg);
data[l++] = getnum (delta+1); //0x04;
data[l++] = 0xa8|r;
data[l++] = ptr[0];
data[l++] = ptr[1];
data[l++] = ptr[2];
data[l++] = ptr[3];
ptr = (ut8*)&n;
data[l++] = ptr[0];
data[l++] = ptr[1];
data[l++] = ptr[2];
data[l++] = ptr[3];
} else {
data[l++] = 0x83;
data[l++] = 0x6d; // XXX hardcoded
data[l++] = getnum (delta+1);
data[l++] = getnum (arg2);
}
return l;
}
@ -298,7 +325,7 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
data[l++] = '\xff';
data[l] = getreg (arg) | 0xd0;
if (data[l] == 0xff) {
eprintf ("Invalid argument for 'call' (%s)\n", arg);
//eprintf ("Invalid argument for 'call' (%s)\n", arg);
return 0;
}
l++;
@ -327,14 +354,27 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
if (*arg=='[') {
arg++;
delta = strchr (arg, '+');
if (!delta) delta = strchr (arg,'-');
if (delta) {
int r = getreg (arg);
int d = getnum (delta+1);
if (*delta=='-') d = -d;
*delta++ = 0;
data[l++] = 0xff;
data[l++] = 0x70 | r;
if (r==4)
data[l++]=0x24; // wtf
data[l++] = getnum (delta);
if (d<127 && d>-127) {
data[l++] = 0x70 | r;
if (r==4)
data[l++]=0x24; // wtf
data[l++] = d;
} else {
data[l++] = 0xb0 | r;
addr = d;
ptr = (ut8 *)&addr;
data[l++] = ptr[0];
data[l++] = ptr[1];
data[l++] = ptr[2];
data[l++] = ptr[3];
}
} else {
int r = getreg (arg);
data[l++] = 0xff;
@ -351,6 +391,10 @@ static int assemble(RAsm *a, RAsmOp *ao, const char *str) {
dst = r_num_math (NULL, arg);
addr = dst;
ptr = (ut8 *)&addr;
if (!arg) {
eprintf ("Missing argument for push\n");
return 0;
}
if (!isnum (arg)) {
ut8 ch = getreg (arg) | 0x50;
if (ch == 0xff) {

View File

@ -2081,7 +2081,7 @@ static int cmd_flag(void *data, const char *input) {
break;
case 'o':
{
char *file = PREFIX"/share/doc/radare2/fortunes";
char *file = R2_PREFIX"/share/doc/radare2/fortunes";
char *line = r_file_slurp_random_line (file);
if (line) {
r_cons_printf (" -- %s\n", line);

View File

@ -196,7 +196,7 @@ R_API int r_egg_compile(REgg *egg) {
const char *b = (const char *)egg->src->buf;
if (!b || !egg->emit)
return R_FALSE;
for (;*b;b++) {
for (; *b; b++) {
r_egg_lang_parsechar (egg, *b);
// XXX: some parse fail errors are false positives :(
}

View File

@ -213,8 +213,7 @@ static void emit_restore_stack (REgg *egg, int size) {
}
static void emit_get_while_end (REgg *egg, char *str, const char *ctxpush, const char *label) {
if (attsyntax) sprintf (str, " push %s\n jmp %s /* ---- */\n", ctxpush, label);
else sprintf (str, " push %s\n jmp %s\n", ctxpush, label);
sprintf (str, " push %s\n jmp %s\n", ctxpush, label);
}
static void emit_while_end (REgg *egg, const char *labelback) {
@ -231,15 +230,8 @@ static void emit_while_end (REgg *egg, const char *labelback) {
// }
}
// XXX: this is wrong
static void emit_get_var (REgg *egg, int type, char *out, int idx) {
// TODO: deprecate or gtfo
if (attsyntax) {
switch (type) {
case 0: sprintf (out, "%d(%%"R_BP")", -idx); break; /* variable */
case 1: sprintf (out, "%d(%%"R_SP")", idx); break; /* argument */
}
return;
}
switch (type) {
case 0: /* variable */
if (idx>0) sprintf (out, "["R_BP"+%d]", idx);
@ -253,6 +245,11 @@ idx = 8; // HACK to make arg0, arg4, ... work
else if (idx<0) sprintf (out, "["R_SP"%d]", idx);
else strcpy (out, "["R_SP"]");
break;
case 2:
if (idx>0) sprintf (out, "["R_BP"+%d]", idx);
else if (idx<0) sprintf (out, "["R_BP"%d]", idx);
else strcpy (out, "["R_BP"]");
break;
}
}

View File

@ -2,8 +2,33 @@
#include <r_egg.h>
#define isspace(x) IS_WHITESPACE(x)
#define IS_VAR(x) (x[0]=='.'||((x[0]=='*'||x[0]=='&')&&x[1]=='.'))
char *nested[32] = {0};
char *nestede[32] = {0};
int nestedi[32] = {0};
static inline int is_var(char *x) {
return (x[0]=='.'||((x[0]=='*'||x[0]=='&')&&x[1]=='.'));
}
static inline int is_space(char c) {
return (c==' '||c=='\t'||c=='\n'||c=='\r');
}
static const char *skipspaces(const char *s) {
while (is_space (*s))
s++;
return s;
}
/* chop word by space/tab/.. */
/* NOTE: ensure string does not starts with spaces */
static char *trim(char *s) {
char *o;
for (o=s; *o; o++)
if (is_space (*o))
*o = 0;
return s;
}
static void rcc_pushstr(REgg *egg, char *str, int filter);
static void rcc_context(REgg *egg, int delta);
@ -120,30 +145,6 @@ R_API void r_egg_lang_include_init (REgg *egg) {
r_sys_setenv (R_EGG_INCDIR_ENV, ".:"R_EGG_INCDIR_PATH);
}
static const char *skipspaces(const char *s) {
for (;*s;s++)
switch (*s) {
case '\n':
case '\r':
case '\t':
case ' ':
break;
default:
return s;
}
return s;
}
static char *trim(char *s) {
char *o;
for (o=s; *s; s++)
if (isspace (*s)) {
*s = 0;
break;
}
return o;
}
static void rcc_set_callname(const char *s) {
free (callname);
callname = NULL;
@ -185,6 +186,7 @@ static char *get_end_frame_label(REgg *egg) {
static char label[128];
snprintf (label, sizeof (label)-1, FRAME_END_FMT,
nfunctions, nbrackets, context-1);
//eprintf ("--> (endframe: %d %d %d)\n", nfunctions, nbrackets, context);
//snprintf (label, sizeof (label)-1, "frame_end_%d_%d", nfunctions, nbrackets);
return label;
}
@ -301,7 +303,7 @@ R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) {
if ( (q = strchr (str, ':')) ) {
*q = '\0';
qi = atoi (q+1);
varsize = (qi==1)? 'b':'l';
varsize = (qi==1)? 'b': 'l';
} else varsize='l';
if (*str=='*'||*str=='&') {
varxs = *str;
@ -324,15 +326,10 @@ R_API char *r_egg_mkvar(REgg *egg, char *out, const char *_str, int delta) {
} else
if (!memcmp (str+1, "arg", 3)) {
if (str[4]) {
if (stackframe == 0)
e->get_var (egg, 1, out, idx);
else {
/* XXX: must simplify */
if (docall)
e->get_var (egg, 0, out,
-(delta+e->size*2+(e->size*(atoi(str+4)))));
else e->get_var (egg, 1, out,
delta+(e->size*(atoi(str+4))));
if (stackframe == 0) {
e->get_var (egg, 1, out, 4); //idx-4);
} else {
e->get_var (egg, 2, out, idx+4);
}
} else {
/* TODO: return size of syscall */
@ -380,13 +377,11 @@ static void rcc_fun(REgg *egg, const char *str) {
*ptr++ = '\0';
free (dstvar);
dstvar = strdup (skipspaces (str));
ptr2 = (char *)skipspaces(ptr);
if (*ptr2) {
ptr2 = (char *)skipspaces (ptr);
if (*ptr2)
rcc_set_callname (skipspaces (ptr));
}
} else {
str = skipspaces (str);
free (callname);
rcc_set_callname (skipspaces (str));
egg->emit->comment (egg, "rcc_fun %d (%s)", context, callname);
}
@ -462,10 +457,44 @@ static void rcc_fun(REgg *egg, const char *str) {
}
}
#if 0
static void shownested() {
int i;
eprintf ("[[[NESTED %d]]] ", context);
for(i=0;nested[i];i++) {
eprintf ("%s ", nested[i]);
}
eprintf("\n");
}
#endif
static void set_nested(const char *s) {
int c = context-1;
int i=0;
if (context<1)
return;
free (nested[c]);
nested[c] = strdup (s);
nestedi[c]++;
/** clear inner levels **/
for (i=0; i<10; i++) {
//nestedi[context+i] = 0;
free (nested[context+i]);
nested[context+i] = NULL;
}
}
static void rcc_context(REgg *egg, int delta) {
REggEmit *emit = egg->emit;
char str[64];
int c = context-1;
nestedi[context-1]++;
if (callname && context>0) {// && delta>0) {
// set_nested (callname);
//eprintf (" - - - - - - - set nested d=%d c=%d (%s)\n", delta, context-1, callname);
//shownested();
}
context += delta;
lastctxdelta = delta;
@ -476,29 +505,67 @@ static void rcc_context(REgg *egg, int delta) {
mode = NORMAL;
} else {
/* conditional block */
if (callname) {
//eprintf ("Callname is (%s)\n", callname);
const char *elm = skipspaces (elem);
const char *cn = callname;
//if (nested[context-1])
#if 0
if (delta<0 && context>0) {
eprintf ("close bracket foo!!!\n");
shownested ();
cn = strdup (nested[context-1]);
eprintf ("STATEMENT cn=(%s) idx=%d (%s)\n", cn, context-1, nested[context-1]);
eprintf ("CNTXXXPUSH (%s)\n", ctxpush[context-1]);
#if 0
if (!strcmp (cn, "while")) {
emit->while_end (egg, get_frame_label (context-1));
//char *var = get_frame_label (0);
//emit->jmp (egg, var, 0);
return;
}
#endif
}
#endif
//eprintf ("ELEM (%s)\n", elm);
//eprintf ("END BLOCK %d, (%s)\n", context, nested[context-1]);
//eprintf ("CN = (%s) %d (%s) delta=%d\n", cn, context, nested[context-1], delta);
if (cn) {
//if (callname) { // handle 'foo() {'
/* TODO: this must be an array */
char *b, *g, *e, *n;
emit->comment (egg, "cond frame %s (%s)", callname, elem);
emit->comment (egg, "cond frame %s (%s)", cn, elm);
/* TODO: simplify with a single for */
b = strchr (elem, '<'); /* below */
g = strchr (elem, '>'); /* greater */
e = strchr (elem, '='); /* equal */
n = strchr (elem, '!'); /* negate */
if (!strcmp (callname, "while")) {
emit->get_while_end (egg, str, ctxpush[context-1], get_frame_label (2));
free (endframe);
endframe = strdup (str);
rcc_set_callname ("if");
if (!strcmp (cn, "while")) {
char lab[128];
sprintf (lab, "__begin_%d_%d_%d", nfunctions, context-1, nestedi[context-1]);
emit->get_while_end (egg, str, ctxpush[context-1], lab); //get_frame_label (2));
//get_frame_label (2));
//eprintf ("------ (%s)\n", ctxpush[context-1]);
// free (endframe);
// XXX: endframe is deprecated, must use set_nested only
if (delta>0) {
set_nested (str);
}
rcc_set_callname ("if"); // append 'if' body
}
if (!strcmp (callname, "if")) {
emit->branch (egg, b, g, e, n, varsize, get_end_frame_label (egg));
if (!strcmp (cn, "if")) {
//emit->branch (egg, b, g, e, n, varsize, get_end_frame_label (egg));
// HACK HACK :D
sprintf (str, "__end_%d_%d_%d", nfunctions, context-1, nestedi[context-1]);
nestede[context-1] = strdup (str);
sprintf (str, "__end_%d_%d_%d", nfunctions, context, nestedi[context-1]);
emit->branch (egg, b, g, e, n, varsize, str);
if (context>0) {
/* XXX .. */
} else eprintf ("FUCKING CASE\n");
rcc_reset_callname ();
} else eprintf ("Unknown statement (%s)(%s)\n", callname, elem);
}
} //else eprintf ("Unknown statement (%s)(%s)\n", cn, elem);
} // handle '{ ..'
}
}
@ -522,7 +589,7 @@ static int parsedatachar(REgg *egg, char c) {
}
/* capture body */
if (c == '}') { /* XXX: repeated code!! */
if (context < 2) {
if (context < 1) {
inlinectr = 0;
rcc_context (egg, -1);
slurp = 0;
@ -533,7 +600,7 @@ static int parsedatachar(REgg *egg, char c) {
egg->emit->comment (egg, "data (%s)(%s)size=(%d)\n",
dstvar, dstval, stackframe);
r_egg_printf (egg, ".data\n");
for (str=dstval; isspace (*str); str++);
for (str=dstval; is_space (*str); str++);
j = (stackframe)? stackframe: 1;
/* emit label */
r_egg_printf (egg, "%s:\n", dstvar);
@ -663,9 +730,11 @@ static void rcc_next(REgg *egg) {
e->call (egg, str, 1);
else
if (!strcmp (str, "while")) {
char var[128];
if (lastctxdelta>=0)
exit (eprintf ("ERROR: Unsupported while syntax\n"));
e->while_end (egg, get_frame_label (1));
sprintf (var, "__begin_%d_%d_%d\n", nfunctions, context, nestedi[context-1]);
e->while_end (egg, var); //get_frame_label (1));
#if 0
eprintf ("------------------------------------------ lastctx: %d\n", lastctxdelta);
// TODO: the pushvar is required for the if(){}while(); constructions
@ -758,7 +827,7 @@ static void rcc_next(REgg *egg) {
eq = (char*) skipspaces (eq+1);
p = r_egg_mkvar (egg, str2, ptr, 0);
vs = varsize;
if (IS_VAR (eq)) {
if (is_var (eq)) {
eq = r_egg_mkvar (egg, buf, eq, 0);
if (varxs=='*')
e->load (egg, eq, varsize);
@ -790,6 +859,7 @@ R_API int r_egg_lang_parsechar(REgg *egg, char c) {
line++;
elem_n = 0;
}
//eprintf ("CH %c\n", c);
/* comments */
if (skipline) {
if (c != '\n') {
@ -860,18 +930,29 @@ R_API int r_egg_lang_parsechar(REgg *egg, char c) {
slurp = ')';
break;
case '{':
if (context>0)
r_egg_printf (egg, " %s:\n", get_frame_label (0));
if (context>0) {
// r_egg_printf (egg, " %s:\n", get_frame_label (0));
r_egg_printf (egg, " __begin_%d_%d_%d:\n",
nfunctions, context, nestedi[context]); //%s:\n", get_frame_label (0));
}
rcc_context (egg, 1);
break;
case '}':
endframe = nested[context-1];
if (endframe) {
// XXX: use endframe[context]
r_egg_printf (egg, "%s\n", endframe);
R_FREE (endframe);
// R_FREE (endframe);
}
if (context>0) {
r_egg_printf (egg, " %s:\n", get_end_frame_label (egg));
if (context>0) {
if (nestede[context]) {
r_egg_printf (egg, "%s:\n", nestede[context]);
//nestede[context] = NULL;
} else {
r_egg_printf (egg, " __end_%d_%d_%d:\n",
nfunctions, context, nestedi[context-1]);
//get_end_frame_label (egg));
}
nbrackets++;
}
rcc_context (egg, -1);
@ -901,7 +982,7 @@ R_API int r_egg_lang_parsechar(REgg *egg, char c) {
if (elem_n) {
ptr = elem;
elem[elem_n] = '\0';
while (isspace (*ptr)) ptr++;
while (is_space (*ptr)) ptr++;
rcc_fun (egg, ptr);
}
elem_n = 0;

View File

@ -1,3 +1,12 @@
TESTS=exit1 hello loop loop2 fun fun2 fun3 fun4
TESTS+=nest nest2
#ARG PASSING ERR
TESTS+=fun5
#INVALID SYNTAX
#TESTS+=looptail
include ../../config.mk
BINDEPS=r_egg r_util r_asm r_syscall r_db
@ -10,6 +19,11 @@ all: test${EXT_EXE}
test${EXT_EXE}: test.o
${CC} ${CFLAGS} test.o ${LDFLAGS} -o test${EXT_EXE}
.PHONY: t
t tests:
@for a in ${TESTS} ; do sh t-$$a.sh ; done
myclean:
rm -f test${EXT_EXE} test.o

7
libr/egg/t/exit.r Normal file
View File

@ -0,0 +1,7 @@
main@global(128) {
#// printf ("Hello World\n");
: nop
: mov eax, 1
: push eax
: int 0x80
}

View File

@ -23,6 +23,7 @@ exit@global() {
: mov eax, 1
: push eax
: int 0x80
: add esp, 4
}
main@global(128) {

12
libr/egg/t/t-exit1.sh Executable file
View File

@ -0,0 +1,12 @@
#!/bin/sh
EXIT=1
OUTPUT=""
cat > t.r <<EOF
main@global(128) {
: push 1
: mov eax, 1
: push eax
: int 0x80
}
EOF
. ./t.sh

22
libr/egg/t/t-fun.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main();
fun@global(128,128) {
write (1, "loop\n", 5);
}
main@global(128,128) {
.var0 = 0;
while (.var0<2) {
fun ("loop\n", 5);
.var0 += 1;
}
exit (0);
}
EOF
. ./t.sh

22
libr/egg/t/t-fun2.sh Executable file
View File

@ -0,0 +1,22 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main();
fun@global() {
write (1, .arg0, .arg1);
}
main@global(128,128) {
.var0 = 0;
while (.var0<2) {
fun ("loop\n", 5);
.var0 += 1;
}
exit (0);
}
EOF
. ./t.sh

24
libr/egg/t/t-fun3.sh Executable file
View File

@ -0,0 +1,24 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main();
fun@() {
write (1, .arg0, .arg4);
}
main@global(128,128) {
.var0 = 0;
while (.var0<2) {
fun ("loop\n", 5);
.var0 += 1;
}
exit (0);
}
EOF
. ./t.sh

28
libr/egg/t/t-fun4.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main();
fun2@(128) {
write (.arg0, .arg4, .arg8);
}
fun@(128) {
fun2 (1, .arg0, .arg4);
}
main@global(128,128) {
.var0 = 0;
while (.var0<2) {
fun ("loop\n", 5);
.var0 += 1;
}
exit (0);
}
EOF
. ./t.sh

28
libr/egg/t/t-fun5.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main();
fun2@() {
write (.arg0, .arg4, .arg8);
}
fun@() {
fun2 (1, .arg0, .arg4);
}
main@global(128,128) {
.var0 = 0;
while (.var0<2) {
fun ("loop\n", 5);
.var0 += 1;
}
exit (0);
}
EOF
. ./t.sh

13
libr/egg/t/t-hello.sh Executable file
View File

@ -0,0 +1,13 @@
#!/bin/sh
EXIT=0
OUTPUT="hello world"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main@global(128,128) {
write (1, "hello world\n", 12);
exit (0);
}
EOF
. ./t.sh

19
libr/egg/t/t-loop.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main@global(128,128) {
.var0 = 3;
while (.var0) {
write (1, "loop\n", 5);
.var0 -= 1;
}
exit (0);
}
EOF
. ./t.sh

18
libr/egg/t/t-loop2.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main@global(128,128) {
.var0 = 0;
while (.var0<2) {
write (1, "loop\n", 5);
.var0 += 1;
}
exit (0);
}
EOF
. ./t.sh

19
libr/egg/t/t-looptail.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/sh
EXIT=0
OUTPUT="loop
loop
loop"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main@global(128,128) {
.var0 = 3;
{
write (1, "loop\n", 5);
.var0 -= 1;
} while (.var0);
exit (0);
}
EOF
. ./t.sh

30
libr/egg/t/t-nest.sh Executable file
View File

@ -0,0 +1,30 @@
#!/bin/sh
EXIT=0
OUTPUT="one
one
two
one
one
two"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main@global(128,128) {
.var0 = 2;
: polla:
.var4 = 2;
while (.var4) {
write (1, "one\n", 4);
.var4 -= 1;
}
write (1, "two\n", 4);
.var0 -= 1;
if (.var0) {
goto(polla);
}
exit (0);
}
EOF
. ./t.sh

28
libr/egg/t/t-nest2.sh Executable file
View File

@ -0,0 +1,28 @@
#!/bin/sh
EXIT=0
OUTPUT="one
one
two
one
one
two"
cat > t.r <<EOF
exit@syscall(1);
write@syscall(4);
main@global(128,128) {
.var0 = 2;
while (.var0) {
.var4 = 2;
while (.var4) {
write (1, "one\n", 4);
.var4 -= 1;
}
write (1, "two\n", 4);
.var0 -= 1;
}
exit (0);
}
EOF
. ./t.sh

19
libr/egg/t/t.sh Executable file
View File

@ -0,0 +1,19 @@
if [ "$1" = -s ]; then
ragg2 -s t.r > fail-t-$0.s
cp t fail-t-$0
exit 0
fi
ragg2 -FO t.r
rarun2 '' program=./t timeout=1 > t.o
#2>/dev/null
if [ $? = "${EXIT}" -a "`cat t.o`" = "${OUTPUT}" ]; then
out=SUCCESS
rm -f fail-t-$0*
else
out=FAIL
ragg2 -s t.r > fail-t-$0.s
cp -f t fail-t-$0
cp -f t.r fail-t-$0.r
fi
echo "Testing $0.. $out"
rm -f t.r t.o

View File

@ -1,7 +1,14 @@
/* test calling a function */
call@global(128) {
.arg0
}
main@global(128) {
#// printf ("Hello World\n");
: nop
: mov eax, 1
: push eax
: int 0x80
call(1,2);
}

View File

@ -7,10 +7,8 @@
#define LIL_ENDIAN @LIL_ENDIAN@
#define DEBUGGER @DEBUGGER@
#ifdef PREFIX
#undef PREFIX
#endif
#define PREFIX "@PREFIX@"
#define R2_PREFIX "@PREFIX@"
#define R2_LIBDIR "@LIBDIR@"
#define R2_VERSION "@VERSION@"
#define HAVE_LIB_MAGIC @HAVE_LIB_MAGIC@

View File

@ -37,7 +37,7 @@ R_API const char *r_syscall_reg(RSyscall *s, int idx, int num) {
R_API int r_syscall_setup(RSyscall *ctx, const char *arch, const char *os, int bits) {
char file[64];
#define SYSCALLPATH "lib/radare2/"R2_VERSION"/syscall"
#define SYSCALLPATH "radare2/"R2_VERSION"/syscall"
if (os == NULL)
os = R_SYS_OS;
if (arch == NULL)
@ -59,7 +59,7 @@ R_API int r_syscall_setup(RSyscall *ctx, const char *arch, const char *os, int b
ctx->regs = fastcall_sh;
}
snprintf (file, sizeof (file), PREFIX"/%s/%s-%s-%d.sdb",
snprintf (file, sizeof (file), R2_LIBDIR"/%s/%s-%s-%d.sdb",
SYSCALLPATH, os, arch, bits);
if (!r_file_exist (file)) {
//eprintf ("r_syscall_setup: Cannot find '%s'\n", file);

View File

@ -121,16 +121,17 @@ install-python:
E=${SOEXT} ; \
[ `uname` = Darwin ] && E=so ; \
a=python${PYTHON_VERSION} ; \
echo "Installing $$a/site-packages r2 modules in ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2" ; \
mkdir -p ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2 ; \
touch ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2/__init__.py ; \
cp -rf python/r_*.py python/*.$$E ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2/ ; \
echo "Installing $$a/dist-packages r2 modules in ${DESTDIR}${PREFIX}/lib/$$a/dist-packages/r2" ; \
mkdir -p ${DESTDIR}${PREFIX}/lib/$$a/dist-packages/r2 ; \
cp -rf python/r_*.py python/*.$$E ${DESTDIR}${PREFIX}/lib/$$a/dist-packages/r2/ ; \
touch ${DESTDIR}${PREFIX}/lib/$$a/dist-packages/r2/__init__.py ; \
fi
# echo "Installing $$a/site-packages r2 modules in ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2" ; \
# mkdir -p ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2 ; \
# touch ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2/__init__.py ; \
# cp -rf python/r_*.py python/*.$$E ${DESTDIR}${PREFIX}/lib/$$a/site-packages/r2/ ; \
install-lua:
@if [ "`grep lua supported.langs`" ]; then \
for a in 5.1 ; do \

View File

@ -58,6 +58,7 @@
s (r_list_get_n sects idx)
name (get-string s)
size (get-long (+ s NSZ))
; XXX for 64bits
vsize (get-long (+ s NSZ 8))
rva (get-long (+ s NSZ 16))
offset (get-long (+ s NSZ 24))