40 Commits
Author SHA1 Message Date
pancake 2dca803f6d Release 0.5 - Fix minor C warning 2013-07-08 01:04:45 +02:00
pancake fba8f8e1a7 'make dist' uses git now 2013-06-10 02:01:56 +02:00
pancake afbe2e04f6 Fix write command 2013-05-17 18:24:06 +02:00
pancake 085b908d37 Initial support for return values in commands 2013-05-17 17:16:25 +02:00
pancake 4f1d810e98 Fix < command using io_seek 2013-05-17 14:26:25 +02:00
pancake bed1916abc Use markdown in readme and update copyleft timestamps 2013-02-18 17:33:19 +01:00
pancake 36e027fe48 Remove deprecated gitpush.sh 2012-06-29 00:57:11 +02:00
pancake 3fef4efbb5 Fix makefile dependencies and make tests work on osx 2012-06-29 00:50:55 +02:00
pancake 0e0f906f66 Still broken but a bit little fixed 2012-06-27 18:44:13 +02:00
pancake 5fee57d158 * Fix ired 2012-06-27 18:28:28 +02:00
pancake 75b31677e4 * fix -v output and free() warning 2012-03-07 11:56:37 +01:00
pancake 687644afdd * Fix make install when ired is running
* Minor fixes in README
2011-07-28 18:18:07 +02:00
pancake ac04c6e95e * Add initial gitpush script for github integration 2011-07-28 18:09:51 +02:00
pancake 204dbde78e * Properly fix all those signed/unsigned issues 2011-07-28 18:04:01 +02:00
pancake b6db2f859f * Fix search for bytes >0x7f. Thanks Dreyer! 2011-07-26 11:06:41 +02:00
pancake@dazo 6e0f3122b6 * Add patch from @jsegura fixing make clean 2010-09-22 19:51:20 +02:00
pancake@dazo 718330da85 * merge 2010-09-22 19:50:52 +02:00
pancake fca56e2c20 * Fix seeking on scripts 2010-07-22 14:49:36 +02:00
pancake@dazo 4d81079a14 * hexdump output is easily parseable
* Add hexparse.c
2010-06-14 00:45:16 +02:00
pancake@dazo 5a5595ced6 * Add missing TODO file 2010-05-12 10:05:06 +02:00
pancake@dazo f6a4705bf7 * Fix segfault when hexdumping -1 bytes 2010-05-12 10:00:07 +02:00
pancake@dazo b6649372ab * Various syntax fixes (like in suckless.org style)
* Update license headers (we are in 2010)
* Fix slurp in bdiff.c
2010-04-29 11:25:37 +02:00
pancake@flubox2 8bdc8dc92d * Merge heads 2010-02-09 17:33:55 +01:00
pancake@dazo 88c93994a0 * Initial import of 'bdiff'
* Added test suite for bdiff
* Looks like its buggy in some situations
2010-02-06 18:48:51 +01:00
pancake@dazo 0f9a7f7a1b * Added 'r+' command to resize file N bytes at curseek
* Increase the maximum length of input buffers
2010-02-06 14:02:06 +01:00
pancake@flubox 4ddf34f1f8 * Fix make dist for old versions of mercurial 2009-12-22 13:58:24 +01:00
pancake@flubox 6d744e39a7 * Bump revision to 0.5
* Default install directory is /usr/local
* Rename red.h to ired.h

--HG--
rename : red.h => ired.h
2009-12-22 13:56:01 +01:00
pancake@flubox 28d49ebd95 * Release ired 0.4
* Set PATH in vired to run it from current directory
2009-12-22 13:50:45 +01:00
[email protected] 4312ed31c8 * Updated manpages with documentation about environment
* Lot of small code cleanups (reduce code to 500LOC)
  - Sort include directives
  - Fix return value when file open fails
  - Reduce function exit points
  - More use of the ? operator
  - Bigger buffers for variables
* Add more checks in many places
  - Show errors when something is wrong
  - Check for negative values
  - Use ut8 and ut64 when possible
2009-10-07 02:48:18 +02:00
pancake@flubox 4bc37cd723 * Initial support for plan9
- Use 'mk' to build.
  - Needs to be cleaned up
  - system and env access are ugly hacks
  - Some vars have been renamed to avoid p9 collisions
* Handle return values of read/write calls
  - Ubuntu's gcc is no warning anymore
2009-09-23 18:26:53 +02:00
[email protected] 763874f484 * Fixed c99 pedantic warning (signed issue in scanf) 2009-09-03 13:45:49 +00:00
[email protected] 11bebe5268 * mkdir before install 2009-09-03 11:17:48 +00:00
pancake@flubox fc76d60385 * Fix segfault when extending an invalid-format character (f.ex: px*) 2009-09-02 16:58:48 +02:00
[email protected] 0f3faf1144 * Add 'uninstall' makefile target
* Added DESTDIR in makefile
2009-09-01 22:51:53 +00:00
[email protected] 86f8b84cb4 * Update ChangeLog file
* Do not build with -g
2009-09-01 22:31:48 +00:00
[email protected] 02c4366a6f * Add manpages for ired and vired
* Compile with debugging information by default
* Added 'make dist' target
* Fix double free in cmd.c
* Fix disassemble mode in 'p' key of vired
2009-09-01 22:30:01 +00:00
[email protected] af5d0384c4 * Rename from red to ired to avoid program name collisions
--HG--
rename : red.c => ired.c
2009-09-01 21:17:05 +00:00
pancake@flubox f80aa1f2b6 * Fix search command. Oops :) 2009-07-17 11:47:55 +02:00
[email protected] 02d6fe4b53 * Fix segfault in cmd_search() 2009-07-12 01:22:15 +00:00
[email protected] 5ce5aeff66 * Bump revision number to 0.2 2009-07-11 16:31:06 +00:00
24 changed files with 1588 additions and 373 deletions

No files matched your search

+415
View File
@@ -0,0 +1,415 @@
== release 0.2
changeset: 41:6fd885d7d0c2
tag: tip
user: [email protected]
date: Tue Sep 01 22:30:01 2009 +0000
files: ChangeLog Makefile cmd.c ired.1 vired vired.1
description:
* Add manpages for ired and vired
* Compile with debugging information by default
* Added 'make dist' target
* Fix double free in cmd.c
* Fix disassemble mode in 'p' key of vired
changeset: 40:97b4743c4dc6
user: [email protected]
date: Tue Sep 01 21:17:05 2009 +0000
files: Makefile ired.c red.c
description:
* Rename from red to ired to avoid program name collisions
changeset: 39:03da6e158902
user: pancake@flubox
date: Fri Jul 17 11:47:55 2009 +0200
files: Makefile cmd.c
description:
* Fix search command. Oops :)
changeset: 38:1715fc1d195e
user: [email protected]
date: Sun Jul 12 01:22:15 2009 +0000
files: cmd.c
description:
* Fix segfault in cmd_search()
changeset: 37:8ff91ac81732
user: [email protected]
date: Sat Jul 11 16:31:06 2009 +0000
files: ChangeLog red.h
description:
* Bump revision number to 0.2
== release 0.1
changeset: 36:ba4108a3c6d5
tag: tip
user: [email protected]
date: Sat Jul 11 16:28:35 2009 +0000
files: cmd.c
description:
* Fix gcc warning. Release 0.1
changeset: 35:a69c81ce6b79
user: [email protected]
date: Sat Jul 11 16:15:18 2009 +0000
files: Makefile
description:
* Use CFLAGS when compiling
changeset: 34:d3c02ddef876
user: [email protected]
date: Sat Jul 11 16:14:37 2009 +0000
files: cmd.c
description:
* Fix '!' command segfault
- Initialize buf in search command
changeset: 33:cd894a746246
user: [email protected]
date: Sat Jul 11 13:58:12 2009 +0000
files: util.c
description:
* Use 'isascii' instead of buf[0] for pz and pZ
changeset: 32:795733b782ee
user: [email protected]
date: Sat Jul 11 13:41:51 2009 +0000
files: io.c red.h
description:
* Full implementation of the w32 IO API
changeset: 31:af7a10ccfed7
user: [email protected]
date: Sat Jul 11 13:20:11 2009 +0000
files: Makefile red.h
description:
* First build for w32
- Added 'make w32'
- TODO: Use w32 IO API instead of posix by default on w32
changeset: 30:23d74ef2b61b
user: [email protected]
date: Sat Jul 11 13:09:01 2009 +0000
files: README
description:
* Some minor changes in README
changeset: 29:f46469969239
user: [email protected]
date: Sat Jul 11 13:02:59 2009 +0000
files: Makefile util.c
description:
* Added support for 'K' 'M' and 'G' suffix in str2ull function
- Added support for octal input (start with '0')
- po command shows in the same octal way ('0' prefix)
* Fix hexstr2bin with spaces
* Do not make loc vired
changeset: 28:bdcc2e8cfb90
user: [email protected]
date: Sat Jul 11 10:58:28 2009 +0000
files: cmd.c
description:
* Some code review and simplification -10LOC
changeset: 27:b944c1a84437
user: [email protected]
date: Sat Jul 11 10:54:29 2009 +0000
files: README red.c
description:
* Minor fix in README
* Remove end '.' in error message
changeset: 26:26582b52ed09
user: [email protected]
date: Sat Jul 11 10:52:13 2009 +0000
files: util.c
description:
* Fix build
changeset: 25:05b4d6b61a48
user: [email protected]
date: Sat Jul 11 10:50:22 2009 +0000
files: README
description:
* Fix README
changeset: 24:ef1a2671bbc6
user: [email protected]
date: Sat Jul 11 10:47:11 2009 +0000
files: cmd.c io.c red.c util.c
description:
* hexdump() now gets a 3rd argument to set the width
* Show filesize when no args given to 'r' command
- Truncate file when removing bytes (f.ex: r-10)
* Fix segfault in cmd_system() when no BLOCK is used, but [X]OFFSET is
* skipspaces() is now skipping 'all' spaces, not only the first one
* Some code cleanup (-5 LOC) - now is 499 LOC :P
changeset: 23:4f672b5b67b9
user: [email protected]
date: Sat Jul 11 01:26:54 2009 +0000
files: cmd.c vired
description:
* Fix segfault coz an uninitialized variable
* 'r' with no argument should return filesize
- not implemented
changeset: 22:0b6a9d1bcae2
user: [email protected]
date: Sat Jul 11 01:20:51 2009 +0000
files: Makefile cmd.c io.c red.c vired
description:
* Add command 'r' to resize and remove bytes
r128 : truncate file to 128 bytes
r-10 : remove 10 bytes from current seek
* Added io_truncate
* warning: 500LOC reached :)
changeset: 21:1de30455d1c5
user: [email protected]
date: Sat Jul 11 00:34:57 2009 +0000
files: red.c
description:
* Simplify argv parsing (-1 LOC)
changeset: 20:d37eb8dbb125
user: [email protected]
date: Sat Jul 11 00:27:02 2009 +0000
files: cmd.c red.c util.c
description:
* Add '?' in help message
* Simplify and add more checks in cmd_system()
- setenv FILE once
* Simplify code for parsing arguments
- Minor simplification in hexstr2raw
changeset: 19:f455f21e48f9
user: [email protected]
date: Sat Jul 11 00:07:45 2009 +0000
files: Makefile cmd.c red.c util.c
description:
* Code cleanup (-18 LOC)
- Move print_fmt stuff into utils.c
* Use static in more functions
changeset: 18:de171facddfb
user: [email protected]
date: Fri Jul 10 23:43:24 2009 +0000
files: Makefile cmd.c
description:
* Fix some valgrind warnings in the print format command
- Some uninitialized variable usage
- Out of buffer reads are now controlled
- repeat last print format until the end of the block
changeset: 17:48f165d7837a
user: [email protected]
date: Fri Jul 10 23:22:23 2009 +0000
files: cmd.c util.c vired
description:
* Set vired block size to 256
- Set P='' to avoid env interference
* Do not overwrite bsize
changeset: 16:edef8bd2b6ca
user: [email protected]
date: Fri Jul 10 20:41:16 2009 +0000
files: README cmd.c red.c
description:
* Initial implementation of the 'p' command to print
current block as a formatted buffer ('p' for help)
* Add 'X' command in the help message
* Do not parse '@' if ! is used
changeset: 15:7097e08566c4
user: pancake@flubox
date: Fri Jul 10 20:00:12 2009 +0200
files: util.c vired
description:
* Added support for 's+b' and 's-b'
changeset: 14:1c28afb4af0b
user: pancake@flubox
date: Fri Jul 10 19:54:26 2009 +0200
files: README cmd.c
description:
* Define new 'p' command in README
* Fix help message for 'w' command
changeset: 13:963aaffb26b7
user: pancake@flubox
date: Fri Jul 10 18:40:27 2009 +0200
files: cmd.c
description:
* Fix obsize in cmd_bsize()
changeset: 12:fc86586c1084
user: pancake@flubox
date: Fri Jul 10 18:29:30 2009 +0200
files: cmd.c red.c util.c
description:
* Split hexdump() in util.c
* Added support for ':' syntax for temporal blocksize
* Added '-' for slurping stdin like hexdump -C
changeset: 11:dff8083d3b66
user: pancake@flubox
date: Fri Jul 10 18:10:09 2009 +0200
files: cmd.c util.c
description:
* Fix end-of-file and out-of-file IO reads
-2 LOC :)
changeset: 10:0ef965f1cd6b
user: pancake@flubox
date: Tue Jul 07 18:28:24 2009 +0200
files: README cmd.c red.c util.c
description:
* Use ut64 and ut8 instead of ull and uc8
- More consistent type names. radare and libr must change this too
changeset: 9:ce9c10de16dd
user: pancake@flubox
date: Tue Jul 07 18:00:01 2009 +0200
files: io.c red.c util.c
description:
* Use oneliner switch statements for single ops
- Safe -29 LOC
* Fix previous commit (broken build)
* Internal io fd has been renamed to fix a bug
changeset: 8:5ff3f119598c
user: pancake@flubox
date: Tue Jul 07 17:49:35 2009 +0200
files: io.c
description:
* io layer rewritten as cpp macros
- earn -23LOC
changeset: 7:f3d9af189f4c
user: pancake@flubox
date: Tue Jul 07 11:53:45 2009 +0200
files: vired
description:
* Do not use 'read -n' coz is posix shell
changeset: 6:e9dd080db646
user: [email protected]
date: Tue Jul 07 09:41:52 2009 +0000
files: README cmd.c io.c red.c util.c vired
description:
* Added '>' and '<' command to dump and load bytes
from/to files and current block
* Added '.' command to interpret files
* Fix vired for iphoneos (no /dev/stderr, only /dev/tty)
* Some code simplification (reduced some LOCs)
changeset: 5:62eeb4806234
user: [email protected]
date: Mon Jul 06 10:11:34 2009 +0000
files: cmd.c red.c vired
description:
* Implement '/' search command for hex and strings
* Export OFFSET, XOFFSET, FILE and BLOCK environment
to the system '!' command
* Rename '-s' to '-n'
* Make vired self-sufficient
- 'p' toggles between hexa and disasm (using rasm2 -d -)
- Added 'b' key to change block size
- '?' key show help
changeset: 4:3aec8e4c3367
user: [email protected]
date: Sun Jul 05 23:33:51 2009 +0000
files: Makefile cmd.c io.c red.c vired
description:
* Initial import of 'vired'
- The shellscript implementation of the visual mode for 'red'
* Added support to relative change the block size
* Added '!' command to run shell commands
* Added 'X' command to print curblock as hexpairs
changeset: 3:d81b7e09cbce
user: [email protected]
date: Sun Jul 05 22:49:48 2009 +0000
files: cmd.c io.c red.c red.h util.c
description:
* Abstract io stuff in io.c
* 's' command displays curseek when no arg given
- s+ and s- are used to do relative seeks
* Fix 64 bit hexa parsing
* 256 bytes as default block size
changeset: 2:0081ce1e5731
user: [email protected]
date: Sat Jul 04 20:42:27 2009 +0000
files: Makefile cmd.c red.c util.c
description:
* Implement 'w' command to write hexpairs and strings
* Fix hexdump for short buffers
* Added help message and flags for the shell
-h for help
-i [file] interpret file
-s silent
-v version
changeset: 1:75196ad1be66
user: [email protected]
date: Fri Jul 03 20:12:28 2009 +0000
files: Makefile red.c
description:
* Add install target.
* Fix 0arg run
changeset: 0:ed796be9f25e
user: pancake@flubox
date: Fri Jul 03 20:11:24 2009 +0200
files: Makefile README cmd.c red.c red.h util.c
description:
* Initial import of 'red' the raw editor
- A minimalistic implementation of the radare shell
+36 -8
View File
@@ -1,20 +1,48 @@
CC?=gcc
VERSION=0.5
CCw32?=i486-mingw32-gcc
CFLAGS+=-Wall -O2
PREFIX?=/usr
CFLAGS+=-O2 -Wall
CFLAGS+=-DVERSION=\"${VERSION}\"
PREFIX?=/usr/local
DESTDIR?=
all:
${CC} ${CFLAGS} red.c -o red
all: ired bdiff
bdiff: bdiff.o
${CC} ${CFLAGS} bdiff.o -o bdiff
ired.o: cmd.c io.c util.c hexparse.c
ired: ired.o
${CC} ${CFLAGS} ired.o -o ired
dist:
@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}
w32:
${CCw32} ${CFLAGS} red.c -o red.exe
${CCw32} ${CFLAGS} ired.c -o ired.exe
loc:
@wc -l *.c *.h | grep total
clean:
rm -f red red.o
rm -f ired ired.o bdiff bdiff.o
install:
cp red ${PREFIX}/bin
cp vired ${PREFIX}/bin
mkdir -p ${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 -f ired.1 ${DESTDIR}${PREFIX}/share/man/man1
cp -f vired.1 ${DESTDIR}${PREFIX}/share/man/man1
deinstall uninstall:
rm -f ${DESTDIR}${PREFIX}/bin/ired
rm -f ${DESTDIR}${PREFIX}/bin/vired
rm -f ${DESTDIR}${PREFIX}/share/man/man1/ired.1
rm -f ${DESTDIR}${PREFIX}/share/man/man1/vired.1
-44
View File
@@ -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)
+55
View File
@@ -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)
+13
View File
@@ -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
+360
View File
@@ -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;
}
+189 -114
View File
@@ -1,174 +1,249 @@
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
/* Copyleft 2009-2013 -- pancake /at/ nopcode /dot/ org */
static void cmd_hexdump(char *arg) {
unsigned int len = bsize;
unsigned char *buf = getcurblk(arg, &len);
if (buf) {
static int cmd_hexdump(char *arg) {
int len = bsize;
ut8 *buf = getcurblk(arg, &len);
if(buf && len>0) {
hexdump(buf, len, 16);
free(buf);
return 1;
}
return 2;
}
static void cmd_print(char *arg) {
unsigned char *buf;
unsigned int len = bsize;
if (*arg) {
static int cmd_print(char *arg) {
ut8 *buf;
int len = bsize;
if(*arg) {
buf = getcurblk(arg, &len);
if (!buf) return;
if(!buf) return 2;
print_fmt(buf, arg, len);
free(buf);
} else printf(
"ob/wW/dD/qQ byte (oct,hex), word, dword, qword (little, big endian)\n"
"ob/wW/dD/qQ byte (oct,hex), word, dword, qword (lil, big endian)\n"
"i/I/f/F int32 (lil, big), float (lil, big)\n"
"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) {
unsigned int i, len = bsize;
unsigned char *buf = getcurblk(arg, &len);
if (!buf) return;
static int cmd_bytedump(const char *arg) {
int i, len = bsize;
ut8 *buf = getcurblk(arg, &len);
if(!buf) return 2;
for(i=0;i<len;i++)
printf("%02x", buf[i]);
printf("\n");
free(buf);
return 1;
}
void cmd_search(char *arg) {
unsigned char *buf = NULL;
unsigned 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("", &len)))
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)
printf("0x%llx\n", seek+i-len+1);
if(barg[hit++]!=buf[i]) hit = 0;
else if(hit == len)
printf("0x%"LLF"x\n", curseek+i-len+1);
}
seek+=bsize;
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("%lld\n", seek);
else if (*arg=='+') oseek = seek += str2ut64(arg+1);
else if (*arg=='-') oseek = seek -= str2ut64(arg+1);
else oseek = seek = str2ut64(arg);
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);
io_seek((oldseek=curseek), 0);
return 1;
}
static void cmd_dump(char *file) {
unsigned int len = bsize;
void *buf = getcurblk("", &len);
FILE *fd = fopen(file, "wb");
fwrite(buf, len, 1, fd);
fclose(fd);
free(buf);
static int cmd_dump(char *file) {
int len = bsize;
ut8 *buf = getcurblk("", &len);
if(len<1 || buf) {
FILE *fd = fopen(file, "wb");
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) {
void *buf;
static int cmd_load(char *file) {
FILE *fd = fopen(file, "rb");
if (!fd) return;
buf = malloc(bsize);
if (!buf) return;
io_write(buf, fread(buf, 1, bsize, fd));
fclose(fd);
free(buf);
if(fd) {
void *buf = malloc(bsize);
if(bsize>0 && buf) {
int len = fread(buf, 1, bsize, fd);
if(len<bsize)
perror("fread");
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) {
unsigned int len;
arg = skipspaces(arg);
if (*arg=='"') {
arg++;
len = strlen(arg)-1;
arg[len]='\0';
} else len = hexstr2raw(arg);
io_seek(seek, SEEK_SET);
io_write(arg, len);
static int cmd_write(const char *arg) {
ut8 *barg;
int len;
SKIPSPACES(arg);
if(*arg=='"') {
barg = (ut8*)strdup (arg+1);
len = strlen(++arg)-1;
// 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(barg, len)<len) {
perror("io_write");
return -1;
}
//free ((void*)arg);
return 1;
}
static void cmd_help(char *arg) {
if (*arg) {
static int cmd_help(char *arg) {
if(*arg) {
ut64 ret = str2ut64(arg);
printf("0x%llx %lld 0%llo\n", ret, ret, ret);
printf("0x%"LLF"x %"LLF"d 0%"LLF"o\n", ret, ret, ret);
} else printf(
"s[+-addr] seek to relative or absolute address\n"
"b[+-size] change block size\n"
"w[hex|\"str\"] write hexpair or string\n"
"/[hex|\"str\"] search hexpair or string\n"
"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"
".[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");
"s[+-addr] seek to relative or absolute address\n"
"b[+-size] change block size\n"
"w[hex|\"str\"] write hexpair or string\n"
"/[hex|\"str\"] search hexpair or string\n"
"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"
".[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) {
unsigned int len;
if (!*arg) printf("%lld\n", io_seek(0, SEEK_END));
else if (*arg=='-') {
ut8 *buf = malloc(bsize);
ut64 i, n = str2ut64(arg+1);
if (buf) {
for(i=0;;i+=len) {
io_seek(seek+n+i, SEEK_SET);
len = io_read(buf, bsize);
if (len<1) break;
io_seek(seek+i, SEEK_SET);
io_write(buf, len);
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) {
io_seek(curseek+i, SEEK_SET);
if(io_write(buf, len)<len)
perror("io_write"),ret=-1;
} else break; //perror("io_read"), ret=-1;
}
free(buf);
}
io_truncate(io_seek(0, SEEK_END)-n);
} else io_truncate(str2ut64(arg));
if((ret = io_seek(0, SEEK_END))>n)
ret = io_truncate(ret-n);
} else perror("malloc");
break;
default:
ret = io_truncate(str2ut64(arg));
}
if(ret<0) perror("truncate");
return 1;
}
static void cmd_system(char *arg) {
unsigned int len = bsize;
char *buf = NULL, str[64];
if (strstr(arg, "BLOCK")) {
FILE *fd = fopen(".curblk", "w");
if (fd) {
buf = getcurblk("", &len);
if (buf) {
static int cmd_system(char *arg) {
int len = bsize;
char str[1024];
ut8 *buf;
if(strstr(arg, "BLOCK")) {
FILE *fd = fopen(".curblk", "wb");
if(fd) {
if((buf = getcurblk("", &len))) {
setenv("BLOCK", ".curblk", 1);
fwrite(buf, len, 1, fd);
fclose(fd);
if(fwrite(buf, len, 1, fd)<len)
perror("fwrite");
free(buf);
}
fclose(fd);
}
}
if (strstr(arg, "OFFSET")) {
sprintf(str, "%lld", seek);
setenv("OFFSET", str, 1); // XXX
if(strstr(arg, "OFFSET")) {
sprintf(str, "%"LLF"d", curseek);
setenv("OFFSET", str, 1);
}
if (strstr(arg, "XOFFSET")) {
sprintf(str, "0x%llx", seek);
setenv("XOFFSET", str, 1); // XXX
if(strstr(arg, "XOFFSET")) {
sprintf(str, "0x%"LLF"x", curseek);
setenv("XOFFSET", str, 1);
}
io_system(arg);
if(io_system(arg)<0)
perror("system");
unlink(".curblk");
free(buf);
return 1;
}
+20
View File
@@ -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;
}
+35 -13
View File
@@ -1,39 +1,59 @@
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#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>
static HANDLE _fd = NULL;
#define setenv(x,y,z) SetEnvironmentVariable(x, y)
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;
}
static int io_read(void *x, int y) {
static inline int io_read(void *x, int y) {
DWORD ret;
return ReadFile(_fd,x,y,&ret,NULL)?ret:-1;
return ReadFile(_fd, x, y, &ret, NULL)?ret:-1;
}
#define setenv(x,y,z) SetEnvironmentVariable(x, y)
#define io_write(x,y) WriteFile(_fd, x, y, NULL, NULL)
#define io_seek(x,y) SetFilePointer(_fd,x,0,!y?FILE_BEGIN:y==1?FILE_CURRENT:FILE_END)
#define io_close() CloseHandle(_fd)
#define io_system(x) system(x)
#define io_truncate(x) { io_seek(x,SEEK_SET); SetEndOfFile(_fd); }
#define io_truncate(x) 0; { io_seek(x,SEEK_SET); SetEndOfFile(_fd); }
#else
#define _FILE_OFFSET_BITS 64
#define _GNU_SOURCE
#include <fcntl.h>
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)
@@ -41,5 +61,7 @@ static inline int io_open(char *file) {
#define io_seek(x,y) lseek(_fd, x, y)
#define io_close() close(_fd)
#define io_system(x) system(x)
#define io_truncate(x) ftruncate(_fd,(unsigned long)x)
#define io_truncate(x) ftruncate(_fd, (unsigned long)x)
#endif
#endif
+123
View File
@@ -0,0 +1,123 @@
.Dd Oct 7, 2009
.Dt IRED 1
.Os
.Th IRED 1
.Sh NAME
ired \- interactive raw editor
.Sh SYNOPSIS
.Nm ired
.Op Fl hnv
.Op Fl i Ar script
.Ar file ...
.Sh DESCRIPTION
Simple and minimal hexadecimal editor based on radare concepts
.Pp
The program arguments are:
.Pp
.Bl -tag -width Fl
.It Fl h
Show help message
.It Fl v
Show version information
.It Fl n
Do not be verbose
.It Fl i Ar script
Interpret a script file as ired commands.
.Pp
Same as "ired file < script"
.El
.PP
.Sh COMMANDS
.Pp
.Bl -tag -width Fl
.It s[+-addr]
seek to relative or absolute address
.Pp
> s 0x400 # seek to offset 0x400
.Pp
> s+20 # seek 20 bytes forward
.It b[+-size]
change block size
.Pp
> b 5 # set block size to 5 bytes
.Pp
> b +128 # increase block size in 128 bytes
.It w[hex|"str"]
write hexpair or string
.Pp
> w 001122 # write 0x00 0x11 0x22
.Pp
> w"Hello World" # write "Hello World" string without quotes
.It /[hex|"str"]
search hexpair or string
.Pp
> /894722 # search bytes 0x89 0x47 0x22
.Pp
> /"lib" # search string 'lib'
.It x[size]
hexdump
.Pp
> x 256 # dump 256 bytes in hexadecimal
.It X[size]
hexpair dump
.Pp
> X 0x100 # dump 256 bytes in hexpairs
.It p[fmt]
print formatted current block ('p' for help)
.Pp
ob/wW/dD/qQ byte (oct,hex), word, dword, qword (lil, big endian)
.Pp
i/I/f/F int32 (lil, big), float (lil, big)
.Pp
s/S short int16 (lil, big)
.Pp
z/Z zero-terminatted string (ascii, wide-ascii)
.Pp
./:/* skip 1 or 4 chars, repeat last format instead of cycle
.It r[-[num]]
truncate or -remove N bytes
.Pp
> r 1024 # resize file to 1024 bytes
.Pp
> r-10 # remove 10 bytes from current seek and shrink file
.It .[file]
interpret file
.Pp
> .script # run file 'script'
.It <[file]
load file in current seek
.Pp
> <curblock.bin # load blocksize bytes from file
.It >[file]
dump current block to file
.Pp
> >curblock.bin # dump current block to a file
.It !cmd
run shell command
.Pp
The following environment variables are defined when found in the command string:
.Pp
FILE is the filename of the current working file
.Pp
BLOCK points to the temporal filename with the current block dump
.Pp
OFFSET and XOFFSET are decimal and hexadecimal values of the current seek
.Pp
> !cp $BLOCK $FILE-$XOFFSET.curblock # save current block
.It ?expr
calculate numeric expression
.Pp
> ?1024
.Pp
0x400 1024 02000
.It q
quit
.El
.Sh SEE ALSO
.Pp
.Xr vired(1)
.Sh AUTHORS
.PP
pancake <@nopcode.org>
+134
View File
@@ -0,0 +1,134 @@
/* Copyleft 2009-2013 -- pancake /at/ nopcode /dot/ org */
#define ut64 unsigned long long
#define ut8 unsigned char
static int verbose = 1;
static char *script = 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 "ired.h"
#include "util.c"
#include "cmd.c"
static void red_slurpin() {
ut8 buf[BUFSZ];
for(;;) {
int len = read(0, buf, sizeof(buf));
if(len<1) break;
hexdump(buf, len, 16);
curseek += len;
}
}
static int red_interpret(char *file) {
char buf[BUFSZ];
FILE *fd = fopen(file, "r");
if(fd != NULL) {
for(;;) {
if(fgets(buf, sizeof(buf), fd) == NULL)
break;
red_cmd(buf);
}
fclose(fd);
} 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 '>': 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 '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 '?': return cmd_help(arg); break;
default: fprintf(stderr, "? %s\n", cmd);
}
return 1;
}
static int red_prompt() {
char *at, *at2, line[BUFSZ];
if(verbose) {
printf("[0x%08"LLF"x]> ", curseek);
fflush(stdout);
}
if(fgets(line, sizeof(line), stdin) == NULL)
return 0;
line[strlen(line)-1] = '\0';
if(*line != '!') {
at = strchr(line, '@');
oldseek = curseek;
obsize = bsize;
if(at) {
*at = 0;
at2 = strchr(++at, ':');
if(at2) {
*at2 = 0; at2++;
if(*at2) bsize = (int)str2ut64(at2);
}
if(*at) curseek = str2ut64(at);
}
}
at = line;
SKIPSPACES(at);
return red_cmd(at);
}
static int red_open(char *file) {
int ret = io_open(file);
if(ret != -1) {
oldseek = 0;
setenv("FILE", file, 1);
if(script)
red_interpret(script);
while((ret=red_prompt())>0) {
curseek = oldseek;
bsize = obsize;
}
io_close();
} 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] [..]");
return 0;
}
int main(int argc, char **argv) {
int i, ret = 1;
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 'n': verbose = 0; break;
case 'v': puts("ired "VERSION); ret = 0; break;
case 'h': ret = red_help(); break;
case 0x0: red_slurpin(); ret = 0; break;
} else {
if (!argv[i]) break;
ret = red_open(argv[i]);
}
} else ret = red_help();
return ret;
}
+22
View File
@@ -0,0 +1,22 @@
#define VERSION "0.5"
#include <unistd.h>
#include <sys/types.h>
#include "io.c"
#include <stdio.h>
#include <ctype.h>
#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];
snprintf(str, sizeof(str), "echo %s > /env/%s", var, val);
return system(str);
}
#define LLF "L"
#else
#define LLF "ll"
#endif
+10
View File
@@ -0,0 +1,10 @@
</$objtype/mkfile
CC=pcc
ALL=ired
9ired:
$CC -Dplan9 -D_POSIX_SOURCE -D_BSD_EXTENSION $CFLAGS -o 9ired ired.c
clean:
rm -f ired.$O 9ired
-121
View File
@@ -1,121 +0,0 @@
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
#define ut64 unsigned long long
#define ut8 unsigned char
static int verbose = 1;
static char *script = 0;
static ut64 oseek, seek = 0LL;
static unsigned int obsize, bsize = 256;
static int red_cmd(char *cmd); // XXX : recursive depenency
#include "red.h"
int red_slurpin() {
int len;
unsigned char buf[4096];
for(;;) {
len = read(0, buf, 4096);
if (len<1) break;
hexdump(buf, len, 16);
seek += len;
}
return 0;
}
static char *red_interpret(char *file) {
char buf[1024];
FILE *fd = fopen(file, "r");
if (fd != NULL) {
file = NULL;
for(;;) {
fgets(buf, 1023, fd);
if (feof(fd)) break;
red_cmd(buf);
}
fclose(fd);
} else fprintf(stderr, "Cannot open script file '%s'\n", file);
return file;
}
static int red_cmd(char *cmd) {
switch(*cmd) {
case 'q': return 0;
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;
default: fprintf(stderr, "? %s\n", cmd);
}
return 1;
}
static int red_prompt() {
char *at, *at2, line[4096];
if (verbose) {
printf("[0x%08llx]> ", seek);
fflush(stdout);
}
fgets(line, 4095, stdin);
if (feof(stdin)) return 0;
line[strlen(line)-1] = 0;
if (line[0] != '!') {
at = strchr(line, '@');
oseek = seek;
obsize = bsize;
if (at) {
*at = 0; at++;
at2 = strchr(at, ':');
if (at2) {
*at2 = 0; at2++;
if (*at2) bsize = (int)str2ut64(at2);
}
if (*at) seek = str2ut64(at);
}
}
return red_cmd(skipspaces(line));
}
static void red_open(char *file) {
oseek = 0;
setenv("FILE", file, 1);
if (io_open(file) != -1) {
if (script)
script = red_interpret(script);
while(red_prompt()) {
seek = oseek;
bsize = obsize;
}
io_close();
} else fprintf(stderr, "Cannot open '%s'\n", file);
}
static int red_help() {
puts("red [-hnv] [-i script] [file] [..]");
return 0;
}
int main(int argc, char **argv) {
int i;
if (argc>1)
for(i=1;i<argc;i++) {
if (argv[i][0]=='-')
switch(argv[i][1]) {
case 'i': script = argv[++i]; break;
case 'n': verbose = 0; break;
case 'v': puts("red "VERSION" 2009"); return 0;
case 'h': return red_help();
case 0x0: return red_slurpin();
} else red_open(argv[i]);
} else return red_help();
return 0;
}
-11
View File
@@ -1,11 +0,0 @@
#define VERSION "0.1"
#include "io.c"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <ctype.h>
#include "util.c"
#include "cmd.c"
+5
View File
@@ -0,0 +1,5 @@
all:
sh test.sh
clean:
rm -f tmp tmp.ired
+5
View File
@@ -0,0 +1,5 @@
Hello world
soor
loop
is fucking awesome
and new as shit
+5
View File
@@ -0,0 +1,5 @@
Hello world
loop
soor
is fucking awesome
and new as shit
+4
View File
@@ -0,0 +1,4 @@
Hello world
sardina
is fucking awesome
and new as shit
+3
View File
@@ -0,0 +1,3 @@
Hello world
is fucking awesome
and new as shit
Executable
+53
View File
@@ -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
+55 -59
View File
@@ -1,102 +1,98 @@
/* Copyleft 2009 -- pancake /at/ nopcode /dot/ org */
/* ired - Copyleft 2009-2013 -- pancake */
static inline char *skipspaces(char *arg) {
while (*arg==' '||*arg=='\t') arg++;
return arg;
}
#include <ctype.h>
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%08llx ", seek+i);
printf("0x%08"LLF"x: ", curseek+i);
for(j=i;j<i+w;j++) {
if (j>=len) {
if(j>=len) {
printf(j%2?" ":" ");
continue;
}
printf("%02x", buf[j]);
if (j%2) printf(" ");
}
for(j=i;j<i+w;j++) {
if (j>=len) printf(" ");
else printf("%c", isprint(buf[j])?buf[j]:'.');
printf(j%2?"%02x ":"%02x", buf[j]);
}
printf(" ");
for(j=i;j<i+w;j++)
printf("%c", isprint(buf[j])?buf[j]:'.');
printf("\n");
}
}
static void print_fmt(const ut8 *buf, char *fmt, unsigned int len) {
unsigned int i, inc=0, lup=0, up, rep = 0;
unsigned int i, up, inc = 0, lup = 0, rep = 0;
char *ofmt = fmt;
do { /* TODO: needs cleanup */
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;
case 'z': for(i=0; inc<len && isascii(buf[0]);i++) { printf("%c", buf[0]); buf++; inc++; } if(i)printf("\n"); break;
case 'Z': for(i=0; inc<len && isascii(buf[0]);i++) { printf("%c", buf[0]); buf+=2; inc+=2; } if(i)printf("\n"); break;
case 'z': for(i=0; inc<len && isascii(buf[0]);i++) { printf(i?"%c\n":"%c", buf[0]); buf++; } inc++; break;
case 'Z': for(i=0; inc<len && isascii(buf[0]);i++) { printf(i?"%c\n":"%c", buf[0]); buf+=2; } inc+=2; break;
case '*': rep = lup; break;
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);
} 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%llx", &ret);
else sscanf(str, "0x%llo", &ret);
} else sscanf(str, "%lld", &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;
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;
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 int hexstr2raw(char *arg) {
ut8 *ptr, c = 0, d = 0;
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;
}
@@ -104,14 +100,14 @@ static int hexstr2raw(char *arg) {
return len;
}
static void *getcurblk(char *arg, unsigned int *len) {
void *buf;
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 ((buf = malloc(*len)) != NULL) {
if (io_seek(seek, 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);
+5 -3
View File
@@ -1,9 +1,11 @@
#!/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 | red -n $@
$0 | ired -n $@
exit 0
fi
@@ -22,7 +24,7 @@ echo "b 256"
while : ; do
echo "!clear"
case $P in
'd') echo '!echo X | red -s $BLOCK | rasm2 -o $OFFSET -d -' ;;
'd') echo '!echo X | ired -n $BLOCK | rasm2 -o $OFFSET -d -' ;;
*) echo x ;;
esac
A=`dd if=/dev/tty count=1 bs=1 2>/dev/null`
+41
View File
@@ -0,0 +1,41 @@
.Dd Oct 7, 2009
.Dt VIRED 1
.Os
.Th VIRED 1
.Sh NAME
vired \- visual interactive raw editor
.Sh SYNOPSIS
.Nm vired
.Ar file
.Sh DESCRIPTION
Visual mode for ired(1)
.Pp
.Sh KEYS
.Bl -tag -width Fl
.It hjkl
seek left(-1), down(+16), up(-16), right(+1)
.It +-*/
change block size (+1,-1,+16,-16)
.It :[cmd]
input ired command
.It b
prompt to change block size
.It s
prompt seek address
.It r
prompt for resize, remove command
.It p
change print mode
.It :
enter raw ired command
.It ?
show help
.It q
quit program
.Pp
.Sh SEE ALSO
.Pp
.Xr ired(1)
.Sh AUTHORS
.PP
pancake <@nopcode.org>