mirror of
https://github.com/radareorg/r0.git
synced 2026-11-08 08:49:42 -10:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb011f88af | ||
|
|
c5498bd961 | ||
|
|
a173daa812 | ||
|
|
9096ed5126 | ||
|
|
b074f2280d | ||
|
|
ec8e0225c3 | ||
|
|
2dca803f6d | ||
|
|
fba8f8e1a7 | ||
|
|
afbe2e04f6 | ||
|
|
085b908d37 | ||
|
|
4f1d810e98 | ||
|
|
bed1916abc | ||
|
|
36e027fe48 | ||
|
|
3fef4efbb5 | ||
|
|
0e0f906f66 | ||
|
|
5fee57d158 | ||
|
|
75b31677e4 | ||
|
|
687644afdd | ||
|
|
ac04c6e95e | ||
|
|
204dbde78e | ||
|
|
b6db2f859f | ||
|
|
6e0f3122b6 | ||
|
|
718330da85 | ||
|
|
fca56e2c20 | ||
|
|
4d81079a14 | ||
|
|
5a5595ced6 | ||
|
|
f6a4705bf7 | ||
|
|
b6649372ab | ||
|
|
8bdc8dc92d | ||
|
|
88c93994a0 | ||
|
|
0f9a7f7a1b | ||
|
|
4ddf34f1f8 | ||
|
|
6d744e39a7 |
No files matched your search
@@ -1,16 +1,31 @@
|
||||
CC?=gcc
|
||||
VERSION=0.6git
|
||||
CCw32?=i486-mingw32-gcc
|
||||
CFLAGS+=-O2 -Wall
|
||||
PREFIX?=/usr
|
||||
#CFLAGS+=-DVERSION=\"${VERSION}\"
|
||||
PREFIX?=/usr/local
|
||||
DESTDIR?=
|
||||
|
||||
all:
|
||||
${CC} ${CFLAGS} ired.c -o ired
|
||||
all: ired bdiff
|
||||
|
||||
bdiff: bdiff.o
|
||||
${CC} ${CFLAGS} bdiff.o -o bdiff
|
||||
|
||||
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
|
||||
|
||||
dist:
|
||||
if [ -z "${VERSION}" ]; then echo "make dist VERSION=0.3" ; exit 1 ; fi
|
||||
mkdir -p ired-${VERSION}
|
||||
cd ired-${VERSION} ; hg clone .. . ; rm -rf .hg
|
||||
@if [ -z "${VERSION}" ]; then echo "Try: make dist VERSION=0.5" ; exit 1 ; fi
|
||||
git clone . ired-${VERSION}
|
||||
rm -rf ired-${VERSION}/.git
|
||||
tar czvf ired-${VERSION}.tar.gz ired-${VERSION}
|
||||
rm -rf ired-${VERSION}
|
||||
|
||||
@@ -21,17 +36,18 @@ loc:
|
||||
@wc -l *.c *.h | grep total
|
||||
|
||||
clean:
|
||||
rm -f ired ired.o
|
||||
rm -f ired ired.o bdiff bdiff.o
|
||||
|
||||
install:
|
||||
mkdir -p ${DESTDIR}${PREFIX}/bin
|
||||
cp ired ${DESTDIR}${PREFIX}/bin
|
||||
cp vired ${DESTDIR}${PREFIX}/bin
|
||||
cp -f ired ${DESTDIR}${PREFIX}/bin
|
||||
cp -f bdiff ${DESTDIR}${PREFIX}/bin
|
||||
cp -f vired ${DESTDIR}${PREFIX}/bin
|
||||
mkdir -p ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp ired.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp vired.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp -f ired.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
cp -f vired.1 ${DESTDIR}${PREFIX}/share/man/man1
|
||||
|
||||
uninstall:
|
||||
deinstall uninstall:
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/ired
|
||||
rm -f ${DESTDIR}${PREFIX}/bin/vired
|
||||
rm -f ${DESTDIR}${PREFIX}/share/man/man1/ired.1
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
RED stands for the raw editor
|
||||
============================= --pancake
|
||||
|
||||
red aims to be a minimalistic reimplementation of the radare shell
|
||||
without much complexity and relaying all the extensibility to
|
||||
external applications trying to keep the source as small as possible.
|
||||
|
||||
COMMANDS
|
||||
========
|
||||
|
||||
? is for help get help or evaluate numeric expression
|
||||
x hexdump hexdump
|
||||
X dword dump hexpair dump
|
||||
> file dump current block to file
|
||||
< file slurp file into current block
|
||||
w "string\x00" write string
|
||||
w 023839400 write hexpairs
|
||||
b 30 set block size
|
||||
s addr seek address
|
||||
r [size|-rmv] get filesize, truncate file to size, or -remove bytes
|
||||
p [bwWdDqQiIF.] print formatted the current block
|
||||
q quit
|
||||
|
||||
|
||||
WORK IN PROGRESS
|
||||
================
|
||||
print command
|
||||
b/w/d/q byte, word, dword, qword (little endian)
|
||||
B/W/D/Q byte, word, dword, qword (big endian)
|
||||
i/I/f/F int32 (lil, big), float (lil, big)
|
||||
z/Z zero-terminatted strings (ascii, widechar)
|
||||
./: skip 1 or 4 chars
|
||||
* repeat last value until death
|
||||
|
||||
TODO:
|
||||
=====
|
||||
- support for escapped characters in string write and search ops
|
||||
- Add support for simple math ops (+,-,*,/) no parenthesis plz :)
|
||||
|
||||
TODO/TOTHINK
|
||||
============
|
||||
- Remove '.' command? do it suckless
|
||||
- Add .! command that runs !foo > file and then .file
|
||||
- Support for multiple commands in a single line (';' separator)
|
||||
@@ -0,0 +1,55 @@
|
||||
IRED stands for the independent raw editor
|
||||
==========================================
|
||||
|
||||
red aims to be a minimalistic reimplementation of the radare shell
|
||||
without much complexity and relaying all the extensibility to external
|
||||
applications trying to keep the source as small as possible.
|
||||
|
||||
AUTHOR
|
||||
------
|
||||
pancake<nopcode.org>
|
||||
|
||||
COMMANDS
|
||||
========
|
||||
|
||||
? is for help get help or evaluate numeric expression
|
||||
/ search search strings or hexpairs
|
||||
!cmd run command from shell
|
||||
x hexdump hexdump
|
||||
X dword dump hexpair dump
|
||||
> file dump current block to file
|
||||
< file slurp file into current block
|
||||
w "string\x00" write string
|
||||
w 023839400 write hexpairs
|
||||
b 30 set block size
|
||||
s addr seek address
|
||||
r [size|-rmv] get filesize, truncate file to size, or -remove bytes
|
||||
p [bwWdDqQiIF.] print formatted the current block
|
||||
q quit
|
||||
|
||||
|
||||
WORK IN PROGRESS
|
||||
================
|
||||
print command
|
||||
b/w/d/q byte, word, dword, qword (little endian)
|
||||
B/W/D/Q byte, word, dword, qword (big endian)
|
||||
i/I/f/F int32 (lil, big), float (lil, big)
|
||||
z/Z zero-terminatted strings (ascii, widechar)
|
||||
./: skip 1 or 4 chars
|
||||
* repeat last value until death
|
||||
|
||||
PORTABILITY
|
||||
===========
|
||||
ired is known to build and run on several OS.
|
||||
- GNU, Linux, OSX, Windows (mingw), cygwin, Solaris, BSD, ...
|
||||
|
||||
TODO:
|
||||
=====
|
||||
- support for escapped characters in string write and search ops
|
||||
- Add support for simple math ops (+,-,*,/) no parenthesis plz :)
|
||||
|
||||
TODO/TOTHINK
|
||||
============
|
||||
- Remove '.' command? to make it suck less
|
||||
- Add .! command that runs !foo > file and then .file
|
||||
- Support for multiple commands in a single line (';' separator)
|
||||
@@ -0,0 +1,13 @@
|
||||
* We need a way to work with block based data like the 'wo' cmd in r1
|
||||
* Implement formatted structs with named arguments in p command
|
||||
* getcurblock can manage its own memory.. all those free's can be removed
|
||||
* Find a way to return original value if str2ut64 fails (2nd arg..)
|
||||
* Add math support to '?' command
|
||||
* w<- should write from stdin
|
||||
|
||||
Commands can:
|
||||
|
||||
-1 - fail
|
||||
0 - quit
|
||||
1 - run fine
|
||||
2 - run with issues
|
||||
@@ -0,0 +1,360 @@
|
||||
/* bdiff - MIT - Copyright 2010-2013 - pancake */
|
||||
/* Adapted code from:
|
||||
|
||||
bdiff.c - efficient binary diff extension for Mercurial
|
||||
|
||||
Copyright 2005, 2006 Matt Mackall <[email protected]>
|
||||
|
||||
This software may be used and distributed according to the terms of
|
||||
the GNU General Public License, incorporated herein by reference.
|
||||
|
||||
Based roughly on Python difflib
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <limits.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
struct line {
|
||||
int h, len, n, e;
|
||||
const char *l;
|
||||
};
|
||||
|
||||
struct pos {
|
||||
int pos, len;
|
||||
};
|
||||
|
||||
struct hunk {
|
||||
int a1, a2, b1, b2;
|
||||
};
|
||||
|
||||
struct hunklist {
|
||||
struct hunk *base, *head;
|
||||
};
|
||||
|
||||
static int splitlines(const char *a, int len, struct line **lr) {
|
||||
int h, i;
|
||||
const char *p, *b = a;
|
||||
const char * const plast = a + len - 1;
|
||||
struct line *l;
|
||||
|
||||
/* count the lines */
|
||||
i = 1; /* extra line for sentinel */
|
||||
for(p = a; p < a + len; p++)
|
||||
if(*p == '\n' || p == plast)
|
||||
i++;
|
||||
|
||||
*lr = l = (struct line *)malloc(sizeof(struct line) * i);
|
||||
if(!l)
|
||||
return -1;
|
||||
|
||||
/* build the line array and calculate hashes */
|
||||
h = 0;
|
||||
for(p = a; p < a + len; p++) {
|
||||
/* Leonid Yuriev's hash */
|
||||
h = (h * 1664525) + *p + 1013904223;
|
||||
|
||||
if(*p == '\n' || p == plast) {
|
||||
l->h = h;
|
||||
h = 0;
|
||||
l->len = p - b + 1;
|
||||
l->l = b;
|
||||
l->n = INT_MAX;
|
||||
l++;
|
||||
b = p + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* set up a sentinel */
|
||||
l->h = l->len = 0;
|
||||
l->l = a + len;
|
||||
return i - 1;
|
||||
}
|
||||
|
||||
static int inline cmp(struct line *a, struct line *b) {
|
||||
return a->h != b->h || a->len != b->len || memcmp(a->l, b->l, a->len);
|
||||
}
|
||||
|
||||
static int equatelines(struct line *a, int an, struct line *b, int bn) {
|
||||
int i, j, buckets = 1, t, scale;
|
||||
struct pos *h = NULL;
|
||||
|
||||
/* build a hash table of the next highest power of 2 */
|
||||
while(buckets < bn + 1)
|
||||
buckets *= 2;
|
||||
|
||||
/* try to allocate a large hash table to avoid collisions */
|
||||
for(scale = 4; scale; scale /= 2) {
|
||||
h = (struct pos *)malloc(scale * buckets * sizeof(struct pos));
|
||||
if(h)
|
||||
break;
|
||||
}
|
||||
|
||||
if(!h)
|
||||
return 0;
|
||||
|
||||
buckets = buckets * scale - 1;
|
||||
|
||||
/* clear the hash table */
|
||||
for(i = 0; i <= buckets; i++) {
|
||||
h[i].pos = INT_MAX;
|
||||
h[i].len = 0;
|
||||
}
|
||||
|
||||
/* add lines to the hash table chains */
|
||||
for(i = bn - 1; i >= 0; i--) {
|
||||
/* find the equivalence class */
|
||||
for(j = b[i].h & buckets; h[j].pos != INT_MAX;
|
||||
j = (j + 1) & buckets)
|
||||
if(!cmp(b + i, b + h[j].pos))
|
||||
break;
|
||||
|
||||
/* add to the head of the equivalence class */
|
||||
b[i].n = h[j].pos;
|
||||
b[i].e = j;
|
||||
h[j].pos = i;
|
||||
h[j].len++; /* keep track of popularity */
|
||||
}
|
||||
|
||||
/* compute popularity threshold */
|
||||
t = (bn >= 4000) ? bn / 1000 : bn + 1;
|
||||
|
||||
/* match items in a to their equivalence class in b */
|
||||
for(i = 0; i < an; i++) {
|
||||
/* find the equivalence class */
|
||||
for(j = a[i].h & buckets; h[j].pos != INT_MAX;
|
||||
j = (j + 1) & buckets)
|
||||
if(!cmp(a + i, b + h[j].pos))
|
||||
break;
|
||||
|
||||
a[i].e = j; /* use equivalence class for quick compare */
|
||||
if(h[j].len <= t)
|
||||
a[i].n = h[j].pos; /* point to head of match list */
|
||||
else a[i].n = INT_MAX; /* too popular */
|
||||
}
|
||||
|
||||
/* discard hash tables */
|
||||
free(h);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int longest_match(struct line *a, struct line *b, struct pos *pos,
|
||||
int a1, int a2, int b1, int b2, int *omi, int *omj) {
|
||||
int mi = a1, mj = b1, mk = 0, mb = 0, i, j, k;
|
||||
|
||||
for(i = a1; i < a2; i++) {
|
||||
/* skip things before the current block */
|
||||
for(j = a[i].n; j < b1; j = b[j].n)
|
||||
;
|
||||
|
||||
/* loop through all lines match a[i] in b */
|
||||
for(; j < b2; j = b[j].n) {
|
||||
/* does this extend an earlier match? */
|
||||
if(i > a1 && j > b1 && pos[j - 1].pos == i - 1)
|
||||
k = pos[j - 1].len + 1;
|
||||
else k = 1;
|
||||
pos[j].pos = i;
|
||||
pos[j].len = k;
|
||||
|
||||
/* best match so far? */
|
||||
if(k > mk) {
|
||||
mi = i;
|
||||
mj = j;
|
||||
mk = k;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(mk) {
|
||||
mi = mi - mk + 1;
|
||||
mj = mj - mk + 1;
|
||||
}
|
||||
|
||||
/* expand match to include neighboring popular lines */
|
||||
while(mi - mb > a1 && mj - mb > b1 &&
|
||||
a[mi - mb - 1].e == b[mj - mb - 1].e)
|
||||
mb++;
|
||||
while(mi + mk < a2 && mj + mk < b2 &&
|
||||
a[mi + mk].e == b[mj + mk].e)
|
||||
mk++;
|
||||
|
||||
*omi = mi - mb;
|
||||
*omj = mj - mb;
|
||||
|
||||
return mk + mb;
|
||||
}
|
||||
|
||||
static void recurse(struct line *a, struct line *b, struct pos *pos,
|
||||
int a1, int a2, int b1, int b2, struct hunklist *l) {
|
||||
int i, j, k;
|
||||
|
||||
/* find the longest match in this chunk */
|
||||
k = longest_match(a, b, pos, a1, a2, b1, b2, &i, &j);
|
||||
if(!k)
|
||||
return;
|
||||
/* and recurse on the remaining chunks on either side */
|
||||
recurse(a, b, pos, a1, i, b1, j, l);
|
||||
l->head->a1 = i;
|
||||
l->head->a2 = i + k;
|
||||
l->head->b1 = j;
|
||||
l->head->b2 = j + k;
|
||||
l->head++;
|
||||
recurse(a, b, pos, i + k, a2, j + k, b2, l);
|
||||
}
|
||||
|
||||
static struct hunklist diff(struct line *a, int an, struct line *b, int bn) {
|
||||
struct hunklist l;
|
||||
struct hunk *curr;
|
||||
struct pos *pos;
|
||||
int t;
|
||||
|
||||
/* allocate and fill arrays */
|
||||
t = equatelines(a, an, b, bn);
|
||||
pos = (struct pos *)calloc(bn ? bn : 1, sizeof(struct pos));
|
||||
/* we can't have more matches than lines in the shorter file */
|
||||
l.head = l.base = (struct hunk *)malloc(sizeof(struct hunk) *
|
||||
((an<bn ? an:bn) + 1));
|
||||
if(pos && l.base && t) {
|
||||
/* generate the matching block list */
|
||||
recurse(a, b, pos, 0, an, 0, bn, &l);
|
||||
l.head->a1 = l.head->a2 = an;
|
||||
l.head->b1 = l.head->b2 = bn;
|
||||
l.head++;
|
||||
}
|
||||
free(pos);
|
||||
|
||||
/* normalize the hunk list, try to push each hunk towards the end */
|
||||
for(curr = l.base; curr != l.head; curr++) {
|
||||
struct hunk *next = curr+1;
|
||||
int shift = 0;
|
||||
if(next == l.head)
|
||||
break;
|
||||
if(curr->a2 == next->a1)
|
||||
while(curr->a2+shift < an && curr->b2+shift < bn
|
||||
&& !cmp(a+curr->a2+shift, b+curr->b2+shift))
|
||||
shift++;
|
||||
else if(curr->b2 == next->b1)
|
||||
while(curr->b2+shift < bn && curr->a2+shift < an
|
||||
&& !cmp(b+curr->b2+shift, a+curr->a2+shift))
|
||||
shift++;
|
||||
if(!shift)
|
||||
continue;
|
||||
curr->b2 += shift;
|
||||
next->b1 += shift;
|
||||
curr->a2 += shift;
|
||||
next->a1 += shift;
|
||||
}
|
||||
|
||||
return l;
|
||||
}
|
||||
|
||||
char *slurp(const char *str, int *usz) {
|
||||
char *ret;
|
||||
long sz, n, num = 0;
|
||||
FILE *fd = fopen(str, "rb");
|
||||
if(fd == NULL)
|
||||
return NULL;
|
||||
fseek(fd, 0, SEEK_END);
|
||||
sz = ftell(fd);
|
||||
fseek(fd, 0, SEEK_SET);
|
||||
ret = (char *)malloc(sz+1);
|
||||
do {
|
||||
n = fread(ret, 1, sz, fd);
|
||||
if(n<1)
|
||||
break;
|
||||
num += n;
|
||||
} while(num < sz);
|
||||
ret[num] = '\0';
|
||||
fclose(fd);
|
||||
if(usz)
|
||||
*usz = (int)sz;
|
||||
return ret;
|
||||
}
|
||||
|
||||
int bdiff(const char *filea, const char *fileb) {
|
||||
char *sa, *sb;
|
||||
int i, an, bn, offa, rlen, offb, len = 0;
|
||||
int la, lb, hits = 0;
|
||||
struct line *al, *bl;
|
||||
struct hunklist l = { NULL, NULL };
|
||||
struct hunk *h;
|
||||
|
||||
if((sa = slurp(filea, &la)) == NULL)
|
||||
return fprintf(stderr, "Cannot open %s\n", filea), 0;
|
||||
if((sb = slurp(fileb, &lb)) == NULL)
|
||||
return fprintf(stderr, "Cannot open %s\n", fileb), 0;
|
||||
|
||||
/* TODO: split to function here */
|
||||
an = splitlines(sa, la, &al);
|
||||
bn = splitlines(sb, lb, &bl);
|
||||
if(!al || !bl)
|
||||
return -1;
|
||||
|
||||
l = diff(al, an, bl, bn);
|
||||
if(!l.head)
|
||||
return -1;
|
||||
|
||||
la = lb = 0;
|
||||
for(h = l.base; h != l.head; h++) {
|
||||
if(h->a1 != la || h->b1 != lb) {
|
||||
len = bl[h->b1].l - bl[lb].l;
|
||||
offa = al[la].l - al->l;
|
||||
offb = al[h->a1].l - al->l;
|
||||
rlen = offb-offa;
|
||||
|
||||
//fprintf(stderr, "all: %d %d\n", );
|
||||
//fprintf(stderr, "len: %d %d\n", len, rlen);
|
||||
//fprintf(stderr, "off: %d %d\n", offa, offb);
|
||||
if(rlen>len)
|
||||
printf("r-%d@%d\n", (rlen-len), offa);
|
||||
else printf("r+%d@%d\n", (len-rlen), offb);
|
||||
|
||||
if(len == rlen) {
|
||||
for(i=0; i<len; i++) {
|
||||
if(bl[lb].l[i] != bl[la].l[i])
|
||||
fprintf(stderr, "%02x %02x\n",
|
||||
(unsigned char)
|
||||
bl[lb].l[i],
|
||||
(unsigned char)
|
||||
bl[la].l[i]);
|
||||
}
|
||||
// XXX fprintf(stderr, "%02x @ 0x%x\n", bl[la].l[i], offa);
|
||||
fprintf(stderr, "WARNING: Binary patch failed\n");
|
||||
}
|
||||
if(len > 0) {
|
||||
printf("w ");
|
||||
for(i=0;i<len;i++)
|
||||
printf("%02x", (unsigned char)bl[lb].l[i]);
|
||||
printf("@%d#len\n", offa);
|
||||
} else
|
||||
if(rlen > 0) {
|
||||
printf("w ");
|
||||
for(i=0; i<rlen; i++)
|
||||
printf("%02x", (unsigned char)bl[la].l[i]);
|
||||
printf("@%d#rlen\n", offa);
|
||||
}
|
||||
}
|
||||
la = h->a2;
|
||||
lb = h->b2;
|
||||
}
|
||||
free(al);
|
||||
free(bl);
|
||||
free(l.base);
|
||||
|
||||
return hits;
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
int ret = 1;
|
||||
if(argc == 3) {
|
||||
if(bdiff(argv[1], argv[2]) == -1)
|
||||
fprintf(stderr, "Out of memory\n");
|
||||
else ret = 0;
|
||||
} else fprintf(stderr, "bdiff [file] [file2] > patch.ired\n");
|
||||
return ret;
|
||||
}
|
||||
@@ -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
|
||||
@@ -1,20 +1,22 @@
|
||||
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
|
||||
/* Copyleft 2009-2013 -- pancake /at/ nopcode /dot/ org */
|
||||
|
||||
static void cmd_hexdump(char *arg) {
|
||||
static int cmd_hexdump(char *arg) {
|
||||
int len = bsize;
|
||||
ut8 *buf = getcurblk(arg, &len);
|
||||
if (buf) {
|
||||
if(buf && len>0) {
|
||||
hexdump(buf, len, 16);
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
|
||||
static void cmd_print(char *arg) {
|
||||
static int cmd_print(char *arg) {
|
||||
ut8 *buf;
|
||||
int len = bsize;
|
||||
if (*arg) {
|
||||
if(*arg) {
|
||||
buf = getcurblk(arg, &len);
|
||||
if (!buf) return;
|
||||
if(!buf) return 2;
|
||||
print_fmt(buf, arg, len);
|
||||
free(buf);
|
||||
} else printf(
|
||||
@@ -23,102 +25,136 @@ static void cmd_print(char *arg) {
|
||||
"s/S short int16 (lil, big)\n"
|
||||
"z/Z zero-terminatted string (ascii, wide-ascii)\n"
|
||||
"./:/* skip 1 or 4 chars, repeat last format instead of cycle\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_bytedump(char *arg) {
|
||||
static int cmd_bytedump(const char *arg) {
|
||||
int i, len = bsize;
|
||||
ut8 *buf = getcurblk(arg, &len);
|
||||
if (buf) {
|
||||
for(i=0;i<len;i++)
|
||||
printf("%02x", buf[i]);
|
||||
printf("\n");
|
||||
free(buf);
|
||||
}
|
||||
if(!buf) return 2;
|
||||
for(i=0;i<len;i++)
|
||||
printf("%02x", buf[i]);
|
||||
printf("\n");
|
||||
free(buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_search(char *arg) {
|
||||
ut8 *buf;
|
||||
int i, len, hit = 0;
|
||||
arg = skipspaces(arg);
|
||||
if (*arg=='"') {
|
||||
static int cmd_search(const char *arg) {
|
||||
ut8 *buf, *barg;
|
||||
size_t len;
|
||||
int i, hit = 0;
|
||||
SKIPSPACES(arg);
|
||||
if(*arg=='"') {
|
||||
arg++;
|
||||
len = strlen(arg)-1;
|
||||
arg[len]='\0';
|
||||
} else len = hexstr2raw(arg);
|
||||
if ((buf = getcurblk("", &bsize)))
|
||||
barg = (ut8*)strdup(arg);
|
||||
len = strlen((const char *)barg)-1;
|
||||
// TODO: ensure last char is '"'
|
||||
barg[len]='\0';
|
||||
} else {
|
||||
barg = (ut8*)strdup(arg);
|
||||
len = hexstr2raw(barg);
|
||||
}
|
||||
if((buf = getcurblk("", &bsize)))
|
||||
do {
|
||||
for(i=0;i<bsize;i++) {
|
||||
if (arg[hit++]!=buf[i]) hit = 0;
|
||||
else if (hit == len)
|
||||
if(barg[hit++]!=buf[i]) hit = 0;
|
||||
else if(hit == len)
|
||||
printf("0x%"LLF"x\n", curseek+i-len+1);
|
||||
}
|
||||
curseek += bsize;
|
||||
} while(io_read(buf, bsize)>0);
|
||||
free(buf);
|
||||
free(barg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_bsize(char *arg) {
|
||||
if (!*arg) printf("%d\n", bsize);
|
||||
else if (*arg=='+') bsize += (int)str2ut64(arg+1);
|
||||
else if (*arg=='-') bsize -= (int)str2ut64(arg+1);
|
||||
static int cmd_bsize(char *arg) {
|
||||
if(!*arg) printf("%d\n", bsize);
|
||||
else if(*arg=='+') bsize += (int)str2ut64(arg+1);
|
||||
else if(*arg=='-') bsize -= (int)str2ut64(arg+1);
|
||||
else bsize = str2ut64(arg);
|
||||
if (bsize<1) bsize = 1;
|
||||
if(bsize<1) bsize = 1;
|
||||
obsize = bsize;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_seek(char *arg) {
|
||||
if (!*arg) printf("%"LLF"d\n", curseek);
|
||||
else if (*arg=='+') curseek += str2ut64(arg+1);
|
||||
else if (*arg=='-') curseek -= str2ut64(arg+1);
|
||||
static int cmd_seek(char *arg) {
|
||||
if(!*arg) printf("%"LLF"d\n", curseek);
|
||||
else if(*arg=='+') curseek += str2ut64(arg+1);
|
||||
else if(*arg=='-') curseek -= str2ut64(arg+1);
|
||||
else curseek = str2ut64(arg);
|
||||
oldseek = curseek;
|
||||
io_seek((oldseek=curseek), 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_dump(char *file) {
|
||||
static int cmd_dump(char *file) {
|
||||
int len = bsize;
|
||||
ut8 *buf = getcurblk("", &len);
|
||||
if (len<1 || buf) {
|
||||
if(len<1 || buf) {
|
||||
FILE *fd = fopen(file, "wb");
|
||||
if (fd) {
|
||||
if (fwrite(buf, len, 1, fd)<len)
|
||||
perror("fwrite");
|
||||
fclose(fd);
|
||||
} else perror("fopen");
|
||||
if (!fd) {
|
||||
free (buf);
|
||||
return -1;
|
||||
}
|
||||
if(fwrite(buf, len, 1, fd)<len) {
|
||||
perror("fwrite");
|
||||
return -1;
|
||||
}
|
||||
fclose(fd);
|
||||
free(buf);
|
||||
} else perror("getcurblk");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_load(char *file) {
|
||||
static int cmd_load(char *file) {
|
||||
FILE *fd = fopen(file, "rb");
|
||||
if (fd) {
|
||||
if(fd) {
|
||||
void *buf = malloc(bsize);
|
||||
if (bsize>0 && buf) {
|
||||
if(bsize>0 && buf) {
|
||||
int len = fread(buf, 1, bsize, fd);
|
||||
if (len<bsize)
|
||||
if(len<bsize)
|
||||
perror("fread");
|
||||
if (io_write(buf, len)<len)
|
||||
io_seek (curseek, SEEK_SET);
|
||||
if(io_write(buf, len)<len) {
|
||||
perror("io_write");
|
||||
return -1;
|
||||
}
|
||||
} else perror("malloc");
|
||||
free(buf);
|
||||
fclose(fd);
|
||||
} else perror("fopen");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_write(char *arg) {
|
||||
static int cmd_write(const char *arg) {
|
||||
ut8 *barg;
|
||||
int len;
|
||||
arg = skipspaces(arg);
|
||||
if (*arg=='"') {
|
||||
SKIPSPACES(arg);
|
||||
if(*arg=='"') {
|
||||
barg = (ut8*)strdup (arg+1);
|
||||
len = strlen(++arg)-1;
|
||||
arg[len]='\0';
|
||||
} else len = hexstr2raw(arg);
|
||||
// TODO: ensure last char is "
|
||||
barg[len] = '\0';
|
||||
} else {
|
||||
barg = (ut8*)strdup (arg);
|
||||
len = hexstr2raw(barg);
|
||||
}
|
||||
if (len<2) {
|
||||
printf ("Invalid hexpair\n");
|
||||
return 2;
|
||||
}
|
||||
io_seek(curseek, SEEK_SET);
|
||||
if (len<1 || io_write(arg, len)<len)
|
||||
if(len<1 || io_write(barg, len)<len) {
|
||||
perror("io_write");
|
||||
return -1;
|
||||
}
|
||||
//free ((void*)arg);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_help(char *arg) {
|
||||
if (*arg) {
|
||||
ut64 ret = str2ut64(arg);
|
||||
static int cmd_help(char *arg) {
|
||||
if(*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"
|
||||
@@ -128,63 +164,90 @@ static void cmd_help(char *arg) {
|
||||
"x[size] hexdump\n"
|
||||
"X[size] hexpair dump\n"
|
||||
"p[fmt] print formatted current block ('p' for help)\n"
|
||||
"r[-[num]] truncate or -remove N bytes\n"
|
||||
"d[size] disasemble\n"
|
||||
"r[+-[num]] truncate or -remove N bytes\n"
|
||||
".[file] interpret file\n"
|
||||
"<[file] load file in current seek\n"
|
||||
">[file] dump current block to file\n"
|
||||
"!cmd run shell command\n"
|
||||
"?expr calculate numeric expression\n"
|
||||
"q quit\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_resize(char *arg) {
|
||||
int len, ret = 0;
|
||||
if (!*arg) printf("%"LLF"d\n", (ut64)io_seek(0, SEEK_END));
|
||||
else if (*arg=='-') {
|
||||
ut8 *buf = malloc(bsize);
|
||||
if (buf) {
|
||||
ut64 i, n = str2ut64(arg+1);
|
||||
static int cmd_resize(char *arg) {
|
||||
ut8 *buf;
|
||||
ut64 tail, n;
|
||||
int i, len, ret = 0;
|
||||
switch(*arg) {
|
||||
case '\0':
|
||||
printf("%"LLF"d\n", (ut64)io_seek(0, SEEK_END));
|
||||
break;
|
||||
case '+': // XXX: needs cleanup
|
||||
n = str2ut64(arg+1);
|
||||
len = (ut64)io_seek(0, SEEK_END);
|
||||
tail = len-curseek;
|
||||
if((buf=malloc(tail))) { // XXX: Use block
|
||||
io_seek(curseek, SEEK_SET);
|
||||
io_read(buf, tail);
|
||||
io_seek(curseek+n, SEEK_SET);
|
||||
io_write(buf, tail);
|
||||
free (buf);
|
||||
} else perror("malloc");
|
||||
break;
|
||||
case '-':
|
||||
buf = malloc(bsize);
|
||||
if(buf) {
|
||||
n = str2ut64(arg+1);
|
||||
for(i=0;!ret;i+=len) {
|
||||
io_seek(curseek+n+i, SEEK_SET);
|
||||
if ((len = io_read(buf, bsize))>0) {
|
||||
if((len = io_read(buf, bsize))>0) {
|
||||
io_seek(curseek+i, SEEK_SET);
|
||||
if (io_write(buf, len)<len)
|
||||
if(io_write(buf, len)<len)
|
||||
perror("io_write"),ret=-1;
|
||||
} else perror("io_read"), ret=-1;
|
||||
} else break; //perror("io_read"), ret=-1;
|
||||
}
|
||||
free(buf);
|
||||
if ((ret = io_seek(0, SEEK_END))>n)
|
||||
if((ret = io_seek(0, SEEK_END))>n)
|
||||
ret = io_truncate(ret-n);
|
||||
}
|
||||
} else ret = io_truncate(str2ut64(arg));
|
||||
if (ret<0)
|
||||
perror("truncate");
|
||||
} else perror("malloc");
|
||||
break;
|
||||
default:
|
||||
ret = io_truncate(str2ut64(arg));
|
||||
}
|
||||
if(ret<0) perror("truncate");
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void cmd_system(char *arg) {
|
||||
static int cmd_system(char *arg) {
|
||||
int len = bsize;
|
||||
char *buf, str[1024];
|
||||
if (strstr(arg, "BLOCK")) {
|
||||
char str[1024];
|
||||
ut8 *buf;
|
||||
if(strstr(arg, "BLOCK")) {
|
||||
FILE *fd = fopen(".curblk", "wb");
|
||||
if (fd) {
|
||||
if ((buf = getcurblk("", &len))) {
|
||||
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, "OFFSET")) {
|
||||
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);
|
||||
}
|
||||
if (strstr(arg, "XOFFSET")) {
|
||||
if(strstr(arg, "XOFFSET")) {
|
||||
sprintf(str, "0x%"LLF"x", curseek);
|
||||
setenv("XOFFSET", str, 1);
|
||||
}
|
||||
if (io_system(arg)<0)
|
||||
if(io_system(arg)<0)
|
||||
perror("system");
|
||||
unlink(".curblk");
|
||||
return 1;
|
||||
}
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
#include <unistd.h>
|
||||
|
||||
int main() {
|
||||
char next=0, ch, och=0;
|
||||
while (read (0, &ch, 1)==1) {
|
||||
if (next) {
|
||||
if (ch==next)
|
||||
next = 0;
|
||||
continue;
|
||||
}
|
||||
if (och == ' ' && ch==' ')
|
||||
next = '\n';
|
||||
if (och == '0' && ch=='x')
|
||||
next = ':';
|
||||
if (!next && ch!=' ')
|
||||
write (1, &ch, 1);
|
||||
och = ch;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -1,5 +1,26 @@
|
||||
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
|
||||
|
||||
#define DEMO 0
|
||||
#if DEMO
|
||||
int bo = 0;
|
||||
char b[4096];
|
||||
static inline int io_open(char *file) {
|
||||
memset (b, 0, sizeof (b));
|
||||
return 10;
|
||||
}
|
||||
static int io_read(void *x,int y) {
|
||||
memcpy (x, b+bo, y);
|
||||
return y;
|
||||
}
|
||||
#define io_write(x,y) memcpy (b+bo, x,y)
|
||||
static int io_seek (int x,int y) {
|
||||
bo=((y==2)?sizeof(b):(y==1)?bo+x:x);
|
||||
return bo;
|
||||
}
|
||||
#define io_close() printf("close: TODO\n")
|
||||
#define io_system(x) system(x)
|
||||
#define io_truncate(x) printf("truncate: TODO\n");
|
||||
#else
|
||||
#if __WIN32__
|
||||
|
||||
#include <windows.h>
|
||||
@@ -8,7 +29,7 @@ static inline int io_open(char *file) {
|
||||
_fd = CreateFile(file, GENERIC_READ | GENERIC_WRITE,
|
||||
FILE_SHARE_READ|FILE_SHARE_WRITE,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
if (_fd == INVALID_HANDLE_VALUE)
|
||||
if(_fd == INVALID_HANDLE_VALUE)
|
||||
_fd = CreateFile(file, GENERIC_READ, FILE_SHARE_READ,
|
||||
NULL, OPEN_ALWAYS, 0, NULL);
|
||||
return (_fd==INVALID_HANDLE_VALUE)?-1:0;
|
||||
@@ -32,7 +53,7 @@ static inline int io_read(void *x, int y) {
|
||||
static int _fd = -1;
|
||||
static inline int io_open(char *file) {
|
||||
_fd = open(file, O_RDWR|O_CREAT, 0644);
|
||||
if (_fd == -1) _fd = open(file, O_RDONLY);
|
||||
if(_fd == -1) _fd = open(file, O_RDONLY);
|
||||
return _fd;
|
||||
}
|
||||
#define io_read(x,y) read(_fd, x, y)
|
||||
@@ -43,3 +64,4 @@ static inline int io_open(char *file) {
|
||||
#define io_truncate(x) ftruncate(_fd, (unsigned long)x)
|
||||
|
||||
#endif
|
||||
#endif
|
||||
@@ -1,122 +1,154 @@
|
||||
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
|
||||
/* Copyleft 2009-2013 -- pancake /at/ nopcode /dot/ org */
|
||||
|
||||
#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
|
||||
#define BUFSZ 128*1024
|
||||
|
||||
#include "red.h"
|
||||
#include "ired.h"
|
||||
#include "util.c"
|
||||
#include "calc.c"
|
||||
#include "cmd.c"
|
||||
|
||||
static void red_slurpin() {
|
||||
ut8 buf[4096];
|
||||
ut8 buf[BUFSZ];
|
||||
for(;;) {
|
||||
int len = read(0, buf, 4096);
|
||||
if (len<1) break;
|
||||
int len = read(0, buf, sizeof(buf));
|
||||
if(len<1) break;
|
||||
hexdump(buf, len, 16);
|
||||
curseek += len;
|
||||
}
|
||||
}
|
||||
|
||||
static void red_interpret(char *file) {
|
||||
char buf[1024];
|
||||
static int red_interpret(const char *file) {
|
||||
char buf[BUFSZ];
|
||||
FILE *fd = fopen(file, "r");
|
||||
if (fd != NULL) {
|
||||
if(fd != NULL) {
|
||||
for(;;) {
|
||||
if (fgets(buf, 1023, fd) == NULL)
|
||||
if(fgets(buf, sizeof(buf), fd) == NULL)
|
||||
break;
|
||||
red_cmd(buf);
|
||||
}
|
||||
fclose(fd);
|
||||
} else fprintf(stderr, "Cannot open script file '%s'\n", file);
|
||||
} else if (file)
|
||||
fprintf(stderr, "Cannot open script file '%s'\n", file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int red_cmd(char *cmd) {
|
||||
char *arg = cmd+1;
|
||||
SKIPSPACES(arg);
|
||||
switch(*cmd) {
|
||||
case 'q': return 0;
|
||||
case ';': case '#': break; // comment
|
||||
case '>': cmd_dump(cmd+1); break;
|
||||
case '<': cmd_load(cmd+1); break;
|
||||
case '.': red_interpret(skipspaces(cmd+1)); break;
|
||||
case 's': cmd_seek(cmd+1); break;
|
||||
case 'b': cmd_bsize(cmd+1); break;
|
||||
case '/': cmd_search(cmd+1); break;
|
||||
case 'p': cmd_print(cmd+1); break;
|
||||
case 'r': cmd_resize(cmd+1); break;
|
||||
case 'x': cmd_hexdump(cmd+1); break;
|
||||
case 'X': cmd_bytedump(cmd+1); break;
|
||||
case 'w': cmd_write(cmd+1); break;
|
||||
case '!': cmd_system(cmd+1); break;
|
||||
case '?': cmd_help(cmd+1); break;
|
||||
case '>': return cmd_dump(arg); break;
|
||||
case '<': return cmd_load(arg); break;
|
||||
case '.': return red_interpret(arg); break;
|
||||
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);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int red_prompt() {
|
||||
char *at, *at2, line[4096];
|
||||
if (verbose) {
|
||||
char *at, *at2, line[BUFSZ];
|
||||
if(verbose) {
|
||||
printf("[0x%08"LLF"x]> ", curseek);
|
||||
fflush(stdout);
|
||||
}
|
||||
if (fgets(line, 4095, stdin) == NULL)
|
||||
if(fgets(line, sizeof(line), stdin) == NULL)
|
||||
return 0;
|
||||
line[strlen(line)-1] = '\0';
|
||||
if (*line != '!') {
|
||||
if(*line != '!') {
|
||||
at = strchr(line, '@');
|
||||
oldseek = curseek;
|
||||
obsize = bsize;
|
||||
if (at) {
|
||||
if(at) {
|
||||
*at = 0;
|
||||
at2 = strchr(++at, ':');
|
||||
if (at2) {
|
||||
if(at2) {
|
||||
*at2 = 0; at2++;
|
||||
if (*at2) bsize = (int)str2ut64(at2);
|
||||
if(*at2) bsize = (int)str2ut64(at2);
|
||||
}
|
||||
if (*at) curseek = str2ut64(at);
|
||||
if(*at) curseek = str2ut64(at);
|
||||
}
|
||||
}
|
||||
return red_cmd(skipspaces(line));
|
||||
at = line;
|
||||
SKIPSPACES(at);
|
||||
return red_cmd(at);
|
||||
}
|
||||
|
||||
static int red_open(char *file) {
|
||||
int ret = io_open(file);
|
||||
if (ret != -1) {
|
||||
if(ret != -1) {
|
||||
oldseek = 0;
|
||||
setenv("FILE", file, 1);
|
||||
if (script)
|
||||
red_interpret(script);
|
||||
while(red_prompt()) {
|
||||
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;
|
||||
}
|
||||
io_close();
|
||||
} else fprintf(stderr, "Cannot open '%s'\n", file);
|
||||
return ret==-1 ?1:0;;
|
||||
} else if (file)
|
||||
fprintf(stderr, "Cannot open '%s'\n", file);
|
||||
return ret==-1 ?1:0;
|
||||
}
|
||||
|
||||
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;
|
||||
if (argc>1)
|
||||
for(i=1;i<argc;i++) {
|
||||
if (argv[i][0]=='-')
|
||||
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("red "VERSION" 2009"); ret = 0; break;
|
||||
case 'v': puts(VERSION); ret = 0; break;
|
||||
case 'h': ret = red_help(); break;
|
||||
case 0x0: red_slurpin(); ret = 0; break;
|
||||
} else ret = red_open(argv[i]);
|
||||
} else {
|
||||
if (!argv[i]) break;
|
||||
ret = red_open(argv[i]);
|
||||
}
|
||||
} else ret = red_help();
|
||||
free(scripts);
|
||||
return ret;
|
||||
}
|
||||
+3
-1
@@ -1,4 +1,4 @@
|
||||
#define VERSION "0.4"
|
||||
#define VERSION "0.6"
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/types.h>
|
||||
@@ -8,6 +8,8 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#define SKIPSPACES(x) for(;*(x)==' '||*(x)=='\t';x++) {};
|
||||
|
||||
#if(plan9)
|
||||
static int setenv(char *var, char *val, int force) {
|
||||
char str[256];
|
||||
@@ -0,0 +1,5 @@
|
||||
all:
|
||||
sh test.sh
|
||||
|
||||
clean:
|
||||
rm -f tmp tmp.ired
|
||||
@@ -0,0 +1,53 @@
|
||||
#!/bin/sh
|
||||
|
||||
FILES=4
|
||||
jot 1 >/dev/null
|
||||
if [ $? = 0 ]; then
|
||||
SEQ=`jot $FILES 1 $FILES`
|
||||
else
|
||||
md5=`seq 1 $FILES`
|
||||
fi
|
||||
|
||||
|
||||
md5sum -h 2>/dev/null
|
||||
if [ $? = 0 ]; then
|
||||
md5=md5sum
|
||||
else
|
||||
md5=md5
|
||||
fi
|
||||
|
||||
function hash {
|
||||
$md5 $1 | awk '{print $1}'
|
||||
}
|
||||
|
||||
function btest {
|
||||
cp $1 tmp
|
||||
../bdiff $1 $2 > tmp.ired
|
||||
../ired -n tmp < tmp.ired
|
||||
test `hash tmp` = `hash $2`
|
||||
ret=$?
|
||||
echo $ret $1 $2
|
||||
if [ $ret = 1 ]; then
|
||||
if [ -n "`echo $1| grep file`" ]; then
|
||||
diff -u $2 tmp
|
||||
fi
|
||||
fi
|
||||
#/ rm -f tmp.ired tmp
|
||||
}
|
||||
|
||||
(cd .. && make -s)
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
btest $1 $2
|
||||
else
|
||||
for i in $SEQ ; do
|
||||
for j in $SEQ ; do
|
||||
btest file$i file$j
|
||||
done
|
||||
done
|
||||
fi
|
||||
|
||||
#btest /etc/services /etc/fstab
|
||||
|
||||
#btest /bin/true /bin/false
|
||||
#radiff /bin/false tmp
|
||||
@@ -1,27 +1,18 @@
|
||||
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
|
||||
/* ired - Copyleft 2009-2013 -- pancake */
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
static inline char *skipspaces(char *arg) {
|
||||
while (*arg==' '||*arg=='\t') arg++;
|
||||
return arg;
|
||||
}
|
||||
|
||||
static inline void hexdump(const ut8 *buf, unsigned int len, int w) {
|
||||
unsigned int i, j;
|
||||
for(i=0;i<len;i+=w) {
|
||||
printf("0x%08"LLF"x ", curseek+i);
|
||||
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]);
|
||||
}
|
||||
for(j=i;j<i+w;j++) {
|
||||
if (j>=len) printf(" ");
|
||||
else printf("%c", isprint(buf[j])?buf[j]:'.');
|
||||
if(j<len) printf(j%2?"%02x ":"%02x", buf[j]);
|
||||
else printf(j%2?" ":" ");
|
||||
}
|
||||
printf(" ");
|
||||
for(j=i;j<i+w;j++)
|
||||
printf("%c", isprint(buf[j])?buf[j]:'.');
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
@@ -33,19 +24,19 @@ static void print_fmt(const ut8 *buf, char *fmt, unsigned int len) {
|
||||
for(;(*fmt||rep);fmt++) {
|
||||
up = rep?rep:*fmt;
|
||||
switch(up) {
|
||||
case 'i': if (len>3) printf("%d\n", ((buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3])); inc=4; break;
|
||||
case 'I': if (len>3) printf("%d\n", ((buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0])); inc=4; break;
|
||||
case 's': if (len>1) printf("%d\n", (buf[0]<<8 | buf[1])); inc=2; break;
|
||||
case 'S': if (len>1) printf("%d\n", (buf[1]<<8 | buf[0])); inc=2; break;
|
||||
case 'o': if (len>0) printf("0%o\n", buf[0]); inc=1; break;
|
||||
case 'b': if (len>0) printf("0x%02x\n", buf[0]); inc=1; break;
|
||||
case 'w': if (len>1) printf("0x%02x%02x\n", buf[1], buf[0]); inc=2; break;
|
||||
case 'W': if (len>1) printf("0x%02x%02x\n", buf[0], buf[1]); inc=2; break;
|
||||
case 'd': if (len>3) printf("0x%02x%02x%02x%02x\n",buf[3], buf[2], buf[1], buf[0]); inc=4; break;
|
||||
case 'D': if (len>3) printf("0x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3]); inc=4; break;
|
||||
case 'q': if (len>7) printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
case 'i': if(len>3) printf("%d\n", ((buf[0]<<24) | (buf[1]<<16) | (buf[2]<<8) | buf[3])); inc=4; break;
|
||||
case 'I': if(len>3) printf("%d\n", ((buf[3]<<24) | (buf[2]<<16) | (buf[1]<<8) | buf[0])); inc=4; break;
|
||||
case 's': if(len>1) printf("%d\n", (buf[0]<<8 | buf[1])); inc=2; break;
|
||||
case 'S': if(len>1) printf("%d\n", (buf[1]<<8 | buf[0])); inc=2; break;
|
||||
case 'o': if(len>0) printf("0%o\n", buf[0]); inc=1; break;
|
||||
case 'b': if(len>0) printf("0x%02x\n", buf[0]); inc=1; break;
|
||||
case 'w': if(len>1) printf("0x%02x%02x\n", buf[1], buf[0]); inc=2; break;
|
||||
case 'W': if(len>1) printf("0x%02x%02x\n", buf[0], buf[1]); inc=2; break;
|
||||
case 'd': if(len>3) printf("0x%02x%02x%02x%02x\n",buf[3], buf[2], buf[1], buf[0]); inc=4; break;
|
||||
case 'D': if(len>3) printf("0x%02x%02x%02x%02x\n", buf[0], buf[1], buf[2], buf[3]); inc=4; break;
|
||||
case 'q': if(len>7) printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
buf[7], buf[6], buf[5], buf[4], buf[3], buf[2], buf[1], buf[0]); inc=8; break;
|
||||
case 'Q': if (len>7) printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
case 'Q': if(len>7) printf("0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
|
||||
buf[0], buf[1], buf[2], buf[3], buf[4], buf[5], buf[6], buf[7]); inc=8; break;
|
||||
case '.': inc=1; break;
|
||||
case ':': inc=4; break;
|
||||
@@ -55,50 +46,50 @@ static void print_fmt(const ut8 *buf, char *fmt, unsigned int len) {
|
||||
default: fprintf(stderr, "Unknown format '%c' (%d)\n", up, up);
|
||||
return;
|
||||
}
|
||||
if (!rep) lup = up;
|
||||
if(!rep) lup = up;
|
||||
buf += inc;
|
||||
if (inc>len) break;
|
||||
if(inc>len) break;
|
||||
len -= inc;
|
||||
}
|
||||
fmt = ofmt;
|
||||
} while(!rep && inc && inc<len);
|
||||
}
|
||||
|
||||
static ut64 str2ut64(char *str) {
|
||||
static ut64 str2ut64(const char *str) {
|
||||
ut64 ret = 0LL;
|
||||
str = skipspaces(str);
|
||||
if (str[0]=='b'&&str[1]=='\0')
|
||||
SKIPSPACES(str);
|
||||
if(str[0]=='b'&&str[1]=='\0')
|
||||
ret = bsize;
|
||||
else if (str[0]=='0') {
|
||||
if (str[1]=='x') sscanf(str, "0x%"LLF"x", &ret);
|
||||
else if(str[0]=='0') {
|
||||
if(str[1]=='x') sscanf(str, "0x%"LLF"x", &ret);
|
||||
else sscanf(str, "0x%"LLF"o", &ret);
|
||||
} else sscanf(str, "%"LLF"u", &ret);
|
||||
str += strlen(str)-1;
|
||||
if (*str=='K') ret *= 1024;
|
||||
else if (*str=='M') ret *= 1024*1024;
|
||||
else if (*str=='G') ret *= 1024*1024*1024;
|
||||
if(*str=='K') ret *= 1024;
|
||||
else if(*str=='M') ret *= 1024*1024;
|
||||
else if(*str=='G') ret *= 1024*1024*1024;
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int hex2byte(ut8 *val, ut8 c) {
|
||||
if ('0' <= c && c <= '9') *val = (ut8)(*val) * 16 + ( c - '0');
|
||||
else if (c >= 'A' && c <= 'F') *val = (ut8)(*val) * 16 + ( c - 'A' + 10);
|
||||
else if (c >= 'a' && c <= 'f') *val = (ut8)(*val) * 16 + ( c - 'a' + 10);
|
||||
if('0' <= c && c <= '9') *val = (ut8)(*val) * 16 + ( c - '0');
|
||||
else if(c >= 'A' && c <= 'F') *val = (ut8)(*val) * 16 + ( c - 'A' + 10);
|
||||
else if(c >= 'a' && c <= 'f') *val = (ut8)(*val) * 16 + ( c - 'a' + 10);
|
||||
else return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static unsigned int hexstr2raw(char *arg) {
|
||||
static unsigned int hexstr2raw(ut8 *arg) {
|
||||
ut8 *ptr, d, c = 0;
|
||||
unsigned int j = 0, len = 0;
|
||||
for (ptr=(ut8 *)arg; *ptr; ptr++) {
|
||||
if (*ptr==' ') continue;
|
||||
for(ptr=(ut8 *)arg; *ptr; ptr++) {
|
||||
if(*ptr==' ') continue;
|
||||
d = c;
|
||||
if (hex2byte(&c, *ptr))
|
||||
if(hex2byte(&c, *ptr))
|
||||
return -1;
|
||||
c |= d;
|
||||
if (!j++) c <<= 4;
|
||||
else if (j==2) {
|
||||
if(!j++) c <<= 4;
|
||||
else if(j==2) {
|
||||
arg[len++] = c;
|
||||
c = j = 0;
|
||||
}
|
||||
@@ -106,14 +97,14 @@ static unsigned int hexstr2raw(char *arg) {
|
||||
return len;
|
||||
}
|
||||
|
||||
static void *getcurblk(char *arg, int *len) {
|
||||
void *buf = NULL;
|
||||
if (*arg) {
|
||||
*len = (int)str2ut64(arg);
|
||||
if (*len<1) *len = bsize;
|
||||
static ut8 *getcurblk(const char *arg, int *len) {
|
||||
ut8 *buf = NULL;
|
||||
if(*arg) {
|
||||
*len = (int)str2ut64((const char *)arg);
|
||||
if(*len<1) *len = bsize;
|
||||
}
|
||||
if (*len>0 && (buf = malloc(*len)) != NULL) {
|
||||
if (io_seek((int)curseek, SEEK_SET)<0) {
|
||||
if(*len>0 && (buf = malloc(*len)) != NULL) {
|
||||
if(io_seek((int)curseek, SEEK_SET)<0) {
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
} else *len = io_read(buf, *len);
|
||||
|
||||
@@ -1,51 +1,75 @@
|
||||
#!/bin/sh
|
||||
# vired: the visual raw editor
|
||||
# copyleft: pancake at nopcode dot org @ 2009
|
||||
# copyleft: pancake at nopcode dot org @ 2009-2013
|
||||
|
||||
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
|
||||
Reference in new issue
Block a user