* 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:
parent
0e98ad3b37
commit
1f7f9dc036
2
TODO
2
TODO
|
@ -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
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
program=/usr/bin/find
|
||||
arg0=/
|
||||
timeout=2
|
|
@ -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;
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 :(
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
203
libr/egg/lang.c
203
libr/egg/lang.c
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
main@global(128) {
|
||||
#// printf ("Hello World\n");
|
||||
: nop
|
||||
: mov eax, 1
|
||||
: push eax
|
||||
: int 0x80
|
||||
}
|
|
@ -23,6 +23,7 @@ exit@global() {
|
|||
: mov eax, 1
|
||||
: push eax
|
||||
: int 0x80
|
||||
: add esp, 4
|
||||
}
|
||||
|
||||
main@global(128) {
|
||||
|
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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@
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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))
|
||||
|
|
Loading…
Reference in New Issue