* Theorically fix the r_magic dirty sanchez bug

* Fix RIO seek undo with io.va
* Warn if file size != region size in dml
This commit is contained in:
pancake 2011-11-16 10:06:34 +01:00
parent c5ca77e2dd
commit 31a11600c5
9 changed files with 72 additions and 297 deletions

View File

@ -4980,7 +4980,7 @@ R_API int r_core_cmd_command(RCore *core, const char *command) {
return 0;
}
static int cmd_debug_dm(RCore *core, const char *input) {
static int cmd_debug_map(RCore *core, const char *input) {
char file[128];
RListIter *iter;
RDebugMap *map;
@ -4994,10 +4994,10 @@ static int cmd_debug_dm(RCore *core, const char *input) {
" dm* Same as above but in radare commands\n"
" dm 4096 Allocate 4096 bytes in child process\n"
" dm-0x8048 Deallocate memory map of address 0x8048\n"
" dmi [addr|libname] [symname] List symbols of target lib\n"
" dmi* [addr|libname] [symname] Same as above but in radare commands\n"
" dmd [file] Dump current debug map region to a file (from-to.dmp) (see Sd)\n"
" dml file Load contents of file into the current map region (see Sl)\n"
" dmi [addr|libname] [symname] List symbols of target lib\n"
" dmi* [addr|libname] [symname] Same as above but in radare commands\n"
//" dm rw- esp 9K set 9KB of the stack as read+write (no exec)\n"
"TODO: map files in process memory. (dmf file @ [addr])\n");
break;
@ -5044,7 +5044,11 @@ static int cmd_debug_dm(RCore *core, const char *input) {
return R_FALSE;
}
r_io_write_at (core->io, map->addr, (const ut8*)buf, sz);
eprintf ("Loaded %d bytes into the map region at 0x%08"PFMT64x"\n", sz, map->addr);
if (sz != map->size)
eprintf ("File size differs from region size (%d vs %d)\n",
sz, map->size);
eprintf ("Loaded %d bytes into the map region at 0x%08"PFMT64x"\n",
sz, map->addr);
free (buf);
return R_TRUE;
}
@ -5491,7 +5495,7 @@ static int cmd_debug(void *data, const char *input) {
r_cons_break_end();
break;
case 'm':
cmd_debug_dm (core, input+1);
cmd_debug_map (core, input+1);
break;
case 'r':
cmd_reg (core, input+1);

View File

@ -9,7 +9,7 @@
* - Per-fd history log
#endif
R_API int r_io_undo_init(struct r_io_t *io) {
R_API int r_io_undo_init(RIO *io) {
io->undo.w_init = 0;
io->undo.w_enable = 0;
io->undo.idx = 0;
@ -20,17 +20,17 @@ R_API int r_io_undo_init(struct r_io_t *io) {
return R_TRUE;
}
R_API void r_io_undo_enable(struct r_io_t *io, int s, int w) {
R_API void r_io_undo_enable(RIO *io, int s, int w) {
io->undo.s_enable = s;
io->undo.w_enable = w;
}
R_API ut64 r_io_sundo_last(struct r_io_t *io) {
R_API ut64 r_io_sundo_last(RIO *io) {
return (io->undo.idx>0)?
io->undo.seek[io->undo.idx-2] : io->off;
}
R_API int r_io_sundo(struct r_io_t *io) {
R_API int r_io_sundo(RIO *io) {
if (io->undo.idx == io->undo.limit)
r_io_sundo_push (io);
io->undo.idx--;
@ -40,28 +40,24 @@ R_API int r_io_sundo(struct r_io_t *io) {
return R_TRUE;
}
R_API int r_io_sundo_redo(struct r_io_t *io) {
R_API int r_io_sundo_redo(RIO *io) {
if (io->undo.idx<io->undo.limit) {
io->undo.idx += 1;
if (io->undo.idx>=R_IO_UNDOS) {
io->undo.idx -= 1;
return R_FALSE;
} else io->off = io->undo.seek[io->undo.idx-1];
r_io_sundo(io);
return R_TRUE;
if (io->undo.idx<R_IO_UNDOS) {
io->off = io->undo.seek[io->undo.idx-1];
return R_TRUE;
r_io_sundo (io);
}
io->undo.idx -= 1;
}
return R_FALSE;
}
R_API void r_io_sundo_push(RIO *io) {
ut64 off = (io->va && !r_list_empty (io->sections))?
r_io_section_offset_to_vaddr (io, io->off) : io->off;
ut64 off = io->off;
if (!io->undo.s_enable)
return;
#if 0
if (io->undo.seek[io->undo.idx-1] == off)
return;
#endif
//if (io->undo.seek[io->undo.idx-1] == off) return;
io->undo.seek[io->undo.idx] = off;
io->undo.idx++;
if (io->undo.idx==R_IO_UNDOS-1) {
@ -72,15 +68,15 @@ R_API void r_io_sundo_push(RIO *io) {
io->undo.limit = io->undo.idx;
}
R_API void r_io_sundo_reset(struct r_io_t *io) {
R_API void r_io_sundo_reset(RIO *io) {
io->undo.idx = 0;
}
R_API void r_io_sundo_list(struct r_io_t *io) {
R_API void r_io_sundo_list(RIO *io) {
int i;
if (io->undo.idx>0) {
io->printf ("f undo_idx @ %d\n", io->undo.idx);
for (i=io->undo.idx;i!=0;i--)
for (i=io->undo.idx; i!=0; i--)
io->printf ("f undo_%d @ 0x%"PFMT64x"\n",
io->undo.idx-i, io->undo.seek[i-1]);
} else eprintf("-no seeks done-\n");
@ -88,32 +84,32 @@ R_API void r_io_sundo_list(struct r_io_t *io) {
/* undo writez */
R_API void r_io_wundo_new(struct r_io_t *io, ut64 off, const ut8 *data, int len) {
R_API void r_io_wundo_new(RIO *io, ut64 off, const ut8 *data, int len) {
struct r_io_undo_w_t *uw;
if (!io->undo.w_enable)
return;
/* undo write changes */
uw = R_NEW(struct r_io_undo_w_t);
uw = R_NEW (RIOUndoWrite);
if (!uw) return;
uw->set = R_TRUE;
uw->off = off;
uw->len = len;
uw->n = (ut8*) malloc(len);
uw->n = (ut8*) malloc (len);
memcpy(uw->n, data, len);
uw->o = (ut8*) malloc(len);
uw->o = (ut8*) malloc (len);
r_io_read_at(io, off, uw->o, len);
r_list_append (io->undo.w_list, uw);
}
R_API void r_io_wundo_clear(struct r_io_t *io) {
R_API void r_io_wundo_clear(RIO *io) {
// XXX memory leak
io->undo.w_list = r_list_new ();
}
// rename to r_io_undo_length ?
R_API int r_io_wundo_size(struct r_io_t *io) {
R_API int r_io_wundo_size(RIO *io) {
RListIter *iter;
struct r_io_undo_w_t *uw;
RIOUndoWrite *uw;
int i = 0;
if (io->undo.w_init)
@ -123,43 +119,43 @@ R_API int r_io_wundo_size(struct r_io_t *io) {
}
// TODO: Deprecate or so? iterators must be language-wide, but helpers are useful
R_API void r_io_wundo_list(struct r_io_t *io) {
R_API void r_io_wundo_list(RIO *io) {
#define BW 8 /* byte wrap */
RListIter *iter;
struct r_io_undo_w_t *u;
RIOUndoWrite *u;
int i = 0, j, len;
if (io->undo.w_init)
r_list_foreach (io->undo.w_list, iter, u) {
r_list_foreach (io->undo.w_list, iter, u) {
io->printf ("%02d %c %d %08"PFMT64x": ", i, u->set?'+':'-', u->len, u->off);
len = (u->len>BW)?BW:u->len;
for(j=0;j<len;j++) io->printf ("%02x ", u->o[j]);
for (j=0;j<len;j++) io->printf ("%02x ", u->o[j]);
if (len == BW) io->printf (".. ");
io->printf ("=> ");
for(j=0;j<len;j++) io->printf ("%02x ", u->n[j]);
for (j=0;j<len;j++) io->printf ("%02x ", u->n[j]);
if (len == BW) io->printf (".. ");
io->printf ("\n");
i++;
}
}
R_API int r_io_wundo_apply(struct r_io_t *io, struct r_io_undo_w_t *u, int set) {
R_API int r_io_wundo_apply(RIO *io, struct r_io_undo_w_t *u, int set) {
int orig = io->undo.w_enable;
io->undo.w_enable = 0;
if (set) {
r_io_write_at(io, u->off, u->n, u->len);
r_io_write_at (io, u->off, u->n, u->len);
u->set = R_TRUE;
} else {
r_io_write_at(io, u->off, u->o, u->len);
r_io_write_at (io, u->off, u->o, u->len);
u->set = R_FALSE;
}
io->undo.w_enable = orig;
return 0;
}
R_API void r_io_wundo_apply_all(struct r_io_t *io, int set) {
R_API void r_io_wundo_apply_all(RIO *io, int set) {
RListIter *iter;
struct r_io_undo_w_t *u;
RIOUndoWrite *u;
r_list_foreach_prev (io->undo.w_list, iter, u) {
r_io_wundo_apply (io, u, set); //UNDO_WRITE_UNSET);
@ -169,21 +165,19 @@ R_API void r_io_wundo_apply_all(struct r_io_t *io, int set) {
/* sets or unsets the writes done */
/* if ( set == 0 ) unset(n) */
R_API int r_io_wundo_set(struct r_io_t *io, int n, int set) {
R_API int r_io_wundo_set(RIO *io, int n, int set) {
RListIter *iter;
struct r_io_undo_w_t *u = NULL;
RIOUndoWrite *u = NULL;
int i = 0;
if (io->undo.w_init) {
r_list_foreach_prev (io->undo.w_list, iter, u) {
if (i++ == n) {
r_list_foreach_prev (io->undo.w_list, iter, u)
if (i++ == n)
break;
}
}
if (u) {
r_io_wundo_apply(io, u, set);
if (u) { // wtf?
r_io_wundo_apply (io, u, set);
return R_TRUE;
} else eprintf ("invalid undo-write index\n");
}
eprintf ("invalid undo-write index\n");
} else eprintf ("no writes done\n");
return R_FALSE;
}

View File

@ -402,7 +402,7 @@ static size_t apprentice_r_magic_strength(const struct r_magic *m) {
break;
default:
(void)fprintf(stderr, "Bad relation %c\n", m->reln);
eprintf ("Bad relation %c\n", m->reln);
abort();
}
@ -535,8 +535,8 @@ static int apprentice_load(RMagic *ms, struct r_magic **magicp, ut32 *nmagicp, c
ms->flags |= R_MAGIC_CHECK; /* Enable checks for parsed files */
maxmagic = MAXMAGIS;
if ((marray = calloc(maxmagic, sizeof(*marray))) == NULL) {
file_oomem(ms, maxmagic * sizeof(*marray));
if ((marray = calloc (maxmagic, sizeof(*marray))) == NULL) {
file_oomem (ms, maxmagic * sizeof(*marray));
return -1;
}
marraycount = 0;
@ -546,16 +546,13 @@ static int apprentice_load(RMagic *ms, struct r_magic **magicp, ut32 *nmagicp, c
eprintf ("%s\n", usg_hdr);
/* load directory or file */
if (stat (fn, &st) == 0 && S_ISDIR(st.st_mode)) {
dir = opendir(fn);
if (stat (fn, &st) == 0 && S_ISDIR (st.st_mode)) {
dir = opendir (fn);
if (dir) {
while ((d = readdir(dir))) {
snprintf(subfn, sizeof(subfn), "%s/%s",
fn, d->d_name);
if (stat(subfn, &st) == 0 && S_ISREG(st.st_mode)) {
load_1(ms, action, subfn, &errs,
&marray, &marraycount);
}
while ((d = readdir (dir))) {
snprintf (subfn, sizeof(subfn), "%s/%s", fn, d->d_name);
if (stat (subfn, &st) == 0 && S_ISREG (st.st_mode))
load_1 (ms, action, subfn, &errs, &marray, &marraycount);
}
closedir (dir);
} else errs++;

View File

@ -1,224 +0,0 @@
/* $OpenBSD: file.c,v 1.23 2011/04/15 16:05:34 stsp Exp $ */
/*
* Copyright (c) Ian F. Darwin 1986-1995.
* Software written by Ian F. Darwin and others;
* maintained 1995-present by Christos Zoulas and others.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice immediately at the beginning of the file, without modification,
* this list of conditions, and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
/*
* file - find type of a file or files - main program.
*/
#include <r_userconf.h>
#if !USE_LIB_MAGIC
#include <sys/types.h>
#include <sys/param.h> /* for MAXPATHLEN */
#include <sys/stat.h>
#include <r_magic.h>
#include "file.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h> /* for read() */
#endif
#ifdef HAVE_WCHAR_H
#include <wchar.h>
#endif
#include <getopt.h>
// TODO: drop support for getopt-long
#ifndef HAVE_GETOPT_LONG
int getopt_long(int argc, char * const *argv, const char *optstring, const struct option *longopts, int *longindex);
#endif
#include <netinet/in.h> /* for byte swapping */
#include "patchlevel.h"
#ifdef S_IFLNK
#define SYMLINKFLAG "Lh"
#else
#define SYMLINKFLAG ""
#endif
# define USAGE "Usage: %s [-bcik" SYMLINKFLAG "nNprsvz0] [-e test] [-f namefile] [-F separator] [-m magicfiles] file...\n" \
" %s -C -m magicfiles\n"
#ifndef MAXPATHLEN
#define MAXPATHLEN 512
#endif
static int /* Global command-line options */
bflag = 0, /* brief output format */
nopad = 0, /* Don't pad output */
nobuffer = 0, /* Do not buffer stdout */
nulsep = 0; /* Append '\0' to the separator */
static const char *magicfile = 0; /* where the magic is */
static const char *default_magicfile = MAGIC;
static const char *separator = ":"; /* Default field separator */
extern char *__progname; /* used throughout */
static struct r_magic_set *magic;
static void unwrap(char *);
static void usage(void);
static void help(void);
static void process(const char *, int);
static void load(const char *, int);
static void load(const char *m, int flags) {
if (magic || m == NULL)
return;
magic = r_magic_new (flags);
if (magic == NULL) {
eprintf ("%s: %s\n", __progname, strerror (errno));
exit (1);
}
if (r_magic_load(magic, magicfile) == -1) {
eprintf ("%s: %s\n", __progname, r_magic_error (magic));
exit (1);
}
}
/*
* unwrap -- read a file of filenames, do each one.
*/
static void unwrap(char *fn) {
char buf[MAXPATHLEN];
FILE *f;
int wid = 0, cwid;
if (strcmp("-", fn) == 0) {
f = stdin;
wid = 1;
} else {
if ((f = fopen(fn, "r")) == NULL) {
(void)fprintf(stderr, "%s: Cannot open `%s' (%s).\n",
__progname, fn, strerror (errno));
exit(1);
}
while (fgets(buf, sizeof(buf), f) != NULL) {
buf[strcspn(buf, "\n")] = '\0';
cwid = file_mbswidth(buf);
if (cwid > wid)
wid = cwid;
}
rewind(f);
}
while (fgets (buf, sizeof (buf), f) != NULL) {
buf[strcspn (buf, "\n")] = '\0';
process (buf, wid);
if (nobuffer)
fflush (stdout);
}
fclose (f);
}
/*
* Called for each input file on the command line (or in a list of files)
*/
static void process(const char *inname, int wid) {
const char *type;
int std_in = strcmp (inname, "-") == 0;
if (wid > 0 && !bflag) {
(void)printf ("%s", std_in ? "/dev/stdin" : inname);
if (nulsep)
(void)putc('\0', stdout);
else
(void)printf("%s", separator);
(void)printf("%*s ",
(int) (nopad ? 0 : (wid - file_mbswidth(inname))), "");
}
type = r_magic_file(magic, std_in ? NULL : inname);
if (type == NULL)
(void)printf ("ERROR: %s\n", r_magic_error (magic));
else (void)printf ("%s\n", type);
}
size_t file_mbswidth(const char *s) {
#if defined(HAVE_WCHAR_H) && defined(HAVE_MBRTOWC) && defined(HAVE_WCWIDTH)
size_t bytesconsumed, old_n, n, width = 0;
mbstate_t state;
wchar_t nextchar;
(void)memset(&state, 0, sizeof(mbstate_t));
old_n = n = strlen(s);
int w;
while (n > 0) {
bytesconsumed = mbrtowc(&nextchar, s, n, &state);
if (bytesconsumed == (size_t)(-1) ||
bytesconsumed == (size_t)(-2)) {
/* Something went wrong, return something reasonable */
return old_n;
}
if (s[0] == '\n') {
/*
* do what strlen() would do, so that caller
* is always right
*/
width++;
} else {
w = wcwidth(nextchar);
if (w > 0)
width += w;
}
s += bytesconsumed, n -= bytesconsumed;
}
return width;
#else
return strlen (s);
#endif
}
static void usage(void) {
eprintf (USAGE, __progname, __progname);
fputs ("Try `file --help' for more information.\n", stderr);
exit (1);
}
static void help(void) {
(void)fputs(
"Usage: file [OPTION...] [FILE...]\n"
"Determine type of FILEs.\n"
"\n", stderr);
#define OPT(shortname, longname, opt, doc) \
fprintf(stderr, " -%c, --" longname doc, shortname);
#define OPT_LONGONLY(longname, opt, doc) \
fprintf(stderr, " --" longname doc);
#include "file_opts.h"
#undef OPT
#undef OPT_LONGONLY
exit (0);
}
#endif

View File

@ -75,7 +75,9 @@ int file_vprintf(RMagic *ms, const char *fmt, va_list ap) {
if (ms->o.buf != NULL) {
int obuflen = strlen (ms->o.buf);
len = obuflen+buflen+1;
newstr = malloc (len);
newstr = malloc (len+1);
memset (newstr, 0, len+1); // XXX: unnecessary?
newstr[len] = 0;
memcpy (newstr, ms->o.buf, obuflen);
memcpy (newstr+obuflen, buf, buflen);
free (buf);

View File

@ -173,7 +173,7 @@ static const char * file_or_fd(RMagic *ms, const char *inname, int fd) {
switch (file_fsmagic (ms, inname, &sb)) {
case -1: goto done; /* error */
case 0: break; /* nothing found */
default: rv=0; goto done; /* matched it and printed type */
default: rv = 0; goto done; /* matched it and printed type */
}
if (inname == NULL) {

View File

@ -194,7 +194,7 @@ void file_magwarn(struct r_magic_set *ms, const char *f, ...) {
(void) fputc('\n', stderr);
}
const char * file_fmttime(ut32 v, int local) {
const char *file_fmttime(ut32 v, int local) {
char *pp;
time_t t = (time_t)v;
struct tm *tm;

View File

@ -225,7 +225,7 @@ static int match(RMagic *ms, struct r_magic *magic, ut32 nmagic, const ut8 *s, s
if (need_separator
&& ((m->flag & NOSPACE) == 0)
&& *R_MAGIC_DESC) {
if (file_printf(ms, " ") == -1)
if (file_printf (ms, " ") == -1)
return -1;
need_separator = 0;
}
@ -383,16 +383,16 @@ static st32 mprint(RMagic *ms, struct r_magic *m) {
case FILE_BESTRING16:
case FILE_LESTRING16:
if (m->reln == '=' || m->reln == '!') {
if (file_printf(ms, R_MAGIC_DESC, m->value.s) == -1)
if (file_printf (ms, R_MAGIC_DESC, m->value.s) == -1)
return -1;
t = ms->offset + m->vallen;
}
else {
if (*m->value.s == '\0')
p->s[strcspn(p->s, "\n")] = '\0';
if (file_printf(ms, R_MAGIC_DESC, p->s) == -1)
p->s[strcspn (p->s, "\n")] = '\0';
if (file_printf (ms, R_MAGIC_DESC, p->s) == -1)
return -1;
t = ms->offset + strlen(p->s);
t = ms->offset + strlen (p->s);
if (m->type == FILE_PSTRING)
t++;
}

View File

@ -1,7 +1,9 @@
/* radare - LGPL - Copyright 2007-2010 pancake<nopcode.org> */
/* radare - LGPL - Copyright 2007-2011 pancake<nopcode.org> */
#include <r_util.h>
// XXX: This api is kinda ugly.. we need to redefine it
static const char *logfile = "radare.log";
R_API void r_log_file(const char *str) {