* Added dummy xrefs

* Added cmd_meta in r_core->cmd
* Cleanup data type range before adding new one in r_meta
  - mix idea for meta+ranges (commented)
* Search -> initialize renamed to begin()
* Added memcmp_mask for r_util
* Fix crash issue in perl module

--HG--
rename : libr/search/xrefs.c => libr/search/old_xrefs.c
This commit is contained in:
pancake 2009-02-16 11:24:45 +01:00
parent 1f02a3f1be
commit ac10ad7df1
17 changed files with 608 additions and 498 deletions

9
README
View File

@ -1,6 +1,7 @@
____ ___ ____ ___ ____ ___ ______ ____
| _ \/ \' \/ \ _ \/ _ \ \__ | / \
| < V . T . V < _/ .--'_/ | () |
|_|\__|_|__|___/|_|_|_|\__\___/ |_____(_)____/
____ ___ ____ ___ ____ ___ ______ ____
| _ \/ \' \/ \ _ \/ _ \ \__ | / \
| < V . T . V < _/ .--'_/ | () |
|_|\__|_|__|___/|_|_|_|\__\___/ |_____(_)____/

View File

@ -727,6 +727,22 @@ static int cmd_system(void *data, const char *input)
#endif
}
static int cmd_meta(void *data, const char *input)
{
struct r_core_t *core = (struct r_core_t *)data;
switch(input[0]) {
case '\0':
/* meta help */
break;
case 'C': /* add comment */
// r_meta_add(&core->meta);
break;
case 'F': /* add function */
break;
}
return R_TRUE;
}
static int cmd_io_system(void *data, const char *input)
{
struct r_core_t *core = (struct r_core_t *)data;
@ -1018,26 +1034,27 @@ int r_core_cmd_init(struct r_core_t *core)
{
r_cmd_init(&core->cmd);
r_cmd_set_data(&core->cmd, core);
r_cmd_add(&core->cmd, "x", "alias for px", &cmd_hexdump);
r_cmd_add(&core->cmd, "anal", "analysis", &cmd_anal);
r_cmd_add(&core->cmd, "flag", "get/set flags", &cmd_flag);
r_cmd_add(&core->cmd, "debug", "debugger operations", &cmd_debug);
r_cmd_add(&core->cmd, "info", "get file info", &cmd_info);
r_cmd_add(&core->cmd, "seek", "seek to an offset", &cmd_seek);
r_cmd_add(&core->cmd, "bsize", "change block size", &cmd_bsize);
r_cmd_add(&core->cmd, "eval", "evaluate configuration variable", &cmd_eval);
r_cmd_add(&core->cmd, "print", "print current block", &cmd_print);
r_cmd_add(&core->cmd, "write", "write bytes", &cmd_write);
r_cmd_add(&core->cmd, "Visual","enter visual mode", &cmd_visual);
r_cmd_add(&core->cmd, "!", "run system command", &cmd_system);
r_cmd_add(&core->cmd, "|", "run io system command", &cmd_io_system);
r_cmd_add(&core->cmd, "#", "calculate hash", &cmd_hash);
r_cmd_add(&core->cmd, "?", "help message", &cmd_help);
r_cmd_add(&core->cmd, ".", "interpret", &cmd_interpret);
r_cmd_add(&core->cmd, "/", "search kw, pattern aes", &cmd_search);
r_cmd_add(&core->cmd, "(", "macro", &cmd_macro);
r_cmd_add(&core->cmd, "|", "io pipe", &cmd_iopipe);
r_cmd_add(&core->cmd, "quit", "exit program session", &cmd_quit);
r_cmd_add(&core->cmd, "x", "alias for px", &cmd_hexdump);
r_cmd_add(&core->cmd, "analysis", "analysis", &cmd_anal);
r_cmd_add(&core->cmd, "flag", "get/set flags", &cmd_flag);
r_cmd_add(&core->cmd, "debug", "debugger operations", &cmd_debug);
r_cmd_add(&core->cmd, "info", "get file info", &cmd_info);
r_cmd_add(&core->cmd, "seek", "seek to an offset", &cmd_seek);
r_cmd_add(&core->cmd, "bsize", "change block size", &cmd_bsize);
r_cmd_add(&core->cmd, "eval", "evaluate configuration variable", &cmd_eval);
r_cmd_add(&core->cmd, "print", "print current block", &cmd_print);
r_cmd_add(&core->cmd, "write", "write bytes", &cmd_write);
r_cmd_add(&core->cmd, "Code", "code metadata", &cmd_meta);
r_cmd_add(&core->cmd, "Visual", "enter visual mode", &cmd_visual);
r_cmd_add(&core->cmd, "!", "run system command", &cmd_system);
r_cmd_add(&core->cmd, "|", "run io system command", &cmd_io_system);
r_cmd_add(&core->cmd, "#", "calculate hash", &cmd_hash);
r_cmd_add(&core->cmd, "?", "help message", &cmd_help);
r_cmd_add(&core->cmd, ".", "interpret", &cmd_interpret);
r_cmd_add(&core->cmd, "/", "search kw, pattern aes", &cmd_search);
r_cmd_add(&core->cmd, "(", "macro", &cmd_macro);
r_cmd_add(&core->cmd, "|", "io pipe", &cmd_iopipe);
r_cmd_add(&core->cmd, "quit", "exit program session", &cmd_quit);
return 0;
}

View File

@ -89,6 +89,7 @@ int r_core_init(struct r_core_t *core)
r_lang_init(&core->lang);
r_lang_set_user_ptr(&core->lang, core);
r_anal_init(&core->anal);
r_meta_init(&core->meta);
r_anal_set_user_ptr(&core->anal, core);
r_cons_init();
core->search = r_search_new(R_SEARCH_KEYWORD);

View File

@ -1,6 +1,6 @@
OBJ=radare2.o
BIN=radare2
BINDEPS=r_core r_cons r_macro r_util r_flags r_lib r_io r_hash r_cmd r_config r_asm r_anal r_lang r_debug r_print r_line r_bin r_search
BINDEPS=r_core r_cons r_macro r_util r_flags r_lib r_io r_hash r_cmd r_config r_asm r_anal r_lang r_debug r_print r_line r_bin r_search r_meta
#LIBS=-lr_core -L..
### shared

View File

@ -7,6 +7,7 @@
#include "r_lang.h"
#include "r_anal.h"
#include "r_cmd.h"
#include "r_meta.h"
#include "r_cons.h"
#include "r_line.h"
#include "r_print.h"
@ -43,6 +44,7 @@ struct r_core_t {
struct r_lib_t lib;
struct r_cmd_t cmd;
struct r_anal_t anal;
struct r_meta_t meta;
struct r_lang_t lang;
struct r_debug_t dbg;
struct r_flag_t flags;

View File

@ -13,7 +13,7 @@ struct r_debug_handle_t {
const char *name;
int (*attach)(int pid);
int (*detach)(int pid);
int (*step)(int pid);
int (*step)(int pid); // if step() is NULL; reimplement it with traps
int (*cont)(int pid);
int (*contsc)(int pid, int sc);
struct list_head list;

View File

@ -80,7 +80,7 @@ int r_search_strings_update_char(const unsigned char *buf, int min, int max, int
int r_search_pattern(struct r_search_t *s, u32 size);
int r_search_strings(struct r_search_t *s, u32 min, u32 max);
int r_search_set_callback(struct r_search_t *s, int (*callback)(struct r_search_kw_t *, void *, u64), void *user);
int r_search_initialize(struct r_search_t *s);
int r_search_begin(struct r_search_t *s);
#endif

View File

@ -22,8 +22,9 @@
#define R_TRUE 1
/* memory */
void r_mem_copyloop (u8 *dest, u8 *orig, int dsize, int osize);
void r_mem_copyendian (u8 *dest, u8 *orig, int size, int endian);
void r_mem_copyloop (u8 *dest, const u8 *orig, int dsize, int osize);
void r_mem_copyendian (u8 *dest, const u8 *orig, int size, int endian);
int r_mem_cmp_mask(const u8 *dest, const u8 *orig, const u8 *mask, int len);
/* numbers */
struct r_num_t {

View File

@ -8,8 +8,13 @@
#include <EXTERN.h>
#include <XSUB.h>
#undef PL_madskills
#undef PL_xmlfp
#include <perl.h>
#undef U32_MAX
#undef U32_MIN
#include "r_core.h"
static struct r_core_t *core = NULL;

View File

@ -113,17 +113,57 @@ int r_meta_del(struct r_meta_t *m, int type, u64 from, u64 size, const char *str
return ret;
}
int r_meta_cleanup(struct r_meta_t *m, u64 from, u64 to)
{
struct list_head *pos, *n;
int ret = R_FALSE;
list_for_each_safe(pos, n, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
switch(d->type) {
case R_META_CODE:
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
#if 0
|__| |__| |___| |_|
|__| |_| |_| |___|
====== ===== ===== =====
#endif
if (to>d->from && to<d->to) {
d->from = to;
ret= R_TRUE;
} else
if (from>d->from && from<d->to &&to>d->to) {
d->to = from;
ret= R_TRUE;
} else
if (from>d->from&&from<d->to&&to<d->to) {
// XXX split!
d->to = from;
ret= R_TRUE;
} else
if (from>d->from&&to<d->to) {
list_del(&(d->list));
ret= R_TRUE;
}
break;
}
}
return ret;
}
int r_meta_add(struct r_meta_t *m, int type, u64 from, u64 size, const char *str)
{
struct r_meta_item_t *mi;
switch(type) {
case R_META_CODE:
r_meta_del(m, R_META_CODE, from, size, str);
break;
case R_META_DATA:
case R_META_STRING:
case R_META_STRUCT:
/* we should remove overlapped types and so on.. */
r_meta_cleanup(m, from, from + size);
case R_META_FUNCTION:
case R_META_COMMENT:
case R_META_FOLDER:
@ -227,6 +267,23 @@ const char *r_meta_type_to_string(int type)
return "(...)";
}
#if 0
#include <r_range.h>
struct r_range_t *r_meta_ranges(struct r_meta_t *m)
{
struct r_range_t *r;
struct list_head *pos;
r = r_range_new();
list_for_each(pos, &m->data) {
struct r_meta_item_t *d = (struct r_meta_item_t *)
list_entry(pos, struct r_meta_item_t, list);
r_range_add(r, d->from, d->to, 1); //d->type);
}
return r;
}
#endif
int r_meta_list(struct r_meta_t *m, int type)
{
int count = 0;

View File

@ -85,7 +85,6 @@ u64 r_range_size(struct r_range_t *rgs)
r = list_entry(pos, struct r_range_item_t, list);
sum += r->to - r->from;
}
return sum;
}

View File

@ -1,5 +1,5 @@
NAME=r_search
OBJ=search.o bytepat.o stripstr.o aes-find.o regexp.o
OBJ=search.o bytepat.o stripstr.o aes-find.o regexp.o xrefs.o
DEPS=r_util
CFLAGS+=-g
#OBJ+=binparse.o

461
libr/search/old_xrefs.c Normal file
View File

@ -0,0 +1,461 @@
/*
* Copyright (C) 2007, 2008
* pancake <youterm.com>
*
* 'xrefs' is part of the radare project.
*
* xrefs is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xrefs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xrefs; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/*
=====================================================================
xrefs - find relative inverse references to an offset inside a file.
author: pancake <pancake@youterm.com>
date: 2006-12-30
context: external radare utility
=====================================================================
usage example:
~:$ cat example.c
#include <stdio.h>
void func() {
printf("Hello ");
}
int main() {
func(); func(); func();
}
~:$ gcc example.c
~:$ ./a.out
Hello Hello Hello
~:$ objdump -d a.out | grep func
10000400 <func>:
1000044c: 4b ff ff b5 bl 10000400 <func>
10000450: 4b ff ff b1 bl 10000400 <func>
10000454: 4b ff ff ad bl 10000400 <func>
~:$ ./xrefs -a ppc a.out 0x400
match value ffffffb5 (ffffb5) at offset 0x44c
match value ffffffb1 (ffffb1) at offset 0x450
match value ffffffad (ffffad) at offset 0x454
*/
/**
========================================================================
XXX and TODO:
-------------
- 64 bit offsets support
- set opcode byte (bl == 0x4b, ...)
-- set and find the jump/call byte before the offset address
========================================================================
**/
/* setup 64 bit environment! */
#include "radare.h"
#if __FreeBSD__ || __linux__ || __NetBSD__ || __OpenBSD__
#define __UNIX__ 1
#else
#define __UNIX__ 0
#endif
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#if __UNIX__
#include <sys/mman.h>
#include <sys/ioctl.h>
#endif
u32 base = 0;
u32 delta = 0;
u32 range = 0;
u32 xylum = 0;
u32 gamme = 0;
u32 size = 4;
int sysendian = 0; // initialized in main
int endian = -1; // little endian by default
int verbose = 0;
int found = 0;
int quite = 0;
int arch = ARCH_NULL;
unsigned char *ma = NULL;
static int show_usage()
{
printf(
"Usage: xrefs [-options] [file] [offset]\n"
" -v Verbose mode\n"
" -V Show version\n"
" -q quite mode\n"
" -h Show this helpy message\n"
" -e Use big endian for offsets to search\n"
" -a [arch] Architecture profile (fmi: help) (autodetects ELF and PE hdrs)\n"
" -b [address] base address (0x8048000 f.ex)\n"
" -f [from] start scanning from this offset (default 0)\n"
" -t [to] limit address (default 99999999)\n"
" -r [range] Range in bytes of allowed relative offsets\n"
" -s [size] Size of offset (4 for intel, 3 for ppc, ...)\n"
" -d [offset] Sets a negative delta offset as padding (default 1)\n"
" -X [offset] Print out debugging information of a certain relative offset\n");
return 1;
}
static u32 file_size_fd(int fd)
{
u32 curr = lseek(fd, 0, SEEK_CUR);
u32 size = lseek(fd, 0, SEEK_END); // XXX: this is not size, is rest!
lseek(fd, curr, SEEK_SET);
return size;
}
/* TODO: move+share in offset.c ? */
static u32 get_value32(const char *arg)
{
int i;
u32 ret;
for(i=0;arg[i]==' ';i++);
for(;arg[i]=='\\';i++); i++;
if (arg[i] == 'x')
sscanf(arg, "0x%08llx", (u64 *)&ret);
else
sscanf(arg, "%lld", (u64 *)&ret);
return ret;
}
int get_system_endian()
{
int a = 1;
char *b = (char*)&a;
return (int)(b[0]);
}
int set_arch_settings()
{
switch(arch) {
case ARCH_PPC:
gamme = 1;
delta = 1;
size = 3;
break;
case ARCH_ARM:
gamme = -1;
delta = 1;
size = 3;
break;
case ARCH_X86:
gamme = 1;
delta = 0; //-5;
size = 4;
break;
case ARCH_NULL:
/* autodetect architecture */
// ELF
if (!memcmp(ma, "\x7f\x45\x4c\x46", 4)) {
short ar = (ma[0x12]<<8) + ma[0x13];
switch(ar) {
case 0x0300:
if (endian==-1)
endian = 1;
if (!quite)
printf("# -a x86\n");
arch = ARCH_X86;
endian = 1;
return 1;
case 0x0014:
if (endian==-1)
endian = 0;
if (!quite)
printf("# -a ppc\n");
arch = ARCH_PPC;
return 1;
case 0x2800:
if (endian==-1)
endian = 1;
if (!quite)
printf("# -a arm\n");
arch = ARCH_ARM;
return 1;
default:
printf("Unsupported architecture '%04x'.\n", ar);
exit(1);
}
} else
// MZ
if (!memcmp(ma, "\x4d\x5a",2)) {
unsigned short off = ma[0x3c];
if (!memcmp(ma+off, "PE\x00\x00",4)) {
unsigned short ar = (ma[off+4]<<8)+ma[off+5];
switch(ar) {
case 0x4c01: // x86
if (endian==-1)
endian = 1;
printf("# -a x86\n");
arch = ARCH_X86;
endian = 1;
return 1;
case 0xc001: // arm
if (endian==-1)
endian = 1;
printf("# -a arm\n");
arch = ARCH_ARM;
endian = 1;
return 1;
default:
fprintf(stderr, "Unknown architecture.\n");
break;
}
}
} else {
fprintf(stderr, "Plz. gimmie an architecture. (xrefs -a [arch])\n");
exit(1);
}
}
return 0;
}
int main(int argc, char **argv)
{
u64 i, c, src;
u64 offset = 0;
u64 from = 1,
to = INT_MAX;
u64 sa;
if (argc==2)
if (!strcmp(argv[1],"-V")) {
printf("%s\n", VERSION);
return 0;
}
if (argc<3)
return show_usage();
/* parse arguments */
while ((c = getopt(argc, argv, "qa:d:hves:f:t:r:X:b:")) != -1) {
switch( c ) {
case 'q':
quite = 1;
break;
case 'a':
if (!strcmp(optarg, "intel"))
arch = ARCH_X86;
else
if (!strcmp(optarg, "x86"))
arch = ARCH_X86;
else
if (!strcmp(optarg, "arm"))
arch = ARCH_ARM;
else
if (!strcmp(optarg, "ppc")) {
arch = ARCH_PPC;
} else {
printf("arm ppc x86\n");
return 1;
}
break;
case 'b':
base = get_value32(optarg);
break;
case 'd':
delta = get_value32(optarg);
break;
case 'X':
xylum = get_value32(optarg);
break;
case 'e':
endian = 1;
break;
case 'r':
range = get_value32(optarg);
if (range<0) range = -range;
break;
case 'v':
verbose = 1;
break;
case 'f':
from = get_value32(optarg);
break;
case 't':
to = get_value32(optarg);
break;
case 's':
size = get_value32(optarg);
break;
case 'h':
return show_usage();
}
}
if (optind+2 != argc) {
fprintf(stderr, "Plz. gimmie a file and offset.\n");
return 1;
}
/* openning stuff */
src = open(argv[optind], O_RDONLY);
if (src == -1) {
fprintf(stderr, "Cannot open file source %s\n", argv[optind]);
return -1;
}
offset = get_value32(argv[optind+1]);
if (offset >= base)
offset -= base;
sa = file_size_fd(src) - size;
#if __UNIX__
ma = mmap(NULL, sa, PROT_READ, MAP_SHARED, src, 0);
if (sa < 0x50) {
fprintf(stderr, "Minimum length is 0x50 bytes.\n");
return 1;
}
#elif __WINDOWS__
fprintf(stderr, "Not yet implemented\n");
#else
fprintf(stderr, "No MMAP for this platform? report it!\n");
#endif
if (ma == NULL) {
perror("Error mmaping");
fprintf(stderr, "cannot open %s\n", argv[optind]);
return 1;
}
/* configure environment */
sysendian = get_system_endian();
while( set_arch_settings() );
if (endian == -1)
endian = 0;
/* loopize looking for xrefs */
for(i=from; i<sa && i<to; i++) {
u32 value = offset - i + delta;
u32 ovalue = value;
u32 tmpvalue = 0;
unsigned char *buf = (unsigned char *)&value;
if (range!=0) {
if (value<0 && -value>range)
continue;
else
if (value>0 && value>range)
continue;
}
if (verbose)
printf("0x%08llx try %02x %02x %02x %02x (0x%08llx) - %lld\n",
(u64)i, buf[0], buf[1], buf[2], buf[3], (u64) base+value, (u64) (base+value));
if (xylum && i == xylum) {
printf("# offset: 0x%08llx\n", (u64)i);
printf("# delta: %lld\n", (u64)delta);
printf("# size: %lld\n", (u64)size);
printf("# value: %lld\n", (u64)value);
printf("# bytes: %02x %02x %02x %02x (0x%08llx) - %lld\n",
buf[0], buf[1], buf[2], buf[3], (u64)value, (u64)value);
tmpvalue = ma[i+gamme];
printf("# found: %02x %02x %02x %02x\n",
ma[i+gamme+0], ma[i+gamme+1],
ma[i+gamme+2], ma[i+gamme+3]);
}
switch(arch) {
case ARCH_ARM:
value = (value-8)/4;
break;
case ARCH_X86:
value-=5;
break;
default:
break;
}
// force little endian //
if (sysendian) {
unsigned char tmp;
tmp = buf[0]; buf[0]= buf[3]; buf[3] = tmp;
tmp = buf[1]; buf[1]= buf[2]; buf[2] = tmp;
}
// target architecture endian //
if (endian) {
unsigned char tmp;
tmp = buf[0]; buf[0] = buf[3]; buf[3] = tmp;
tmp = buf[1]; buf[1] = buf[2]; buf[2] = tmp;
}
if (arch==ARCH_ARM) {
buf[3] = buf[2]; buf[2] = buf[1]; buf[1] = buf[0];
}
if (xylum && ovalue == xylum) {
printf("# buf: %02x %02x %02x %02x (+%lld)\n",
buf[0], buf[1], buf[2], buf[3], (u64)(4-size));
printf("# map: %02x %02x %02x \n",
ma[i+gamme], ma[i+1+gamme], ma[i+2+gamme]);
printf("# cmp: %02x %02x %02x\n", ma[i], ma[i+1], ma[i+2]);
}
if (xylum && i == xylum) {
printf("# a: %02x %02x %02x %02x\n",
ma[i+gamme+0], ma[i+gamme+1],
ma[i+gamme+2], ma[i+gamme+3]);
printf("# b: %02x %02x %02x %02x\n",
buf[0], buf[1], buf[2], buf[3]);
}
if (memcmp((unsigned char *)ma+i+gamme, (unsigned char *)buf+(4-size), size) == 0) {
if (quite)
printf("0x%08llx\n", (u64)i);
else
printf("match value 0x%08llx (%02x%02x%02x) at offset 0x%08llx\n",
(u64)ovalue,
buf[0+(4-size)], buf[1+(4-size)], buf[2+(4-size)],
(u64)((u32)i)+((gamme<0)?-1:0));
found++;
}
}
if (found == 0 && !quite)
puts("no matches found.");
return 0;
}

View File

@ -8,7 +8,7 @@ int r_search_init(struct r_search_t *s, int mode)
{
memset(s,'\0', sizeof(struct r_search_t));
if (!r_search_set_mode(s, mode))
return 0;
return R_FALSE;
s->mode = mode;
s->user = NULL;
s->callback = NULL;
@ -18,21 +18,21 @@ int r_search_init(struct r_search_t *s, int mode)
INIT_LIST_HEAD(&(s->kws));
INIT_LIST_HEAD(&(s->hits));
INIT_LIST_HEAD(&(s->hits));
return 1;
return R_TRUE;
}
int r_search_set_string_limits(struct r_search_t *s, u32 min, u32 max)
{
if (max < min)
return 0;
return R_FALSE;
s->string_min = min;
s->string_max = max;
return 1;
return R_TRUE;
}
int r_search_set_mode(struct r_search_t *s, int mode)
{
int ret = 0;
int ret = R_FALSE;
switch(mode) {
case R_SEARCH_KEYWORD:
case R_SEARCH_REGEXP:
@ -41,7 +41,7 @@ int r_search_set_mode(struct r_search_t *s, int mode)
case R_SEARCH_XREFS:
case R_SEARCH_AES:
s->mode = mode;
ret = 1;
ret = R_TRUE;
}
return ret;
}
@ -63,8 +63,7 @@ struct r_search_t *r_search_free(struct r_search_t *s)
}
/* control */
/* Rename to start(), begin() .. */
int r_search_initialize(struct r_search_t *s)
int r_search_begin(struct r_search_t *s)
{
struct list_head *pos;
@ -85,6 +84,7 @@ int r_search_initialize(struct r_search_t *s)
return 1;
}
// TODO: move into a plugin */
int r_search_mybinparse_update(struct r_search_t *s, u64 from, const u8 *buf, int len)
{
struct list_head *pos;
@ -139,7 +139,7 @@ int r_search_update(struct r_search_t *s, u64 *from, const u8 *buf, u32 len)
ret += r_search_mybinparse_update(s, *from, buf, len);
break;
case R_SEARCH_XREFS:
//r_search_xrefs_update(s, *from, buf, len);
r_search_xrefs_update(s, *from, buf, len);
break;
case R_SEARCH_REGEXP:
ret += r_search_regexp_update(s, *from, buf, len);

View File

@ -1,461 +1,18 @@
/*
* Copyright (C) 2007, 2008
* pancake <youterm.com>
*
* 'xrefs' is part of the radare project.
*
* xrefs is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* xrefs is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with xrefs; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
/* radare - LGPL - Copyright 2007-2009 pancake<nopcode.org> */
/*
=====================================================================
#include "r_search.h"
#include <regex.h>
xrefs - find relative inverse references to an offset inside a file.
author: pancake <pancake@youterm.com>
date: 2006-12-30
context: external radare utility
=====================================================================
usage example:
~:$ cat example.c
#include <stdio.h>
void func() {
printf("Hello ");
}
int main() {
func(); func(); func();
}
~:$ gcc example.c
~:$ ./a.out
Hello Hello Hello
~:$ objdump -d a.out | grep func
10000400 <func>:
1000044c: 4b ff ff b5 bl 10000400 <func>
10000450: 4b ff ff b1 bl 10000400 <func>
10000454: 4b ff ff ad bl 10000400 <func>
~:$ ./xrefs -a ppc a.out 0x400
match value ffffffb5 (ffffb5) at offset 0x44c
match value ffffffb1 (ffffb1) at offset 0x450
match value ffffffad (ffffad) at offset 0x454
*/
/**
========================================================================
XXX and TODO:
-------------
- 64 bit offsets support
- set opcode byte (bl == 0x4b, ...)
-- set and find the jump/call byte before the offset address
========================================================================
**/
/* setup 64 bit environment! */
#include "radare.h"
#if __FreeBSD__ || __linux__ || __NetBSD__ || __OpenBSD__
#define __UNIX__ 1
#else
#define __UNIX__ 0
#endif
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <signal.h>
#include <getopt.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#if __UNIX__
#include <sys/mman.h>
#include <sys/ioctl.h>
#endif
u32 base = 0;
u32 delta = 0;
u32 range = 0;
u32 xylum = 0;
u32 gamme = 0;
u32 size = 4;
int sysendian = 0; // initialized in main
int endian = -1; // little endian by default
int verbose = 0;
int found = 0;
int quite = 0;
int arch = ARCH_NULL;
unsigned char *ma = NULL;
static int show_usage()
{
printf(
"Usage: xrefs [-options] [file] [offset]\n"
" -v Verbose mode\n"
" -V Show version\n"
" -q quite mode\n"
" -h Show this helpy message\n"
" -e Use big endian for offsets to search\n"
" -a [arch] Architecture profile (fmi: help) (autodetects ELF and PE hdrs)\n"
" -b [address] base address (0x8048000 f.ex)\n"
" -f [from] start scanning from this offset (default 0)\n"
" -t [to] limit address (default 99999999)\n"
" -r [range] Range in bytes of allowed relative offsets\n"
" -s [size] Size of offset (4 for intel, 3 for ppc, ...)\n"
" -d [offset] Sets a negative delta offset as padding (default 1)\n"
" -X [offset] Print out debugging information of a certain relative offset\n");
return 1;
}
static u32 file_size_fd(int fd)
int r_search_xrefs_update(struct r_search_t *s, u64 from, const u8 *buf, int len)
{
u32 curr = lseek(fd, 0, SEEK_CUR);
u32 size = lseek(fd, 0, SEEK_END); // XXX: this is not size, is rest!
lseek(fd, curr, SEEK_SET);
return size;
}
/* TODO: move+share in offset.c ? */
static u32 get_value32(const char *arg)
{
int i;
u32 ret;
for(i=0;arg[i]==' ';i++);
for(;arg[i]=='\\';i++); i++;
if (arg[i] == 'x')
sscanf(arg, "0x%08llx", (u64 *)&ret);
else
sscanf(arg, "%lld", (u64 *)&ret);
return ret;
}
int get_system_endian()
{
int a = 1;
char *b = (char*)&a;
return (int)(b[0]);
}
int set_arch_settings()
{
switch(arch) {
case ARCH_PPC:
gamme = 1;
delta = 1;
size = 3;
break;
case ARCH_ARM:
gamme = -1;
delta = 1;
size = 3;
break;
case ARCH_X86:
gamme = 1;
delta = 0; //-5;
size = 4;
break;
case ARCH_NULL:
/* autodetect architecture */
// ELF
if (!memcmp(ma, "\x7f\x45\x4c\x46", 4)) {
short ar = (ma[0x12]<<8) + ma[0x13];
switch(ar) {
case 0x0300:
if (endian==-1)
endian = 1;
if (!quite)
printf("# -a x86\n");
arch = ARCH_X86;
endian = 1;
return 1;
case 0x0014:
if (endian==-1)
endian = 0;
if (!quite)
printf("# -a ppc\n");
arch = ARCH_PPC;
return 1;
case 0x2800:
if (endian==-1)
endian = 1;
if (!quite)
printf("# -a arm\n");
arch = ARCH_ARM;
return 1;
default:
printf("Unsupported architecture '%04x'.\n", ar);
exit(1);
}
} else
// MZ
if (!memcmp(ma, "\x4d\x5a",2)) {
unsigned short off = ma[0x3c];
if (!memcmp(ma+off, "PE\x00\x00",4)) {
unsigned short ar = (ma[off+4]<<8)+ma[off+5];
switch(ar) {
case 0x4c01: // x86
if (endian==-1)
endian = 1;
printf("# -a x86\n");
arch = ARCH_X86;
endian = 1;
return 1;
case 0xc001: // arm
if (endian==-1)
endian = 1;
printf("# -a arm\n");
arch = ARCH_ARM;
endian = 1;
return 1;
default:
fprintf(stderr, "Unknown architecture.\n");
break;
}
}
} else {
fprintf(stderr, "Plz. gimmie an architecture. (xrefs -a [arch])\n");
exit(1);
}
}
return 0;
}
int main(int argc, char **argv)
{
u64 i, c, src;
u64 offset = 0;
u64 from = 1,
to = INT_MAX;
u64 sa;
if (argc==2)
if (!strcmp(argv[1],"-V")) {
printf("%s\n", VERSION);
return 0;
}
if (argc<3)
return show_usage();
/* parse arguments */
while ((c = getopt(argc, argv, "qa:d:hves:f:t:r:X:b:")) != -1) {
switch( c ) {
case 'q':
quite = 1;
break;
case 'a':
if (!strcmp(optarg, "intel"))
arch = ARCH_X86;
else
if (!strcmp(optarg, "x86"))
arch = ARCH_X86;
else
if (!strcmp(optarg, "arm"))
arch = ARCH_ARM;
else
if (!strcmp(optarg, "ppc")) {
arch = ARCH_PPC;
} else {
printf("arm ppc x86\n");
return 1;
}
break;
case 'b':
base = get_value32(optarg);
break;
case 'd':
delta = get_value32(optarg);
break;
case 'X':
xylum = get_value32(optarg);
break;
case 'e':
endian = 1;
break;
case 'r':
range = get_value32(optarg);
if (range<0) range = -range;
break;
case 'v':
verbose = 1;
break;
case 'f':
from = get_value32(optarg);
break;
case 't':
to = get_value32(optarg);
break;
case 's':
size = get_value32(optarg);
break;
case 'h':
return show_usage();
}
}
if (optind+2 != argc) {
fprintf(stderr, "Plz. gimmie a file and offset.\n");
return 1;
}
/* openning stuff */
src = open(argv[optind], O_RDONLY);
if (src == -1) {
fprintf(stderr, "Cannot open file source %s\n", argv[optind]);
return -1;
}
offset = get_value32(argv[optind+1]);
if (offset >= base)
offset -= base;
sa = file_size_fd(src) - size;
#if __UNIX__
ma = mmap(NULL, sa, PROT_READ, MAP_SHARED, src, 0);
if (sa < 0x50) {
fprintf(stderr, "Minimum length is 0x50 bytes.\n");
return 1;
}
#elif __WINDOWS__
fprintf(stderr, "Not yet implemented\n");
#else
fprintf(stderr, "No MMAP for this platform? report it!\n");
#endif
if (ma == NULL) {
perror("Error mmaping");
fprintf(stderr, "cannot open %s\n", argv[optind]);
return 1;
}
/* configure environment */
sysendian = get_system_endian();
while( set_arch_settings() );
if (endian == -1)
endian = 0;
/* loopize looking for xrefs */
for(i=from; i<sa && i<to; i++) {
u32 value = offset - i + delta;
u32 ovalue = value;
u32 tmpvalue = 0;
unsigned char *buf = (unsigned char *)&value;
if (range!=0) {
if (value<0 && -value>range)
continue;
else
if (value>0 && value>range)
continue;
}
if (verbose)
printf("0x%08llx try %02x %02x %02x %02x (0x%08llx) - %lld\n",
(u64)i, buf[0], buf[1], buf[2], buf[3], (u64) base+value, (u64) (base+value));
if (xylum && i == xylum) {
printf("# offset: 0x%08llx\n", (u64)i);
printf("# delta: %lld\n", (u64)delta);
printf("# size: %lld\n", (u64)size);
printf("# value: %lld\n", (u64)value);
printf("# bytes: %02x %02x %02x %02x (0x%08llx) - %lld\n",
buf[0], buf[1], buf[2], buf[3], (u64)value, (u64)value);
tmpvalue = ma[i+gamme];
printf("# found: %02x %02x %02x %02x\n",
ma[i+gamme+0], ma[i+gamme+1],
ma[i+gamme+2], ma[i+gamme+3]);
}
switch(arch) {
case ARCH_ARM:
value = (value-8)/4;
break;
case ARCH_X86:
value-=5;
break;
default:
break;
}
// force little endian //
if (sysendian) {
unsigned char tmp;
tmp = buf[0]; buf[0]= buf[3]; buf[3] = tmp;
tmp = buf[1]; buf[1]= buf[2]; buf[2] = tmp;
}
// target architecture endian //
if (endian) {
unsigned char tmp;
tmp = buf[0]; buf[0] = buf[3]; buf[3] = tmp;
tmp = buf[1]; buf[1] = buf[2]; buf[2] = tmp;
}
if (arch==ARCH_ARM) {
buf[3] = buf[2]; buf[2] = buf[1]; buf[1] = buf[0];
}
if (xylum && ovalue == xylum) {
printf("# buf: %02x %02x %02x %02x (+%lld)\n",
buf[0], buf[1], buf[2], buf[3], (u64)(4-size));
printf("# map: %02x %02x %02x \n",
ma[i+gamme], ma[i+1+gamme], ma[i+2+gamme]);
printf("# cmp: %02x %02x %02x\n", ma[i], ma[i+1], ma[i+2]);
}
if (xylum && i == xylum) {
printf("# a: %02x %02x %02x %02x\n",
ma[i+gamme+0], ma[i+gamme+1],
ma[i+gamme+2], ma[i+gamme+3]);
printf("# b: %02x %02x %02x %02x\n",
buf[0], buf[1], buf[2], buf[3]);
}
if (memcmp((unsigned char *)ma+i+gamme, (unsigned char *)buf+(4-size), size) == 0) {
if (quite)
printf("0x%08llx\n", (u64)i);
else
printf("match value 0x%08llx (%02x%02x%02x) at offset 0x%08llx\n",
(u64)ovalue,
buf[0+(4-size)], buf[1+(4-size)], buf[2+(4-size)],
(u64)((u32)i)+((gamme<0)?-1:0));
found++;
}
}
if (found == 0 && !quite)
puts("no matches found.");
return 0;
u8 code[1024];
u8 mask[1024];
int count = 0;
//get_delta_for(
if (r_mem_cmp_mask(buf, code, mask)) {
}
return count;
}

View File

@ -3,7 +3,7 @@
#include <r_util.h>
#include <stdlib.h>
void r_mem_copyloop (u8 *dest, u8 *orig, int dsize, int osize)
void r_mem_copyloop (u8 *dest, const u8 *orig, int dsize, int osize)
{
int i=0,j;
while(i<dsize)
@ -11,8 +11,16 @@ void r_mem_copyloop (u8 *dest, u8 *orig, int dsize, int osize)
dest[i++] = orig[j];
}
int r_mem_cmp_mask(const u8 *dest, const u8 *orig, const u8 *mask, int len)
{
int i, ret = 0;
for(i=0;i<len;i++)
ret += (orig[i]&mask[i])&dest[i];
return ret;
}
/* TODO check and use system endian */
void r_mem_copyendian (u8 *dest, u8 *orig, int size, int endian)
void r_mem_copyendian (u8 *dest, const u8 *orig, int size, int endian)
{
if (endian) {
memcpy(dest, orig, size);

View File

@ -19,6 +19,7 @@ core:
-lr_line -Wl,-R../../line -L../../line \
-lr_lib -Wl,-R../../lib -L../../lib \
-lr_flags -Wl,-R../../flags -L../../flags \
-lr_meta -Wl,-R../../meta -L../../meta \
-lr_macro -Wl,-R../../macro -L../../macro \
-lr_print -Wl,-R../../print -L../../print \
-lr_config -Wl,-R../../config -L../../config \