6 Commits
Author SHA1 Message Date
pancake bb011f88af Release 0.6 2016-12-12 00:22:39 +01:00
pancake c5498bd961 Add llvm bitcode build target 2015-06-19 10:13:03 +02:00
pancake a173daa812 Add -c and -q 2013-09-16 03:51:14 +02:00
pancake 9096ed5126 Add 'ired.js' target 2013-09-16 03:05:13 +02:00
pancake b074f2280d Initial import of calc.c . needs cleanup 2013-07-08 04:10:42 +02:00
pancake ec8e0225c3 Many bug fixes for vired. Added 'd' command to disassemble 2013-07-08 03:43:44 +02:00
7 changed files with 431 additions and 34 deletions

No files matched your search

+9 -3
View File
@@ -1,8 +1,8 @@
CC?=gcc
VERSION=0.5
VERSION=0.6git
CCw32?=i486-mingw32-gcc
CFLAGS+=-O2 -Wall
CFLAGS+=-DVERSION=\"${VERSION}\"
#CFLAGS+=-DVERSION=\"${VERSION}\"
PREFIX?=/usr/local
DESTDIR?=
@@ -11,7 +11,13 @@ all: ired bdiff
bdiff: bdiff.o
${CC} ${CFLAGS} bdiff.o -o bdiff
ired.o: cmd.c io.c util.c hexparse.c
ired.o: calc.c cmd.c io.c util.c hexparse.c
ired.js:
emcc -o ired.js ired.c
ired.bc:
clang -emit-llvm -o ired.bc -c ired.c
ired: ired.o
${CC} ${CFLAGS} ired.o -o ired
+346
View File
@@ -0,0 +1,346 @@
/* ported to C by pancake for r2 in 2012-2013 */
// TODO: integrate floating point support
// TODO: do not use global variables
/*
Reference Chapter 6:
"The C++ Programming Language", Special Edition.
Bjarne Stroustrup,Addison-Wesley Pub Co; 3 edition (February 15, 2000)
ISBN: 0201700735
*/
#include <ctype.h>
#include <stdio.h>
#include <unistd.h>
#define R_API
#define R_NUMCALC_STRSZ 4096
typedef struct {
double d;
ut64 n;
} RNumCalcValue;
typedef enum {
RNCNAME, RNCNUMBER, RNCEND, RNCINC, RNCDEC,
RNCPLUS='+', RNCMINUS='-', RNCMUL='*', RNCDIV='/',
//RNCXOR='^', RNCOR='|', RNCAND='&',
RNCPRINT=';', RNCASSIGN='=', RNCLEFTP='(', RNCRIGHTP=')'
} RNumCalcToken;
typedef struct r_num_calc_t {
RNumCalcToken curr_tok;
RNumCalcValue number_value;
char string_value[R_NUMCALC_STRSZ];
int errors;
char oc;
const char *calc_err;
int calc_i;
const char *calc_buf;
int calc_len;
} RNumCalc;
typedef struct r_num_t {
ut64 (*callback)(struct r_num_t *userptr, const char *str, int *ok);
// RNumCallback callback;
ut64 value;
double fvalue;
void *userptr;
RNumCalc nc;
} RNum;
/* accessors */
static inline RNumCalcValue Nset(ut64 v) { RNumCalcValue n; n.d = (double)v; n.n = v; return n; }
static inline RNumCalcValue Nsetf(double v) { RNumCalcValue n; n.d = v; n.n = (ut64)v; return n; }
static inline RNumCalcValue Naddf(RNumCalcValue n, double v) { n.d += v; n.n += (ut64)v; return n; }
static inline RNumCalcValue Naddi(RNumCalcValue n, ut64 v) { n.d += (double)v; n.n += v; return n; }
static inline RNumCalcValue Nsubi(RNumCalcValue n, ut64 v) { n.d -= (double)v; n.n -= v; return n; }
static inline RNumCalcValue Nadd(RNumCalcValue n, RNumCalcValue v) { n.d += v.d; n.n += v.n; return n; }
static inline RNumCalcValue Nsub(RNumCalcValue n, RNumCalcValue v) { n.d -= v.d; n.n -= v.n; return n; }
static inline RNumCalcValue Nmul(RNumCalcValue n, RNumCalcValue v) { n.d *= v.d; n.n *= v.n; return n; }
static inline RNumCalcValue Ndiv(RNumCalcValue n, RNumCalcValue v) {
if (v.d) n.d /= v.d; else n.d = 0;
if (v.n) n.n /= v.n; else n.n = 0;
return n;
}
static RNumCalcValue expr(RNum*, RNumCalc*, int);
static RNumCalcValue term(RNum*, RNumCalc*, int);
static void error(RNum*, RNumCalc*, const char *);
static RNumCalcValue prim(RNum*, RNumCalc*, int);
static RNumCalcToken get_token(RNum*, RNumCalc*);
static void error(RNum *num, RNumCalc *nc, const char *s) {
nc->errors++;
nc->calc_err = s;
//fprintf (stderr, "error: %s\n", s);
}
static RNumCalcValue expr(RNum *num, RNumCalc *nc, int get) {
RNumCalcValue left = term (num, nc, get);
for (;;) {
if (nc->curr_tok == RNCPLUS)
left = Nadd (left, term (num, nc, 1));
else if (nc->curr_tok == RNCMINUS)
left = Nsub (left, term (num, nc, 1));
else break;
}
return left;
}
static RNumCalcValue term(RNum *num, RNumCalc *nc, int get) {
RNumCalcValue left = prim (num, nc, get);
for (;;) {
if (nc->curr_tok == RNCMUL) {
left = Nmul (left, prim (num, nc, 1));
} else
if (nc->curr_tok == RNCDIV) {
RNumCalcValue d = prim (num, nc, 1);
if (!d.d) {
error (num, nc, "divide by 0");
return d;
}
left = Ndiv (left, d);
} else return left;
}
}
static RNumCalcValue prim(RNum *num, RNumCalc *nc, int get) {
char *p;
RNumCalcValue v = {0};
if (get) get_token (num, nc);
switch (nc->curr_tok) {
case RNCNUMBER:
v = nc->number_value;
get_token (num, nc);
return v;
case RNCNAME:
for(p=nc->string_value;*p&&*p==' ';p++) {};
v = Nset (str2ut64 (nc->string_value));
get_token (num, nc);
if (nc->curr_tok == RNCASSIGN)
v = expr (num, nc, 1);
if (nc->curr_tok == RNCINC) Naddi (v, 1);
if (nc->curr_tok == RNCDEC) Nsubi (v, 1);
return v;
case RNCINC: return Naddi (prim (num, nc, 1), 1);
case RNCDEC: return Naddi (prim (num, nc, 1), -1);
case RNCMINUS: return Nsub (v, prim (num, nc, 1));
case RNCLEFTP:
v = expr (num, nc, 1);
if (nc->curr_tok == RNCRIGHTP)
get_token (num, nc);
else error (num, nc, " ')' expected");
case RNCEND:
case RNCPLUS:
case RNCMUL:
case RNCDIV:
case RNCPRINT:
case RNCASSIGN:
case RNCRIGHTP:
return v;
//default: error (num, nc, "primary expected");
}
return v;
}
static void cin_putback (RNum *num, RNumCalc *nc, char c) {
nc->oc = c;
}
R_API const char *r_num_calc_index (RNum *num, const char *p) {
if (num == NULL)
return NULL;
if (p) {
num->nc.calc_buf = p;
num->nc.calc_len = strlen (p);
num->nc.calc_i = 0;
}
//if (num->nc.calc_i>num->nc.calc_len) return NULL;
return num->nc.calc_buf + num->nc.calc_i;
}
static int cin_get(RNumCalc *nc, char *c) {
if (nc->oc) {
*c = nc->oc;
nc->oc = 0;
} else {
if (!nc->calc_buf)
return 0;
//if (nc->calc_i>nc->calc_len) return 0;
*c = nc->calc_buf[nc->calc_i];
if (*c) nc->calc_i++;
else return 0;
}
return 1;
}
static int cin_get_num(RNum *num, RNumCalc *nc, RNumCalcValue *n) {
char c, str[R_NUMCALC_STRSZ];
double d;
int i = 0;
str[0] = 0;
while (cin_get (nc, &c)) {
if (c!=':' && c!='.' && !isalnum (c)) {
cin_putback (num, nc, c);
break;
}
if (i<R_NUMCALC_STRSZ)
str[i++] = c;
}
str[i] = 0;
*n = Nset (str2ut64 (str));
if (*str>='0' && *str<='9' && strchr (str, '.')) {
if (sscanf (str, "%lf", &d)<1)
return 0;
*n = Nsetf (d);
}
#if 0
// XXX: use r_num_get here
if (str[0]=='0' && str[1]=='x') {
ut64 x = 0;
if (sscanf (str+2, "%llx", &x)<1)
return 0;
*n = Nset (x);
} else
if (strchr (str, '.')) {
if (sscanf (str, "%lf", &d)<1)
return 0;
*n = Nsetf (d);
} else {
ut64 u;
if (sscanf (str, "%"PFMT64d, &u)<1)
return 0;
*n = Nset (u);
}
#endif
return 1;
}
static RNumCalcToken get_token(RNum *num, RNumCalc *nc) {
char ch = 0, c = 0;
do { if (!cin_get (nc, &ch)) return nc->curr_tok = RNCEND;
} while (ch!='\n' && isspace (ch));
switch (ch) {
case 0:
case ';':
case '\n':
return nc->curr_tok = RNCEND;
case '+': // added for ++name and name++
if (cin_get (nc, &c) && c == '+')
return nc->curr_tok = RNCINC;
cin_putback (num, nc, c);
return nc->curr_tok = (RNumCalcToken) ch;
case '-':
if (cin_get (nc, &c) && c == '-')
return nc->curr_tok = RNCDEC;
cin_putback (num, nc, c);
return nc->curr_tok = (RNumCalcToken) ch;
case '*':
case '/':
case '(':
case ')':
case '=':
return nc->curr_tok = (RNumCalcToken) ch;
case '0':case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case '.':
cin_putback (num, nc, ch);
if (!cin_get_num (num, nc, &nc->number_value)) {
error (num, nc, "invalid number conversion");
return 1;
}
return nc->curr_tok = RNCNUMBER;
default:
#define isvalidchar(x) \
(isalnum(x) || x==':' || x=='$' || x=='.' || x=='_' || x=='?' || x=='\\' \
|| x==' ' || x=='[' || x==']' || x=='}' || x=='{' || x=='/' || (x>='0'&&x<='9'))
{
int i = 0;
nc->string_value[i++] = ch;
if (ch == '[') {
while (cin_get (nc, &ch) && ch!=']') {
if (i>=R_NUMCALC_STRSZ) {
error (num, nc, "string too long");
return 0;
}
nc->string_value[i++] = ch;
}
nc->string_value[i++] = ch;
} else {
while (cin_get (nc, &ch) && isvalidchar (ch)) {
if (i>=R_NUMCALC_STRSZ) {
error (num, nc, "string too long");
return 0;
}
nc->string_value[i++] = ch;
}
}
nc->string_value[i] = 0;
cin_putback (num, nc, ch);
return nc->curr_tok = RNCNAME;
}
//}
error (num, nc, "bad token");
return nc->curr_tok = RNCPRINT;
}
}
static void load_token(RNum *num, RNumCalc *nc, const char *s) {
nc->calc_i = 0;
nc->calc_len = 0;
nc->calc_buf = s;
nc->calc_err = NULL;
}
R_API ut64 r_num_calc (RNum *num, const char *str, const char **err) {
RNumCalcValue n;
RNumCalc *nc, nc_local;
if (!str || !*str)
return 0LL;
if (num == NULL)
nc = &nc_local;
else nc = &num->nc;
/* init */
nc->curr_tok = RNCPRINT;
nc->number_value.d = 0.0;
nc->number_value.n = 0LL;
nc->errors = 0;
nc->oc = 0;
nc->calc_err = NULL;
nc->calc_i = 0;
nc->calc_len = 0;
nc->calc_buf = NULL;
load_token (num, nc, str);
get_token (num, nc);
n = expr (num, nc, 0);
if (err) *err = nc->calc_err;
//if (nc->curr_tok == RNCEND) return 0LL; // XXX: Error
//if (nc->curr_tok == RNCPRINT) //return 0LL; // XXX: the fuck
// n = expr (num, nc, 0);
if (n.d != ((double)(ut64)n.d)) {
if (num) num->fvalue = n.d;
} else if (num) num->fvalue = (double)n.n;
return n.n;
}
#if 0
int main(int argc, char* argv[]) {
RNumCalcValue n;
RNumCalc nc;
while (!feof (stdin)) {
get_token (nc);
if (nc.curr_tok == RNCEND) break;
if (nc.curr_tok == RNCPRINT) continue;
n = expr (num, nc, 0);
if (n.d == ((double)(int)n.d))
printf ("%llx\n", n.n);
else printf ("%lf\n", n.d);
}
return nc->errors;
}
#endif
+7 -3
View File
@@ -154,7 +154,7 @@ static int cmd_write(const char *arg) {
static int cmd_help(char *arg) {
if(*arg) {
ut64 ret = str2ut64(arg);
ut64 ret = r_num_calc (NULL, arg, NULL);
printf("0x%"LLF"x %"LLF"d 0%"LLF"o\n", ret, ret, ret);
} else printf(
"s[+-addr] seek to relative or absolute address\n"
@@ -164,6 +164,7 @@ static int cmd_help(char *arg) {
"x[size] hexdump\n"
"X[size] hexpair dump\n"
"p[fmt] print formatted current block ('p' for help)\n"
"d[size] disasemble\n"
"r[+-[num]] truncate or -remove N bytes\n"
".[file] interpret file\n"
"<[file] load file in current seek\n"
@@ -227,13 +228,16 @@ static int cmd_system(char *arg) {
if(fd) {
if((buf = getcurblk("", &len))) {
setenv("BLOCK", ".curblk", 1);
if(fwrite(buf, len, 1, fd)<len)
perror("fwrite");
fwrite(buf, len, 1, fd);
free(buf);
}
fclose(fd);
}
}
if(strstr(arg, "BSIZE")) {
sprintf(str, "%d", len);
setenv("BSIZE", str, 1);
}
if(strstr(arg, "OFFSET")) {
sprintf(str, "%"LLF"d", curseek);
setenv("OFFSET", str, 1);
+27 -7
View File
@@ -3,8 +3,12 @@
#define ut64 unsigned long long
#define ut8 unsigned char
static int earlyquit = 0;
static int verbose = 1;
static char *script = 0;
static int scriptn = 0;
static const char **scripts = 0;
static int cmdn = 0;
static char **cmds = 0;
static ut64 oldseek, curseek = 0LL;
static int obsize, bsize = 256;
static int red_cmd(char *cmd); // XXX : recursive depenency
@@ -12,6 +16,7 @@ static int red_cmd(char *cmd); // XXX : recursive depenency
#include "ired.h"
#include "util.c"
#include "calc.c"
#include "cmd.c"
static void red_slurpin() {
@@ -24,7 +29,7 @@ static void red_slurpin() {
}
}
static int red_interpret(char *file) {
static int red_interpret(const char *file) {
char buf[BUFSZ];
FILE *fd = fopen(file, "r");
if(fd != NULL) {
@@ -51,12 +56,14 @@ static int red_cmd(char *cmd) {
case 's': return cmd_seek(arg); break;
case 'b': return cmd_bsize(arg); break;
case '/': return cmd_search(arg); break;
case 'd': return cmd_system ("echo X | ired -n $BLOCK | rasm2 -o $OFFSET -D - |head -n $(($LINES-1))");
case 'p': return cmd_print(arg); break;
case 'r': return cmd_resize(arg); break;
case 'x': return cmd_hexdump(arg); break;
case 'X': return cmd_bytedump(arg); break;
case 'w': return cmd_write(arg); break;
case '!': return cmd_system(arg); break;
case 'V': return cmd_system("vired $FILE"); break;
case '?': return cmd_help(arg); break;
default: fprintf(stderr, "? %s\n", cmd);
}
@@ -96,8 +103,14 @@ static int red_open(char *file) {
if(ret != -1) {
oldseek = 0;
setenv("FILE", file, 1);
if(script)
red_interpret(script);
if(scripts)
for (ret=0;ret<scriptn;ret++)
red_interpret(scripts[ret]);
if(cmds)
for (ret=0;ret<cmdn;ret++)
red_cmd(cmds[ret]);
if(earlyquit)
return 0;
while((ret=red_prompt())>0) {
curseek = oldseek;
bsize = obsize;
@@ -109,20 +122,26 @@ static int red_open(char *file) {
}
static int red_help() {
puts("ired [-hnv] [-i script] [file] [..]");
puts("ired [-qhnv] [-c cmd] [-i script] [-|file ..]");
return 0;
}
int main(int argc, char **argv) {
int i, ret = 1;
argc++;
cmdn = 0;
scriptn = 0;
scripts = malloc(sizeof(const char*)*argc);
cmds = malloc(sizeof(const char*)*argc);
if(argc>1 && argv[1])
for(i=1; i<argc; i++) {
if(argv[i] && argv[i][0]=='-')
switch(argv[i][1]) {
case 'i': script = argv[++i]; break;
case 'q': earlyquit = 1; break;
case 'i': scripts[scriptn++] = argv[++i]; break;
case 'c': cmds[cmdn++] = argv[++i]; break;
case 'n': verbose = 0; break;
case 'v': puts("ired "VERSION); ret = 0; break;
case 'v': puts(VERSION); ret = 0; break;
case 'h': ret = red_help(); break;
case 0x0: red_slurpin(); ret = 0; break;
} else {
@@ -130,5 +149,6 @@ int main(int argc, char **argv) {
ret = red_open(argv[i]);
}
} else ret = red_help();
free(scripts);
return ret;
}
+1 -1
View File
@@ -1,4 +1,4 @@
#define VERSION "0.5"
#define VERSION "0.6"
#include <unistd.h>
#include <sys/types.h>
+2 -5
View File
@@ -7,11 +7,8 @@ static inline void hexdump(const ut8 *buf, unsigned int len, int w) {
for(i=0;i<len;i+=w) {
printf("0x%08"LLF"x: ", curseek+i);
for(j=i;j<i+w;j++) {
if(j>=len) {
printf(j%2?" ":" ");
continue;
}
printf(j%2?"%02x ":"%02x", buf[j]);
if(j<len) printf(j%2?"%02x ":"%02x", buf[j]);
else printf(j%2?" ":" ");
}
printf(" ");
for(j=i;j<i+w;j++)
+39 -15
View File
@@ -4,48 +4,72 @@
PATH=.:$PATH
if [ -n "$1" ]; then
$0 | ired -n $@
ttyset=`stty -g`
bye() {
[ -n "$ttyset" ] && stty $ttyset
exit 0
fi
}
case "$1" in
-) : ; ;;
'') echo "vired [-hv] [file]" ; exit 1 ; ;;
*) $0 - | ired -n $@ ; bye ; ;;
esac
ttyset=`stty -g`
stty -echo -icanon min 1
trap bye 2
getkey() {
echo "` stty -echo -icanon min 1 ; dd if=/dev/tty count=1 bs=1 2>/dev/null`"
}
getstr() {
stty icanon echo
read A
echo $A
echo "$A"
stty -icanon -echo
}
OLINES=0
autobs() {
LINES=`tput lines`
if [ "${OLINES}" != "${LINES}" ]; then
[ -n "${LINES}" ] && \
echo "b"$((($LINES-1)*16))
OLINES=${LINES}
fi
}
trap autobs 28
P=''
echo "b 256"
while : ; do
autobs
echo "!clear"
case $P in
'd') echo '!echo X | ired -n $BLOCK | rasm2 -o $OFFSET -d -' ;;
#'d') echo '!echo X | ired -n $| rasm2 -o $OFFSET -vd -|head -n '$LINES ; ;;
d) echo d ;;
*) echo x ;;
esac
A=`dd if=/dev/tty count=1 bs=1 2>/dev/null`
case $A in
case "`getkey`" in
'j') echo "s+16" ;;
'k') echo "s-16" ;;
'J') echo "s+b" ;;
'K') echo "s-b" ;;
'h') echo "s-1" ;;
'l') echo "s+1" ;;
'q') stty $ttyset; exit ;;
'b') printf 'b '>/dev/tty; echo b `getstr` ;;
'w') printf 'w '>/dev/tty; echo w `getstr` ;;
's') printf 's '>/dev/tty; echo s `getstr` ;;
'r') printf 'r '>/dev/tty; echo r `getstr` ;;
':') printf ': '>/dev/tty; echo `getstr`; read A ;;
'?') echo '?'; read A ;;
'q') bye ; ;;
'b') printf 'b'>/dev/tty; echo b`getstr` ;;
'w') printf 'w'>/dev/tty; echo w`getstr` ;;
's') printf 's'>/dev/tty; echo s`getstr` ;;
'r') printf 'r '>/dev/tty; echo r`getstr` ;;
':') printf ': '>/dev/tty; getstr; getkey >/dev/null ; ;;
'?') echo '?'; getkey >/dev/null; ;;
'+') echo "b+1" ;;
'-') echo "b-1" ;;
'*') echo "b+16" ;;
'/') echo "b-16" ;;
'p') if [ -n "$P" ]; then P=''; else P=d; fi ;;
p|P) if [ -n "$P" ]; then P=''; else P=d; fi ;;
esac
done