Add hints and named print formats and more
Initial implementation of anal hints (ah?) Use anal hints in core/disasm. Needs more work New data structure StrHT (string hashtable) Simplify core/libs.c with cpp macros Added r_cons_color() wip function for ansi256 consoles RPrint no longer depends on r_cons Sort 'a?' help commands Add support for named print formats with pf$ command Add support for 64 bit string pointers in 'pf' ('S') Add r_print_mute and r_print_format_length functions Bump r2 nodejs bindings version number Merge r_print into r_util
This commit is contained in:
parent
9b1ed0341a
commit
fc9301b14b
2
TODO.md
2
TODO.md
|
@ -14,7 +14,7 @@ Broken stuff to fixe before release
|
|||
|
||||
0.9.4
|
||||
=====
|
||||
* @b: @f: doesnt support temporary seek address?? support multiple @?
|
||||
* cmp rip+xx -> not resolved wtf
|
||||
* search for CALL instructions in text segment.
|
||||
- analyze the destination address of each call destination
|
||||
* Analysis: assume there is a function at the end of each function
|
||||
|
|
|
@ -29,7 +29,6 @@ LDFLAGS+=../../libr/cons/libr_cons.a
|
|||
LDFLAGS+=../../libr/diff/libr_diff.a
|
||||
LDFLAGS+=../../libr/syscall/libr_syscall.a
|
||||
LDFLAGS+=../../libr/flags/libr_flags.a
|
||||
LDFLAGS+=../../libr/print/libr_print.a
|
||||
LDFLAGS+=../../libr/reg/libr_reg.a
|
||||
LDFLAGS+=../../libr/debug/libr_debug.a
|
||||
LDFLAGS+=../../libr/search/libr_search.a
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
BIN=radare2
|
||||
BINDEPS=r_core r_parse r_search r_cons r_lib r_config
|
||||
BINDEPS+=r_bin r_debug r_anal r_diff r_reg r_bp r_io r_cmd r_fs
|
||||
BINDEPS+=r_sign r_print r_lang r_asm r_syscall r_db r_hash
|
||||
BINDEPS+=r_sign r_lang r_asm r_syscall r_db r_hash
|
||||
BINDEPS+=r_magic r_socket r_flags r_util r_egg
|
||||
|
||||
CFLAGS+=-DR2_BIRTH=\"`date +%Y-%m-%d`\" -DR2_GITTIP=\"$(GIT_TIP)\"
|
||||
|
|
|
@ -13,7 +13,8 @@ LIBS2=syscall cmd lang io crypto flags bin
|
|||
LIBS3=fs anal
|
||||
LIBS4=parse sign
|
||||
LIBS5=asm debug
|
||||
LIBS6=print egg
|
||||
LIBS6=egg
|
||||
#LIBS6+=print
|
||||
LIBS7=core
|
||||
|
||||
LIBS=$(LIBS0) $(LIBS1) $(LIBS2) $(LIBS3) $(LIBS4) $(LIBS5) $(LIBS6) $(LIBS7)
|
||||
|
|
|
@ -21,9 +21,9 @@ libr_anal.${EXT_SO} libr_anal.${EXT_AR}: pre
|
|||
|
||||
include ${STATIC_ANAL_PLUGINS}
|
||||
STATIC_OBJS=$(addprefix $(LTOP)/anal/p/,$(STATIC_OBJ))
|
||||
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o anal.o
|
||||
OBJLIBS+=cond.o value.o cc.o diff.o type.o fcnstore.o data.o
|
||||
OBJLIBS+=hint.o
|
||||
OBJLIBS=meta.o reflines.o ref.o op.o fcn.o bb.o var.o
|
||||
OBJLIBS+=cond.o value.o cc.o diff.o type.o fcnstore.o
|
||||
OBJLIBS+=hint.o vm.o anal.o data.o
|
||||
|
||||
ifeq ($(HAVE_CPARSE),1)
|
||||
CPARSE_OBJS=cparse/cparse.o cparse/lex.yy.o cparse/tree.o
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 - pancake, nibble */
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake, nibble */
|
||||
|
||||
#include <r_anal.h>
|
||||
#include <r_util.h>
|
||||
|
@ -40,6 +40,7 @@ R_API RAnal *r_anal_new() {
|
|||
anal->lineswidth = 0;
|
||||
anal->fcns = r_anal_fcn_list_new ();
|
||||
anal->fcnstore = r_listrange_new ();
|
||||
anal->hints = r_list_new ();
|
||||
anal->refs = r_anal_ref_list_new ();
|
||||
anal->types = r_anal_type_list_new ();
|
||||
r_anal_set_bits (anal, 32);
|
||||
|
|
112
libr/anal/hint.c
112
libr/anal/hint.c
|
@ -1,5 +1,117 @@
|
|||
/* radare - LGPL - Copyright 2013 - pancake */
|
||||
|
||||
#include <r_anal.h>
|
||||
|
||||
R_API void r_anal_hint_clear (RAnal *a) {
|
||||
// XXX: memory leak!
|
||||
r_list_free (a->hints);
|
||||
a->hints = r_list_new ();
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_del (RAnal *a, ut64 addr) {
|
||||
RAnalHint *hint = r_anal_hint_at (a, addr, 0);
|
||||
if (hint) r_list_delete_data (a->hints, hint);
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_list (RAnal *a, int mode) {
|
||||
RAnalHint *hint;
|
||||
RListIter *iter;
|
||||
// TODO: move into r_Core, show rad output mode too
|
||||
r_list_foreach (a->hints, iter, hint) {
|
||||
eprintf (" 0x%08"PFMT64x" - 0x%08"PFMT64x, hint->from, hint->to);
|
||||
if (hint->arch)
|
||||
eprintf (" arch='%s'", hint->arch);
|
||||
if (hint->bits)
|
||||
eprintf (" bits=%d", hint->bits);
|
||||
if (hint->length)
|
||||
eprintf (" length=%d", hint->length);
|
||||
if (hint->opcode)
|
||||
eprintf (" opcode='%s'", hint->opcode);
|
||||
if (hint->analstr)
|
||||
eprintf (" analstr='%s'", hint->analstr);
|
||||
eprintf ("\n");
|
||||
}
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_arch (RAnal *a, ut64 addr, int size, const char *arch) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, size);
|
||||
free (hint->arch);
|
||||
arch = r_str_trim_head (arch);
|
||||
hint->arch = strdup (arch);
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_opcode (RAnal *a, ut64 addr, int size, const char *opcode) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, size);
|
||||
free (hint->opcode);
|
||||
opcode = r_str_trim_head (opcode);
|
||||
hint->opcode = strdup (opcode);
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_analstr (RAnal *a, ut64 addr, int size, const char *analstr) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, size);
|
||||
free (hint->analstr);
|
||||
analstr = r_str_trim_head (analstr);
|
||||
hint->analstr = strdup (analstr);
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_bits (RAnal *a, ut64 addr, int size, int bits) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, size);
|
||||
hint->bits = bits;
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_set_length (RAnal *a, ut64 addr, int size, int length) {
|
||||
RAnalHint *hint = r_anal_hint_add (a, addr, size);
|
||||
hint->length = length;
|
||||
}
|
||||
|
||||
R_API RAnalHint *r_anal_hint_at (RAnal *a, ut64 from, int size) {
|
||||
ut64 to = from+size;
|
||||
RAnalHint *hint;
|
||||
RListIter *iter;
|
||||
if (size>0)
|
||||
r_list_foreach (a->hints, iter, hint) {
|
||||
if (from == hint->from && (!size|| (to == hint->to)))
|
||||
return hint;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API RAnalHint *r_anal_hint_add (RAnal *a, ut64 from, int size) {
|
||||
RAnalHint *hint = r_anal_hint_at (a, from, size);
|
||||
if (!hint) {
|
||||
hint = R_NEW0 (RAnalHint);
|
||||
r_list_append (a->hints, hint);
|
||||
}
|
||||
// TODO reuse entries if from and size match
|
||||
hint->from = from;
|
||||
if (size<1) size = 1;
|
||||
hint->to = from+size;
|
||||
return hint;
|
||||
}
|
||||
|
||||
R_API void r_anal_hint_free (RAnalHint *h) {
|
||||
free (h->arch);
|
||||
free (h);
|
||||
}
|
||||
|
||||
R_API RAnalHint *r_anal_hint_get(RAnal *anal, ut64 addr) {
|
||||
RAnalHint *res = NULL;
|
||||
RAnalHint *hint;
|
||||
RListIter *iter;
|
||||
r_list_foreach (anal->hints, iter, hint) {
|
||||
if (addr >= hint->from && addr < hint->to) {
|
||||
if (!res) res = R_NEW0 (RAnalHint);
|
||||
#define SETRET(x) if(hint->x)res->x=hint->x
|
||||
SETRET(arch);
|
||||
SETRET(bits);
|
||||
SETRET(opcode);
|
||||
SETRET(analstr);
|
||||
SETRET(length);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if 0
|
||||
ahl 33 0x80340
|
||||
|
|
|
@ -194,6 +194,8 @@ R_API int r_meta_add(RMeta *m, int type, ut64 from, ut64 to, const char *str) {
|
|||
eprintf ("r_meta_add: Unsupported type '%c'\n", type);
|
||||
return R_FALSE;
|
||||
}
|
||||
if (mi->type == R_META_TYPE_FORMAT)
|
||||
mi->size = r_print_format_length (mi->str);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -313,7 +315,7 @@ R_API int r_meta_list(RMeta *m, int type, int rad) {
|
|||
}
|
||||
|
||||
R_API char *r_anal_meta_bar (RAnal *anal, ut64 from, ut64 to, int blocks) {
|
||||
int i, blocksize;
|
||||
int i, n, blocksize;
|
||||
char *res;
|
||||
ut64 f, t;
|
||||
|
||||
|
@ -328,10 +330,8 @@ R_API char *r_anal_meta_bar (RAnal *anal, ut64 from, ut64 to, int blocks) {
|
|||
for (i=0; i< blocks; i++) {
|
||||
f = from + (blocksize*i);
|
||||
t = f+blocksize;
|
||||
{
|
||||
int n = r_anal_fcn_count (anal, f, t);
|
||||
if (n>0) res[i++] = 'f';
|
||||
}
|
||||
n = r_anal_fcn_count (anal, f, t);
|
||||
if (n>0) res[i++] = 'f';
|
||||
res[i++] = ',';
|
||||
}
|
||||
return res;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2010-2012 - pancake */
|
||||
/* radare - LGPL - Copyright 2010-2013 - pancake */
|
||||
|
||||
#include <string.h>
|
||||
#include <r_types.h>
|
||||
|
@ -8,8 +8,8 @@
|
|||
|
||||
static int mips_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *b, int len) {
|
||||
unsigned int opcode;
|
||||
char buf[10];
|
||||
int family, reg, optype, oplen = (anal->bits==16)?2:4;
|
||||
// UNUSED char buf[10]; int reg;
|
||||
int family, optype, oplen = (anal->bits==16)?2:4;
|
||||
|
||||
if (op == NULL)
|
||||
return oplen;
|
||||
|
|
|
@ -0,0 +1,32 @@
|
|||
#if 0
|
||||
r_anal_vm
|
||||
=========
|
||||
|
||||
call0_enter
|
||||
push ebp
|
||||
mov ebp, esp
|
||||
call0_exit
|
||||
|
||||
call0_signature:
|
||||
stack
|
||||
|
||||
r32=eax,ebx,ecx,edx,esp,ebp,esi,edi
|
||||
byte.0x6a=
|
||||
byte.0xc9=leave
|
||||
|
||||
regs:
|
||||
rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi
|
||||
|
||||
opcode
|
||||
0x6a, BYTE ; esp+=4;[esp-4]32=$0 # = push byte
|
||||
0x50:rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi push
|
||||
0x58:rax,rcx,rdx,rbx,rsp,rbp,rsi,rdi pop
|
||||
0xc9 = leave
|
||||
0xb8:$regs$u32 # mov $0, $1
|
||||
|
||||
stack
|
||||
keep backtrace
|
||||
|
||||
stackframes
|
||||
|
||||
#endif
|
|
@ -102,7 +102,7 @@ static RBreakpointItem *r_bp_add(RBreakpoint *bp, const ut8 *obytes, ut64 addr,
|
|||
eprintf ("Breakpoint already set at this address.\n");
|
||||
return NULL;
|
||||
}
|
||||
b = R_NEW (struct r_bp_item_t);
|
||||
b = R_NEW (RBreakpointItem);
|
||||
b->pids[0] = 0; /* for any pid */
|
||||
b->addr = addr;
|
||||
b->data = NULL;
|
||||
|
|
|
@ -29,6 +29,22 @@ static inline void r_cons_write (const char *buf, int len) {
|
|||
#endif
|
||||
}
|
||||
|
||||
R_API void r_cons_color (int fg, int r, int g, int b) {
|
||||
int k;
|
||||
r = R_DIM (r, 0, 255);
|
||||
g = R_DIM (g, 0, 255);
|
||||
b = R_DIM (b, 0, 255);
|
||||
if (r == g && g == b) { // b&w
|
||||
k = 232 + (int)(((r+g+b)/3)/10.3);
|
||||
} else {
|
||||
r = (int)(r/42.6);
|
||||
g = (int)(g/42.6);
|
||||
b = (int)(b/42.6);
|
||||
k = 16 + (r*36) + (g*6) + b;
|
||||
}
|
||||
r_cons_printf ("\x1b[%d;5;%dm", fg? 48: 38, k);
|
||||
}
|
||||
|
||||
R_API void r_cons_strcat_justify (const char *str, int j, char c) {
|
||||
int i, o, len;
|
||||
for (o=i=len=0; str[i]; i++, len++) {
|
||||
|
@ -456,8 +472,7 @@ R_API void r_cons_set_raw(int is_raw) {
|
|||
}
|
||||
|
||||
R_API void r_cons_invert(int set, int color) {
|
||||
if (color) r_cons_strcat (set? Color_INVERT: Color_INVERT_RESET);
|
||||
else r_cons_strcat (set? "[": "]");
|
||||
r_cons_strcat (R_CONS_INVERT (set, color));
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -2,9 +2,9 @@ include ../config.mk
|
|||
|
||||
NAME=r_core
|
||||
|
||||
DEPS=r_config r_cons r_io r_cmd r_util r_print r_flags r_asm r_lib
|
||||
DEPS+=r_debug r_hash r_bin r_lang r_io r_anal r_parse r_print r_bp r_egg
|
||||
DEPS+=r_reg r_search r_syscall r_sign r_diff r_socket r_fs r_magic r_db
|
||||
DEPS=r_config r_cons r_io r_cmd r_util r_flags r_asm r_lib r_db
|
||||
DEPS+=r_debug r_hash r_bin r_lang r_io r_anal r_parse r_bp r_egg
|
||||
DEPS+=r_reg r_search r_syscall r_sign r_diff r_socket r_fs r_magic
|
||||
|
||||
OBJS=core.o cmd.o file.o config.o visual.o io.o yank.o libs.o hack.o vasm.o
|
||||
OBJS+=anal.o project.o gdiff.o asm.o rtr.o vmenus.o disasm.o patch.o bin.o log.o
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 // pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake */
|
||||
|
||||
#if 1
|
||||
/* TODO: Move into cmd_anal() */
|
||||
|
@ -845,29 +845,105 @@ case 'o':
|
|||
}
|
||||
break;
|
||||
default:
|
||||
eprintf ("Usage: ad[kt] [...]\n");
|
||||
eprintf (" ad [N] [D] analyze N data words at D depth\n");
|
||||
eprintf (" adt analyze data trampolines (wip)\n");
|
||||
eprintf (" adk analyze kind of data (code, text, data, invalid, ...)\n");
|
||||
eprintf ("Usage: ad[kt] [...]\n"
|
||||
" ad [N] [D] analyze N data words at D depth\n"
|
||||
" adt analyze data trampolines (wip)\n"
|
||||
" adk analyze data kind (code, text, data, invalid, ...)\n");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'h':
|
||||
switch (input[1]) {
|
||||
case '?':
|
||||
if (input[2]) {
|
||||
//ut64 addr = r_num_math (core->num, input+2);
|
||||
eprintf ("TODO: show hint\n");
|
||||
} else
|
||||
r_cons_printf (
|
||||
"Usage: ah[lba-]\n"
|
||||
" ah? offset # show hint of given offset\n"
|
||||
" aha ppc 51 # set arch for a range of N bytes\n"
|
||||
" ahb 16 @ $$ # force 16bit for current instruction\n"
|
||||
" ahl 4 32 # set opcode size=4 for range of 32 bytes\n"
|
||||
" aho foo a0,33 # replace opcode string\n"
|
||||
" ahA eax+=3 # set vm analysis string\n"
|
||||
);
|
||||
break;
|
||||
#if 0
|
||||
in core/disasm we call
|
||||
R_API int r_core_hint(RCore *core, ut64 addr) {
|
||||
static int hint_bits = 0;
|
||||
RAnalHint *hint = r_anal_hint_get (core->anal, addr);
|
||||
if (hint->bits) {
|
||||
if (!hint_bits)
|
||||
hint_bits = core->assembler->bits;
|
||||
r_config_set_i (core->config, "asm.bits", hint->bits);
|
||||
} else if (hint_bits) {
|
||||
r_config_set_i (core->config, "asm.bits", hint_bits);
|
||||
hint_bits = 0;
|
||||
}
|
||||
if (hint->arch)
|
||||
r_config_set (core->config, "asm.arch", hint->arch);
|
||||
if (hint->length)
|
||||
force_instruction_length = hint->length;
|
||||
r_anal_hint_free (hint);
|
||||
#endif
|
||||
case 'a': // set arch
|
||||
r_anal_hint_set_arch (core->anal, core->offset,
|
||||
1, input+2);
|
||||
break;
|
||||
case 'b': // set bits
|
||||
r_anal_hint_set_bits (core->anal, core->offset,
|
||||
1, atoi (input+2));
|
||||
//r_anal_hint_bits (op, 1);
|
||||
break;
|
||||
case 'l': // set size (opcode length)
|
||||
r_anal_hint_set_length (core->anal, core->offset,
|
||||
1, atoi (input+2));
|
||||
break;
|
||||
case 'o': // set opcode string
|
||||
r_anal_hint_set_opcode (core->anal, core->offset,
|
||||
1, input+2);
|
||||
break;
|
||||
case 'A': // set analysis string
|
||||
r_anal_hint_set_analstr (core->anal, core->offset,
|
||||
1, input+2);
|
||||
break;
|
||||
#if TODO
|
||||
case 'e': // set endian
|
||||
r_anal_hint_set_opcode (core->anal, core->offset,
|
||||
1, atoi (input+2));
|
||||
break;
|
||||
#endif
|
||||
case '*':
|
||||
case '\0':
|
||||
r_anal_hint_list (core->anal, input[1]);
|
||||
break;
|
||||
case '-':
|
||||
if (input[2]) {
|
||||
r_anal_hint_del (core->anal,
|
||||
r_num_math (core->num, input+2));
|
||||
} else r_anal_hint_clear (core->anal);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
r_cons_printf (
|
||||
"Usage: a[?obdfrgtv]\n"
|
||||
" aa ; analyze all (fcns + bbs)\n"
|
||||
"Usage: a[?adfFghoprsx]\n"
|
||||
" a8 [hexpairs] ; analyze bytes\n"
|
||||
" aa ; analyze all (fcns + bbs)\n"
|
||||
" ad ; analyze data trampoline (wip)\n"
|
||||
" ap ; find and analyze function preludes\n"
|
||||
" ad [from] [to] ; analyze data pointers to (from-to)\n"
|
||||
" as [num] ; analyze syscall using dbg.reg\n"
|
||||
" ax[-cCd] [f] [t] ; manage code/call/data xrefs\n"
|
||||
" ao[e?] [len] ; analyze Opcodes (or emulate it)\n"
|
||||
" af[bcsl?+-*] ; analyze Functions\n"
|
||||
" aF ; same as above, but using graph.depth=1\n"
|
||||
" ar[?ld-*] ; manage refs/xrefs\n"
|
||||
" ag[?acgdlf] ; output Graphviz code\n"
|
||||
" ah[?lba-] ; analysis hints (force opcode size, ...)\n"
|
||||
" ao[e?] [len] ; analyze Opcodes (or emulate it)\n"
|
||||
" ap ; find and analyze function preludes\n"
|
||||
" ar[?ld-*] ; manage refs/xrefs\n"
|
||||
" as [num] ; analyze syscall using dbg.reg\n"
|
||||
" at[trd+-*?] [.] ; analyze execution Traces\n"
|
||||
" ax[-cCd] [f] [t] ; manage code/call/data xrefs\n"
|
||||
"Examples:\n"
|
||||
" f ts @ `S*~text:0[3]`; f t @ section..text\n"
|
||||
" f ds @ `S*~data:0[3]`; f d @ section..data\n"
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 - pancake */
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake */
|
||||
|
||||
static int printzoomcallback(void *user, int mode, ut64 addr, ut8 *bufz, ut64 size) {
|
||||
RCore *core = (RCore *) user;
|
||||
|
@ -557,7 +557,7 @@ static int cmd_print(void *data, const char *input) {
|
|||
else eprintf ("r_base64_decode: invalid stream\n");
|
||||
break;
|
||||
default:
|
||||
eprintf ("Usage: p6[ed] [len] ; base 64 encode/decode\n");
|
||||
eprintf ("Usage: p6[ed] [len] base 64 encode/decode\n");
|
||||
break;
|
||||
}
|
||||
free (buf);
|
||||
|
@ -567,7 +567,40 @@ static int cmd_print(void *data, const char *input) {
|
|||
r_print_bytes (core->print, core->block, len, "%02x");
|
||||
break;
|
||||
case 'f':
|
||||
r_print_format (core->print, core->offset, core->block, len, input+1);
|
||||
if (input[1]=='$') {
|
||||
if (input[2]=='\0') {
|
||||
RListIter *iter;
|
||||
RStrHT *sht = core->print->formats;
|
||||
int *i;
|
||||
r_list_foreach (sht->ls, iter, i) {
|
||||
int idx = ((int)(size_t)i)-1;
|
||||
const char *key = r_strpool_get (sht->sp, idx);
|
||||
const char *val = r_strht_get (core->print->formats, key);
|
||||
r_cons_printf ("%s %s\n", key, val);
|
||||
}
|
||||
} else
|
||||
if (input[2]=='-') {
|
||||
if (input[3]) r_strht_del (core->print->formats, input+3);
|
||||
else r_strht_clear (core->print->formats);
|
||||
} else {
|
||||
char *name = strdup (input+2);
|
||||
char *space = strchr (name, ' ');
|
||||
if (space) {
|
||||
*space++ = 0;
|
||||
//printf ("SET (%s)(%s)\n", name, space);
|
||||
r_strht_set (core->print->formats, name, space);
|
||||
return 0;
|
||||
} else {
|
||||
const char *fmt = r_strht_get (core->print->formats, name);
|
||||
if (fmt) {
|
||||
//printf ("GET (%s) = %s\n", name, fmt);
|
||||
r_print_format (core->print, core->offset,
|
||||
core->block, len, fmt);
|
||||
} else eprintf ("Unknown format (%s)\n", name);
|
||||
}
|
||||
free (name);
|
||||
}
|
||||
} else r_print_format (core->print, core->offset, core->block, len, input+1);
|
||||
break;
|
||||
case 'n': // easter penis
|
||||
for (l=0; l<10; l++) {
|
||||
|
@ -662,20 +695,20 @@ static int cmd_print(void *data, const char *input) {
|
|||
default:
|
||||
r_cons_printf (
|
||||
"Usage: p[fmt] [len]\n"
|
||||
" p= show entropy bars of full file\n"
|
||||
" p6[de] [len] base64 decode/encode\n"
|
||||
" p8 [len] 8bit hexpair list of bytes\n"
|
||||
" pa [opcode] bytes of assembled opcode\n"
|
||||
" pb [len] bitstream of N bytes\n"
|
||||
" pc[p] [len] output C (or python) format\n"
|
||||
" pd[lf] [l] disassemble N opcodes (see pd?)\n"
|
||||
" pD [len] disassemble N bytes\n"
|
||||
" pf [fmt] print formatted data\n"
|
||||
" pi[f] [len] print N instructions (f=function) (see pdi)\n"
|
||||
" pm [magic] print libmagic data (pm? for more information)\n"
|
||||
" pr [len] print N raw bytes\n"
|
||||
" ps[pwz] [len] print pascal/wide/zero-terminated strings\n"
|
||||
" pt[dn?] [len] print different timestamps\n"
|
||||
" p= show entropy bars of full file\n"
|
||||
" p6[de] [len] base64 decode/encode\n"
|
||||
" p8 [len] 8bit hexpair list of bytes\n"
|
||||
" pa [opcode] bytes of assembled opcode\n"
|
||||
" pb [len] bitstream of N bytes\n"
|
||||
" pc[p] [len] output C (or python) format\n"
|
||||
" pd[lf] [l] disassemble N opcodes (see pd?)\n"
|
||||
" pD [len] disassemble N bytes\n"
|
||||
" pf[$nam] [fmt] print formatted data (pf$name, pf$name $<expression>) \n"
|
||||
" pi[f] [len] print N instructions (f=function) (see pdi)\n"
|
||||
" pm [magic] print libmagic data (pm? for more information)\n"
|
||||
" pr [len] print N raw bytes\n"
|
||||
" ps[pwz] [len] print pascal/wide/zero-terminated strings\n"
|
||||
" pt[dn?] [len] print different timestamps\n"
|
||||
" pu[w] [len] print N url encoded bytes (w=wide)\n"
|
||||
" px[owq] [len] hexdump of N bytes (o=octal, w=32bit, q=64bit)\n"
|
||||
" pz [len] print zoom view (see pz? for help)\n");
|
||||
|
|
|
@ -304,26 +304,59 @@ static int cmd_write(void *data, const char *input) {
|
|||
}
|
||||
break;
|
||||
case 'v':
|
||||
off = r_num_math (core->num, input+1);
|
||||
r_io_set_fd (core->io, core->file->fd);
|
||||
r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
|
||||
if (off&UT64_32U) {
|
||||
/* 8 byte addr */
|
||||
{
|
||||
int type = 0;
|
||||
ut8 addr1;
|
||||
ut16 addr2;
|
||||
ut32 addr4, addr4_;
|
||||
ut64 addr8;
|
||||
memcpy((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
|
||||
// endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
|
||||
r_io_write(core->io, (const ut8 *)&addr8, 8);
|
||||
WSEEK (core, 8);
|
||||
} else {
|
||||
/* 4 byte addr */
|
||||
ut32 addr4, addr4_ = (ut32)off;
|
||||
//drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
|
||||
//endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
|
||||
memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
|
||||
r_io_write (core->io, (const ut8 *)&addr4, 4);
|
||||
WSEEK (core, 4);
|
||||
|
||||
switch (input[1]) {
|
||||
case '?':
|
||||
r_cons_printf ("Usage: wv[size] [value] # write value of given size\n"
|
||||
" wv1 234 # write one byte with this value\n"
|
||||
" wv 0x834002 # write dword with this value\n"
|
||||
"Supported sizes are: 1, 2, 4, 8\n");
|
||||
return 0;
|
||||
case '1': type = 1; break;
|
||||
case '2': type = 2; break;
|
||||
case '4': type = 4; break;
|
||||
case '8': type = 8; break;
|
||||
}
|
||||
off = r_num_math (core->num, input+2);
|
||||
r_io_set_fd (core->io, core->file->fd);
|
||||
r_io_seek (core->io, core->offset, R_IO_SEEK_SET);
|
||||
if (type == 0)
|
||||
type = (off&UT64_32U)? 8: 4;
|
||||
switch (type) {
|
||||
case 1:
|
||||
addr1 = (ut8)off;
|
||||
r_io_write (core->io, (const ut8 *)&addr1, 1);
|
||||
WSEEK (core, 1);
|
||||
break;
|
||||
case 2:
|
||||
addr2 = (ut16)off;
|
||||
r_io_write (core->io, (const ut8 *)&addr2, 2);
|
||||
WSEEK (core, 2);
|
||||
break;
|
||||
case 4:
|
||||
addr4_ = (ut32)off;
|
||||
//drop_endian((ut8*)&addr4_, (ut8*)&addr4, 4); /* addr4_ = addr4 */
|
||||
//endian_memcpy((ut8*)&addr4, (ut8*)&addr4_, 4); /* addr4 = addr4_ */
|
||||
memcpy ((ut8*)&addr4, (ut8*)&addr4_, 4); // XXX needs endian here too
|
||||
r_io_write (core->io, (const ut8 *)&addr4, 4);
|
||||
WSEEK (core, 4);
|
||||
break;
|
||||
case 8:
|
||||
/* 8 byte addr */
|
||||
memcpy ((ut8*)&addr8, (ut8*)&off, 8); // XXX needs endian here
|
||||
// endian_memcpy((ut8*)&addr8, (ut8*)&off, 8);
|
||||
r_io_write (core->io, (const ut8 *)&addr8, 8);
|
||||
WSEEK (core, 8);
|
||||
break;
|
||||
}
|
||||
r_core_block_read (core, 0);
|
||||
}
|
||||
r_core_block_read (core, 0);
|
||||
break;
|
||||
case 'o':
|
||||
switch (input[1]) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 - pancake */
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake */
|
||||
|
||||
#include <r_core.h>
|
||||
#include <r_socket.h>
|
||||
|
@ -453,6 +453,7 @@ R_API int r_core_init(RCore *core) {
|
|||
core->print->user = core;
|
||||
core->print->offname = r_core_print_offname;
|
||||
core->print->printf = (void *)r_cons_printf;
|
||||
core->print->write = (void *)r_cons_memcat;
|
||||
core->lang = r_lang_new ();
|
||||
r_lang_define (core->lang, "RCore", "core", core);
|
||||
r_lang_set_user_ptr (core->lang, core);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 - nibble, pancake */
|
||||
/* radare - LGPL - Copyright 2009-2013 - nibble, pancake */
|
||||
|
||||
#include "r_core.h"
|
||||
|
||||
|
@ -34,6 +34,11 @@ static void printoffset(ut64 off, int show_color, int invert, int opt) {
|
|||
|
||||
// int l is for lines
|
||||
R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int len, int l, int invbreak, int cbytes) {
|
||||
/* hints */
|
||||
RAnalHint *hint = NULL;
|
||||
char *hint_arch = NULL;
|
||||
int hint_bits = 0;
|
||||
/* other */
|
||||
int ret, idx = 0, i, j, k, lines, ostackptr = 0, stackptr = 0;
|
||||
char *line = NULL, *comment = NULL, *opstr, *osl = NULL; // old source line
|
||||
int continueoninvbreak = (len == l) && invbreak;
|
||||
|
@ -119,7 +124,6 @@ R_API int r_core_print_disasm(RPrint *p, RCore *core, ut64 addr, ut8 *buf, int l
|
|||
toro:
|
||||
// uhm... is this necesary? imho can be removed
|
||||
r_asm_set_pc (core->assembler, addr+idx);
|
||||
|
||||
#if 0
|
||||
/* find last function else stackptr=0 */
|
||||
{
|
||||
|
@ -171,9 +175,34 @@ toro:
|
|||
oplen = 1;
|
||||
for (i=idx=ret=0; idx < len && lines < l; idx+=oplen,i++, lines++) {
|
||||
ut64 at = addr + idx;
|
||||
if (cbytes) {
|
||||
if (idx>=l)
|
||||
break;
|
||||
if (hint) {
|
||||
r_anal_hint_free (hint);
|
||||
hint = NULL;
|
||||
}
|
||||
hint = r_anal_hint_get (core->anal, at);
|
||||
if (cbytes && idx>=l)
|
||||
break;
|
||||
if (hint_arch) {
|
||||
r_config_set (core->config, "asm.arch", hint_arch);
|
||||
hint_arch = NULL;
|
||||
}
|
||||
if (hint_bits) {
|
||||
r_config_set_i (core->config, "asm.bits", hint_bits);
|
||||
hint_bits = 0;
|
||||
}
|
||||
if (hint) {
|
||||
/* arch */
|
||||
if (hint->arch) {
|
||||
if (!hint_arch) hint_arch = strdup (
|
||||
r_config_get (core->config, "asm.arch"));
|
||||
r_config_set (core->config, "asm.arch", hint->arch);
|
||||
}
|
||||
/* bits */
|
||||
if (hint->bits) {
|
||||
if (!hint_bits) hint_bits =
|
||||
r_config_get_i (core->config, "asm.bits");
|
||||
r_config_set_i (core->config, "asm.bits", hint->bits);
|
||||
}
|
||||
}
|
||||
r_asm_set_pc (core->assembler, at);
|
||||
if (show_lines) {
|
||||
|
@ -284,7 +313,9 @@ toro:
|
|||
sprintf (asmop.buf_hex, "%02x", buf[idx]);
|
||||
} else {
|
||||
lastfail = 0;
|
||||
oplen = r_asm_op_get_size (&asmop);
|
||||
if (hint && hint->length)
|
||||
oplen = hint->length;
|
||||
else oplen = r_asm_op_get_size (&asmop);
|
||||
}
|
||||
if (acase)
|
||||
r_str_case (asmop.buf_asm, 1);
|
||||
|
@ -311,6 +342,8 @@ toro:
|
|||
r_anal_op_fini (&analop);
|
||||
if (!lastfail)
|
||||
r_anal_op (core->anal, &analop, at, buf+idx, (int)(len-idx));
|
||||
if (hint && hint->length)
|
||||
analop.length = hint->length;
|
||||
{
|
||||
RAnalValue *src;
|
||||
switch (analop.type) {
|
||||
|
@ -470,7 +503,9 @@ toro:
|
|||
}
|
||||
continue;
|
||||
case R_META_TYPE_FORMAT:
|
||||
r_cons_printf ("format %s {\n", mi->str);
|
||||
r_print_format (core->print, at, buf+idx, len-idx, mi->str);
|
||||
r_cons_printf ("} %d\n", mi->size);
|
||||
oplen = ret = (int)mi->size;
|
||||
free (line);
|
||||
free (refline);
|
||||
|
@ -575,6 +610,10 @@ toro:
|
|||
// if we want to get more information
|
||||
opstr = tmpopstr? tmpopstr: strdup (asmop.buf_asm);
|
||||
}
|
||||
if (hint && hint->opcode) {
|
||||
free (opstr);
|
||||
opstr = strdup (hint->opcode);
|
||||
}
|
||||
if (filter) {
|
||||
int ofs = core->parser->flagspace;
|
||||
int fs = flagspace_ports;
|
||||
|
@ -787,6 +826,7 @@ toro:
|
|||
}
|
||||
#endif
|
||||
r_anal_op_fini (&analop);
|
||||
if (hint) r_anal_hint_free (hint);
|
||||
free (osl);
|
||||
return idx-lastfail;
|
||||
}
|
||||
|
|
168
libr/core/libs.c
168
libr/core/libs.c
|
@ -1,140 +1,46 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 - pancake */
|
||||
/* radare - LGPL - Copyright 2009-2013 - pancake */
|
||||
|
||||
#include "r_core.h"
|
||||
|
||||
// XXX: spageti!
|
||||
/* io callback */
|
||||
static int __lib_io_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_io_plugin_t *hand = (struct r_io_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added IO handler\n");
|
||||
r_io_plugin_add (core->io, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
#define CB(x,y) \
|
||||
static int __lib_##x##_cb(RLibPlugin *pl, void *user, void *data) { \
|
||||
struct r_##x##_plugin_t *hand = (struct r_##x##_plugin_t *)data; \
|
||||
RCore *core = (RCore *)user; \
|
||||
r_##x##_add (core->y, hand); \
|
||||
return R_TRUE; \
|
||||
}\
|
||||
static int __lib_##x##_dt(RLibPlugin *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
static int __lib_io_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* cmd callback */
|
||||
static int __lib_cmd_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_cmd_plugin_t *hand = (struct r_cmd_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added CMD handler\n");
|
||||
r_cmd_plugin_add (core->rcmd, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_cmd_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* debug callback */
|
||||
static int __lib_dbg_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_debug_plugin_t *hand = (struct r_debug_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added debugger handler\n");
|
||||
r_debug_plugin_add (core->dbg, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_dbg_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* breakpoint callback */
|
||||
static int __lib_bp_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_bp_plugin_t *hand = (struct r_bp_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added bpger handler\n");
|
||||
r_bp_plugin_add (core->dbg->bp, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_bp_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* lang callback */
|
||||
static int __lib_lng_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_lang_plugin_t *hand = (struct r_lang_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added language handler\n");
|
||||
r_lang_add (core->lang, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_lng_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* anal callback */
|
||||
static int __lib_anl_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_anal_plugin_t *hand = (struct r_anal_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added analysis handler\n");
|
||||
r_anal_add (core->anal, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_anl_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* asm callback */
|
||||
static int __lib_asm_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_asm_plugin_t *hand = (struct r_asm_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added (dis)assembly handler\n");
|
||||
r_asm_add (core->assembler, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_asm_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* parse callback */
|
||||
static int __lib_parse_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_parse_plugin_t *hand = (struct r_parse_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added (dis)assembly handler\n");
|
||||
r_parse_add (core->parser, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_parse_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* bin callback */
|
||||
static int __lib_bin_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
struct r_bin_plugin_t *hand = (struct r_bin_plugin_t *)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added (dis)assembly handler\n");
|
||||
r_bin_add (core->bin, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_bin_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
|
||||
/* bin callback */
|
||||
static int __lib_egg_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
|
||||
REggPlugin *hand = (REggPlugin*)data;
|
||||
struct r_core_t *core = (struct r_core_t *)user;
|
||||
//printf(" * Added (dis)assembly handler\n");
|
||||
r_egg_add (core->egg, hand);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int __lib_egg_dt(struct r_lib_plugin_t *pl, void *p, void *u) { return R_TRUE; }
|
||||
// XXX api consistency issues
|
||||
#define r_io_add r_io_plugin_add
|
||||
CB (io, io)
|
||||
#define r_cmd_add r_cmd_plugin_add
|
||||
CB (cmd, rcmd)
|
||||
#define r_debug_add r_debug_plugin_add
|
||||
CB (debug, dbg)
|
||||
#define r_bp_add r_bp_plugin_add
|
||||
CB (bp, dbg->bp)
|
||||
CB (lang, lang)
|
||||
CB (anal, anal)
|
||||
CB (asm, assembler)
|
||||
CB (parse, parser)
|
||||
CB (bin, bin)
|
||||
CB (egg, egg)
|
||||
|
||||
R_API int r_core_loadlibs_init(struct r_core_t *core) {
|
||||
/* initialize handlers */
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_IO, "io plugins",
|
||||
&__lib_io_cb, &__lib_io_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_CMD, "cmd plugins",
|
||||
&__lib_cmd_cb, &__lib_cmd_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_DBG, "debug plugins",
|
||||
&__lib_dbg_cb, &__lib_dbg_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_BP, "breakpoint plugins",
|
||||
&__lib_bp_cb, &__lib_bp_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_LANG, "language plugins",
|
||||
&__lib_lng_cb, &__lib_lng_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_ANAL, "analysis plugins",
|
||||
&__lib_anl_cb, &__lib_anl_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_ASM, "(dis)assembly plugins",
|
||||
&__lib_asm_cb, &__lib_asm_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_PARSE, "parsing plugins",
|
||||
&__lib_parse_cb, &__lib_parse_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_BIN, "bin plugins",
|
||||
&__lib_bin_cb, &__lib_bin_dt, core);
|
||||
r_lib_add_handler (core->lib, R_LIB_TYPE_EGG, "egg plugins",
|
||||
&__lib_egg_cb, &__lib_egg_dt, core);
|
||||
#define DF(x,y,z) r_lib_add_handler(core->lib, R_LIB_TYPE_##x,y,&__lib_##z##_cb, &__lib_##z##_dt, core);
|
||||
|
||||
DF(IO,"io plugins",io);
|
||||
DF(CMD,"cmd plugins",cmd);
|
||||
DF(DBG,"debugger plugins",debug);
|
||||
DF(BP,"debugger breakpoint plugins",bp);
|
||||
DF(LANG,"language plugins",lang);
|
||||
DF(ANAL,"analysis plugins",anal);
|
||||
DF(ASM,"(dis)assembler plugins",asm);
|
||||
DF(PARSE,"parsing plugins",parse);
|
||||
DF(BIN,"bin plugins",bin);
|
||||
DF(EGG,"egg plugins",egg);
|
||||
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2011-2012 - pancake */
|
||||
/* radare - LGPL - Copyright 2011-2013 - pancake */
|
||||
|
||||
#include <r_core.h>
|
||||
|
||||
|
|
|
@ -0,0 +1,44 @@
|
|||
|
||||
/** hashtable **/
|
||||
typedef struct r_hashtable_entry_t {
|
||||
ut32 hash;
|
||||
void *data;
|
||||
} RHashTableEntry;
|
||||
|
||||
typedef struct r_hashtable_t {
|
||||
RHashTableEntry *table;
|
||||
ut32 size;
|
||||
ut32 rehash;
|
||||
ut32 max_entries;
|
||||
ut32 size_index;
|
||||
ut32 entries;
|
||||
ut32 deleted_entries;
|
||||
} RHashTable;
|
||||
|
||||
typedef struct r_hashtable64_entry_t {
|
||||
ut64 hash;
|
||||
void *data;
|
||||
} RHashTable64Entry;
|
||||
|
||||
typedef struct r_hashtable64_t {
|
||||
RHashTable64Entry *table;
|
||||
ut64 size;
|
||||
ut64 rehash;
|
||||
ut64 max_entries;
|
||||
ut64 size_index;
|
||||
ut64 entries;
|
||||
ut64 deleted_entries;
|
||||
} RHashTable64;
|
||||
|
||||
R_API RHashTable* r_hashtable_new(void);
|
||||
R_API void r_hashtable_free(RHashTable *ht);
|
||||
R_API void *r_hashtable_lookup(RHashTable *ht, ut32 hash);
|
||||
R_API boolt r_hashtable_insert(RHashTable *ht, ut32 hash, void *data);
|
||||
R_API void r_hashtable_remove(RHashTable *ht, ut32 hash);
|
||||
|
||||
R_API RHashTable64* r_hashtable64_new(void);
|
||||
R_API void r_hashtable64_free(RHashTable64 *ht);
|
||||
R_API void *r_hashtable64_lookup(RHashTable64 *ht, ut64 hash);
|
||||
R_API boolt r_hashtable64_insert(RHashTable64 *ht, ut64 hash, void *data);
|
||||
R_API void r_hashtable64_remove(RHashTable64 *ht, ut64 hash);
|
||||
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2009-2012 - nibble, pancake, xvilka */
|
||||
/* radare - LGPL - Copyright 2009-2013 - nibble, pancake, xvilka */
|
||||
|
||||
#ifndef _INCLUDE_R_ANAL_H_
|
||||
#define _INCLUDE_R_ANAL_H_
|
||||
|
@ -492,8 +492,19 @@ typedef struct r_anal_t {
|
|||
//struct r_anal_ctx_t *ctx;
|
||||
struct r_anal_plugin_t *cur;
|
||||
struct list_head anals; // TODO: Reimplement with RList
|
||||
RList *hints; // XXX use better data structure here (slist?)
|
||||
} RAnal;
|
||||
|
||||
typedef struct r_anal_hint_t {
|
||||
ut64 from;
|
||||
ut64 to;
|
||||
char *arch;
|
||||
char *opcode;
|
||||
char *analstr;
|
||||
int length;
|
||||
int bits;
|
||||
} RAnalHint;
|
||||
|
||||
// mul*value+regbase+regidx+delta
|
||||
typedef struct r_anal_value_t {
|
||||
int absolute; // if true, unsigned cast is used
|
||||
|
@ -831,6 +842,19 @@ R_API RMetaItem *r_meta_item_new(int type);
|
|||
R_API int r_anal_fcn_xref_add (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 addr, int type);
|
||||
R_API int r_anal_fcn_xref_del (RAnal *anal, RAnalFunction *fcn, ut64 at, ut64 addr, int type);
|
||||
|
||||
/* hints */
|
||||
R_API void r_anal_hint_list (RAnal *anal, int mode);
|
||||
R_API void r_anal_hint_del (RAnal *anal, ut64 addr);
|
||||
R_API RAnalHint *r_anal_hint_at (RAnal *a, ut64 from, int size);
|
||||
R_API RAnalHint *r_anal_hint_add (RAnal *a, ut64 from, int size);
|
||||
R_API void r_anal_hint_free (RAnalHint *h);
|
||||
R_API RAnalHint *r_anal_hint_get(RAnal *anal, ut64 addr);
|
||||
R_API void r_anal_hint_set_bits (RAnal *a, ut64 addr, int size, int bits);
|
||||
R_API void r_anal_hint_set_arch (RAnal *a, ut64 addr, int size, const char *arch);
|
||||
R_API void r_anal_hint_set_length (RAnal *a, ut64 addr, int size, int length);
|
||||
R_API void r_anal_hint_set_opcode (RAnal *a, ut64 addr, int size, const char *str);
|
||||
R_API void r_anal_hint_set_analstr (RAnal *a, ut64 addr, int size, const char *str);
|
||||
|
||||
/* plugin pointers */
|
||||
extern RAnalPlugin r_anal_plugin_csr;
|
||||
extern RAnalPlugin r_anal_plugin_avr;
|
||||
|
|
|
@ -237,6 +237,7 @@ R_API void r_cons_grep(const char *str);
|
|||
R_API int r_cons_grep_line(char *buf, int len); // must be static
|
||||
R_API int r_cons_grepbuf(char *buf, int len);
|
||||
|
||||
R_API void r_cons_color (int fg, int r, int g, int b);
|
||||
R_API void r_cons_invert(int set, int color);
|
||||
R_API int r_cons_yesno(int def, const char *fmt, ...);
|
||||
R_API void r_cons_set_cup(int enable);
|
||||
|
@ -245,7 +246,6 @@ R_API int r_cons_get_column();
|
|||
R_API char *r_cons_message(const char *msg);
|
||||
#endif
|
||||
|
||||
|
||||
/* r_line */
|
||||
#define R_LINE_BUFSIZE 4096
|
||||
#define R_LINE_HISTSIZE 256
|
||||
|
@ -304,7 +304,8 @@ R_API int r_line_hist_save(const char *file);
|
|||
R_API int r_line_hist_label(const char *label, void (*cb)(const char*));
|
||||
R_API void r_line_label_show();
|
||||
|
||||
#endif
|
||||
|
||||
#define R_CONS_INVERT(x,y) (y? (x?Color_INVERT: Color_INVERT_RESET): (x?"[":"]"))
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -13,7 +13,8 @@
|
|||
// rename to REggShellcode
|
||||
#define R_EGG_PLUGIN_SHELLCODE 0
|
||||
#define R_EGG_PLUGIN_ENCODER 1
|
||||
typedef struct r_egg_plugin {
|
||||
|
||||
typedef struct r_egg_plugin_t {
|
||||
const char *name;
|
||||
const char *desc;
|
||||
int type;
|
||||
|
|
|
@ -28,7 +28,9 @@ typedef struct r_print_t {
|
|||
void *user;
|
||||
RIOBind iob;
|
||||
char datefmt[32];
|
||||
int (*write)(const unsigned char *buf, int len);
|
||||
int (*printf)(const char *str, ...);
|
||||
int (*oprintf)(const char *str, ...);
|
||||
/* TODO: add printf callback */
|
||||
int interrupt;
|
||||
int bigendian;
|
||||
|
@ -43,12 +45,14 @@ typedef struct r_print_t {
|
|||
int col;
|
||||
RPrintZoom *zoom;
|
||||
RPrintNameCallback offname;
|
||||
RStrHT *formats;
|
||||
} RPrint;
|
||||
|
||||
#ifdef R_API
|
||||
R_API char *r_print_hexpair(RPrint *p, const char *str, int idx);
|
||||
R_API RPrint *r_print_new();
|
||||
R_API RPrint *r_print_free(RPrint *p);
|
||||
R_API int r_print_mute(RPrint *p, int x);
|
||||
R_API void r_print_set_flags(RPrint *p, int _flags);
|
||||
R_API void r_print_unset_flags(RPrint *p, int flags);
|
||||
R_API void r_print_addr(RPrint *p, ut64 addr);
|
||||
|
@ -64,7 +68,8 @@ R_API void r_print_cursor(RPrint *p, int cur, int set);
|
|||
R_API void r_print_cursor_range(RPrint *p, int cur, int to, int set);
|
||||
R_API void r_print_set_cursor(RPrint *p, int curset, int ocursor, int cursor);
|
||||
R_API void r_print_code(RPrint *p, ut64 addr, ut8 *buf, int len, char lang);
|
||||
R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const char *fmt);
|
||||
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const char *fmt);
|
||||
R_API int r_print_format_length (const char *fmt);
|
||||
// XXX . change wide, zeroend, urlencode for option flags
|
||||
R_API int r_print_string(RPrint *p, ut64 seek, const ut8 *str, int len, int wide, int zeroend, int urlencode);
|
||||
R_API int r_print_date_dos(RPrint *p, ut8 *buf, int len);
|
||||
|
|
|
@ -122,6 +122,7 @@ typedef void (*PrintfCallback)(const char *str, ...);
|
|||
#define eprintf(x,y...) fprintf(stderr,x,##y)
|
||||
|
||||
#define R_ROUND(x,y) ((x)%(y))? (x)+((y)-((x)%(y))): (x)
|
||||
#define R_DIM(x,y,z) (x<y?y:x>z?z:x)
|
||||
#define R_MAX(x,y) ((x)>(y))?x:y
|
||||
#define R_MIN(x,y) ((x)>(y))?y:x
|
||||
#define R_ABS(x) (((x)<0)?-(x):(x))
|
||||
|
|
|
@ -154,36 +154,7 @@ enum {
|
|||
R_SYS_BITS_64 = 8,
|
||||
};
|
||||
|
||||
/** hashtable **/
|
||||
typedef struct r_hashtable_entry_t {
|
||||
ut32 hash;
|
||||
void *data;
|
||||
} RHashTableEntry;
|
||||
|
||||
typedef struct r_hashtable_t {
|
||||
RHashTableEntry *table;
|
||||
ut32 size;
|
||||
ut32 rehash;
|
||||
ut32 max_entries;
|
||||
ut32 size_index;
|
||||
ut32 entries;
|
||||
ut32 deleted_entries;
|
||||
} RHashTable;
|
||||
|
||||
typedef struct r_hashtable64_entry_t {
|
||||
ut64 hash;
|
||||
void *data;
|
||||
} RHashTable64Entry;
|
||||
|
||||
typedef struct r_hashtable64_t {
|
||||
RHashTable64Entry *table;
|
||||
ut64 size;
|
||||
ut64 rehash;
|
||||
ut64 max_entries;
|
||||
ut64 size_index;
|
||||
ut64 entries;
|
||||
ut64 deleted_entries;
|
||||
} RHashTable64;
|
||||
#include "ht.h"
|
||||
|
||||
/* r_mixed */
|
||||
|
||||
|
@ -536,24 +507,11 @@ R_API int r_big_divisible_ut(RNumBig *n, ut32 v);
|
|||
R_API void r_big_mod(RNumBig *c, RNumBig *a, RNumBig *b);
|
||||
#endif
|
||||
|
||||
R_API RHashTable* r_hashtable_new(void);
|
||||
R_API void r_hashtable_free(RHashTable *ht);
|
||||
R_API void *r_hashtable_lookup(RHashTable *ht, ut32 hash);
|
||||
R_API boolt r_hashtable_insert(RHashTable *ht, ut32 hash, void *data);
|
||||
R_API void r_hashtable_remove(RHashTable *ht, ut32 hash);
|
||||
|
||||
R_API RHashTable64* r_hashtable64_new(void);
|
||||
R_API void r_hashtable64_free(RHashTable64 *ht);
|
||||
R_API void *r_hashtable64_lookup(RHashTable64 *ht, ut64 hash);
|
||||
R_API boolt r_hashtable64_insert(RHashTable64 *ht, ut64 hash, void *data);
|
||||
R_API void r_hashtable64_remove(RHashTable64 *ht, ut64 hash);
|
||||
|
||||
/* uleb */
|
||||
R_API const ut8 *r_uleb128 (const ut8 *data, ut32 *v);
|
||||
R_API const ut8 *r_leb128 (const ut8 *data, st32 *v);
|
||||
#endif
|
||||
|
||||
|
||||
/* constr */
|
||||
typedef struct r_constr_t {
|
||||
char *b;
|
||||
|
@ -597,4 +555,17 @@ R_API char *r_strpool_next(RStrpool *p, int index);
|
|||
R_API char *r_strpool_slice (RStrpool *p, int index);
|
||||
R_API char *r_strpool_empty (RStrpool *p);
|
||||
|
||||
typedef struct r_strht_t {
|
||||
RStrpool *sp;
|
||||
RHashTable *ht;
|
||||
RList *ls;
|
||||
} RStrHT;
|
||||
|
||||
R_API RStrHT *r_strht_new();
|
||||
R_API void r_strht_free(RStrHT *s);
|
||||
R_API const char *r_strht_get(RStrHT *s, const char *key);
|
||||
R_API int r_strht_set(RStrHT *s, const char *key, const char *val);
|
||||
R_API void r_strht_clear(RStrHT *s);
|
||||
R_API void r_strht_del(RStrHT *s, const char *key);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
include ../config.mk
|
||||
|
||||
NAME=r_print
|
||||
DEPS=r_cons r_util r_asm r_anal
|
||||
OBJS=print.o format.o date.o disasm.o seven.o
|
||||
|
||||
include ../rules.mk
|
|
@ -1,13 +0,0 @@
|
|||
include ../../config.mk
|
||||
|
||||
all: hex fmt
|
||||
|
||||
BINS=fmt${EXT_EXE}
|
||||
BIN=hex
|
||||
OBJ=hex.o
|
||||
BINDEPS=r_cons r_print r_util
|
||||
|
||||
myclean:
|
||||
rm -f fmt fmt.o
|
||||
|
||||
include ../../rules.mk
|
|
@ -1,18 +0,0 @@
|
|||
#include "r_cons.h"
|
||||
#include "r_print.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
struct r_print_t *p;
|
||||
const ut8 buf[] = "1234578901234567890";
|
||||
|
||||
p = r_print_new();
|
||||
p->printf = (void*)r_cons_printf;
|
||||
r_cons_new();
|
||||
r_print_format(p, 0LL, buf, 10, "xxd foo bar cow");
|
||||
r_print_format(p, 0LL, buf, 10, "xxd");
|
||||
r_cons_flush();
|
||||
r_print_free(p);
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -1,15 +0,0 @@
|
|||
#include "r_cons.h"
|
||||
#include "r_print.h"
|
||||
|
||||
int main()
|
||||
{
|
||||
struct r_print_t *p;
|
||||
ut8 *buf = (ut8*)main;
|
||||
|
||||
r_cons_new();
|
||||
p = r_print_new();
|
||||
r_print_hexdump(p, (ut64)(size_t)(main), buf, 128, 16, 1);
|
||||
r_cons_flush();
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -7,7 +7,8 @@ OBJS=mem.o pool.o num.o str.o hex.o file.o alloca.o range.o log.o
|
|||
OBJS+=prof.o cache.o sys.o buf.o w32-sys.o base64.o base85.o name.o
|
||||
OBJS+=list.o flist.o ht.o ht64.o mixed.o btree.o chmod.o graph.o
|
||||
OBJS+=regex/regcomp.o regex/regerror.o regex/regexec.o uleb128.o
|
||||
OBJS+=sandbox.o calc.o thread.o lock.o strpool.o bitmap.o
|
||||
OBJS+=sandbox.o calc.o thread.o lock.o strpool.o bitmap.o strht.o
|
||||
OBJS+= p_date.o p_disasm.o p_format.o p_print.o p_seven.o
|
||||
|
||||
# DO NOT BUILD r_big api (not yet used and its buggy)
|
||||
ifeq (1,0)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2010-2012 pancake <@nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2010-2013 - pancake */
|
||||
|
||||
int r_flist_iterator(void **x) {
|
||||
return *x!=0;
|
||||
|
@ -24,7 +24,6 @@ void** r_flist_get(void **x) {
|
|||
#define r_flist_unref(x) x
|
||||
#endif
|
||||
|
||||
|
||||
R_API void **r_flist_new(int n) {
|
||||
void **it;
|
||||
if (!(it = (void **)malloc ((n+2) * sizeof (void*))))
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
/* radare - LGPL - Copyright 2007-2012 pancake<nopcode.org> */
|
||||
/* radare - LGPL - Copyright 2007-2013 - pancake */
|
||||
|
||||
#include "r_cons.h"
|
||||
#include "r_util.h"
|
||||
|
@ -6,9 +6,14 @@
|
|||
|
||||
static void print_format_help(RPrint *p) {
|
||||
p->printf (
|
||||
"Usage: pf [times][format] [arg0 arg1]\n"
|
||||
"Example: pf 10xiz pointer length string\n"
|
||||
"Example: pf {array_size}b @ array_base\n"
|
||||
"Usage: pf[$key[ val]]|[times][format] [arg0 arg1]\n"
|
||||
"Examples:\n"
|
||||
" pf 10xiz pointer length string\n"
|
||||
" pf {array_size}b @ array_base\n"
|
||||
" pf$ # list all formats\n"
|
||||
" pf$obj xxdz prev next size name\n"
|
||||
" pf$obj # run stored format\n"
|
||||
"Format chars:\n"
|
||||
" e - temporally swap endian\n"
|
||||
//" D - double (8 bytes)\n"
|
||||
" f - float value\n"
|
||||
|
@ -23,7 +28,8 @@ static void print_format_help(RPrint *p) {
|
|||
" x - 0x%%08x hexadecimal value and flag (fd @ addr)\n"
|
||||
" z - \\0 terminated string\n"
|
||||
" Z - \\0 terminated wide string\n"
|
||||
" s - pointer to string\n"
|
||||
" s - 32bit pointer to string\n"
|
||||
" S - 64bit pointer to string\n"
|
||||
" t - unix timestamp string\n"
|
||||
" * - next char is pointer\n"
|
||||
" + - toggle show flags for each offset\n"
|
||||
|
@ -31,7 +37,7 @@ static void print_format_help(RPrint *p) {
|
|||
}
|
||||
|
||||
/* TODO: needs refactoring */
|
||||
R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const char *fmt) {
|
||||
R_API int r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const char *fmt) {
|
||||
ut8 buffer[256];
|
||||
int nargs, i, j, idx, times, otimes, endian;
|
||||
char *args, *bracket, tmp, last = 0;
|
||||
|
@ -52,7 +58,7 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
|
|||
char *end = strchr (arg,'}');
|
||||
if (end == NULL) {
|
||||
eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
*end='\0';
|
||||
times = r_num_math (NULL, bracket+1);
|
||||
|
@ -61,7 +67,7 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
|
|||
|
||||
if (*arg=='\0') {
|
||||
print_format_help (p);
|
||||
return;
|
||||
return 0;
|
||||
}
|
||||
/* get args */
|
||||
args = strchr (arg, ' ');
|
||||
|
@ -98,7 +104,7 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
|
|||
if (endian)
|
||||
addr64 = (ut64)(*(buf+i))<<56 | (ut64)(*(buf+i+1))<<48 | (ut64)*(buf+i+2)<<40 | (ut64)(*(buf+i+3))<<32
|
||||
| (*(buf+i+4))<<24 | (*(buf+i+5))<<16 | *(buf+i+6)<<8 | *(buf+i+7);
|
||||
else addr64 = ((ut64)(*(buf+i+7)))<<56 | (ut64)(*(buf+i+6))<<48 | (ut64)(*(buf+i+5))<<40 | (ut64)(*(buf+i+4))<<32
|
||||
else addr64 = ((ut64)(*(buf+i+7)))<<56 | (ut64)(*(buf+i+6))<<48 | (ut64)(*(buf+i+5))<<40 | (ut64)(*(buf+i+4))<<32
|
||||
| (*(buf+i+3))<<24 | (*(buf+i+2))<<16 | *(buf+i+1)<<8 | *(buf+i);
|
||||
tmp = *arg;
|
||||
feed_me_again:
|
||||
|
@ -251,15 +257,32 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
|
|||
p->printf ("0x%08"PFMT64x" = ", seeki);
|
||||
memset (buffer, '\0', 255);
|
||||
if (p->iob.read_at) {
|
||||
p->iob.read_at (p->iob.io, (ut64)addr, buffer, 248);
|
||||
p->iob.read_at (p->iob.io, (ut64)addr,
|
||||
buffer, sizeof (buffer)-8);
|
||||
} else {
|
||||
printf ("(cannot read memory)\n");
|
||||
break;
|
||||
}
|
||||
p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ", seeki, addr);
|
||||
p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ",
|
||||
seeki, addr);
|
||||
p->printf ("%s ", buffer);
|
||||
i += 4;
|
||||
break;
|
||||
case 'S':
|
||||
p->printf ("0x%08"PFMT64x" = ", seeki);
|
||||
memset (buffer, '\0', 255);
|
||||
if (p->iob.read_at) {
|
||||
p->iob.read_at (p->iob.io, addr64,
|
||||
buffer, sizeof (buffer)-8);
|
||||
} else {
|
||||
printf ("(cannot read memory)\n");
|
||||
break;
|
||||
}
|
||||
p->printf ("0x%08"PFMT64x" -> 0x%08"PFMT64x" ",
|
||||
seeki, addr);
|
||||
p->printf ("%s ", buffer);
|
||||
i += 8;
|
||||
break;
|
||||
default:
|
||||
/* ignore unknown chars */
|
||||
break;
|
||||
|
@ -279,4 +302,5 @@ R_API void r_print_format(RPrint *p, ut64 seek, const ut8* buf, int len, const c
|
|||
idx = 0;
|
||||
}
|
||||
// free((void *)&args);
|
||||
return i;
|
||||
}
|
|
@ -1,9 +1,26 @@
|
|||
/* radare - LGPL - Copyright 2007-2012 - pancake */
|
||||
/* radare - LGPL - Copyright 2007-2013 - pancake */
|
||||
|
||||
#include "r_cons.h"
|
||||
#include "r_print.h"
|
||||
#include "r_util.h"
|
||||
|
||||
static int nullprinter(const char* a, ...) { return 0; }
|
||||
|
||||
R_API int r_print_mute(RPrint *p, int x) {
|
||||
if (x) {
|
||||
if (p->printf == &nullprinter)
|
||||
return 0;
|
||||
p->oprintf = p->printf;
|
||||
p->printf = nullprinter;
|
||||
return 1;
|
||||
}
|
||||
if (p->printf == nullprinter) {
|
||||
p->printf = p->oprintf;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
R_API RPrint *r_print_new() {
|
||||
RPrint *p = R_NEW (RPrint);
|
||||
if (!p) return NULL;
|
||||
|
@ -11,6 +28,7 @@ R_API RPrint *r_print_new() {
|
|||
p->user = NULL;
|
||||
r_io_bind_init (p->iob);
|
||||
p->printf = printf;
|
||||
p->oprintf = nullprinter;
|
||||
p->interrupt = 0;
|
||||
p->bigendian = 0;
|
||||
p->col = 0;
|
||||
|
@ -18,6 +36,7 @@ R_API RPrint *r_print_new() {
|
|||
p->cols = 16;
|
||||
p->cur_enabled = R_FALSE;
|
||||
p->cur = p->ocur = -1;
|
||||
p->formats = r_strht_new ();
|
||||
p->addrmod = 4;
|
||||
p->flags = \
|
||||
R_PRINT_FLAGS_COLOR |
|
||||
|
@ -29,6 +48,8 @@ R_API RPrint *r_print_new() {
|
|||
|
||||
R_API RPrint *r_print_free(RPrint *p) {
|
||||
if (!p) return NULL;
|
||||
r_strht_free (p->formats);
|
||||
p->formats = NULL;
|
||||
if (p->zoom) {
|
||||
free (p->zoom->buf);
|
||||
free (p->zoom);
|
||||
|
@ -62,10 +83,10 @@ R_API void r_print_cursor(RPrint *p, int cur, int set) {
|
|||
int to = p->cur;
|
||||
r_num_minmax_swap_i (&from, &to);
|
||||
if (cur>=from && cur<=to)
|
||||
r_cons_invert (set, 1); //p->flags&R_PRINT_FLAGS_COLOR);
|
||||
p->printf ("%s", R_CONS_INVERT (set, 1)); //r_cons_invert (set, 1); //p->flags&R_PRINT_FLAGS_COLOR);
|
||||
} else
|
||||
if (cur==p->cur)
|
||||
r_cons_invert (set, 1); //p->flags & R_PRINT_FLAGS_COLOR);
|
||||
p->printf ("%s", R_CONS_INVERT (set, 1)); //r_cons_invert (set, 1); //p->flags&R_PRINT_FLAGS_COLOR);
|
||||
}
|
||||
|
||||
R_API void r_print_addr(RPrint *p, ut64 addr) {
|
||||
|
@ -83,7 +104,7 @@ R_API void r_print_addr(RPrint *p, ut64 addr) {
|
|||
r_cons_singleton ()->palette[PAL_ADDRESS], addr, ch);
|
||||
#endif
|
||||
p->printf ("0x%08"PFMT64x"%c", addr, ch);
|
||||
} else r_cons_printf ("0x%08"PFMT64x"%c", addr, ch);
|
||||
} else p->printf ("0x%08"PFMT64x"%c", addr, ch);
|
||||
}
|
||||
|
||||
#define CURDBG 0
|
||||
|
@ -475,8 +496,7 @@ R_API void r_print_bytes(RPrint *p, const ut8* buf, int len, const char *fmt) {
|
|||
}
|
||||
|
||||
R_API void r_print_raw(RPrint *p, const ut8* buf, int len) {
|
||||
// TODO independize from cons
|
||||
r_cons_memcat ((char *)buf, len);
|
||||
p->write (buf, len);
|
||||
}
|
||||
|
||||
R_API void r_print_c(RPrint *p, const ut8 *str, int len) {
|
116
libr/util/str.c
116
libr/util/str.c
|
@ -972,3 +972,119 @@ R_API char *r_str_uri_encode (const char *s) {
|
|||
*d = 0;
|
||||
return realloc (o, strlen (d)+1); // FIT
|
||||
}
|
||||
|
||||
// TODO: merge print inside rutil
|
||||
/* hack from print */
|
||||
R_API int r_print_format_length (const char *fmt) {
|
||||
int nargs, i, j, idx, times, otimes, endian;
|
||||
char *args, *bracket, tmp, last = 0;
|
||||
const char *arg = fmt;
|
||||
const char *argend = arg+strlen (fmt);
|
||||
char namefmt[8];
|
||||
int viewflags = 0;
|
||||
nargs = endian = i = j = 0;
|
||||
|
||||
while (*arg && iswhitechar (*arg)) arg++;
|
||||
/* get times */
|
||||
otimes = times = atoi (arg);
|
||||
if (times > 0)
|
||||
while ((*arg>='0'&&*arg<='9')) arg++;
|
||||
bracket = strchr (arg,'{');
|
||||
if (bracket) {
|
||||
char *end = strchr (arg,'}');
|
||||
if (end == NULL) {
|
||||
eprintf ("No end bracket. Try pm {ecx}b @ esi\n");
|
||||
return 0;
|
||||
}
|
||||
*end='\0';
|
||||
times = r_num_math (NULL, bracket+1);
|
||||
arg = end + 1;
|
||||
}
|
||||
|
||||
if (*arg=='\0')
|
||||
return 0;
|
||||
|
||||
/* get args */
|
||||
args = strchr (arg, ' ');
|
||||
if (args) {
|
||||
int l=0, maxl = 0;
|
||||
argend = args;
|
||||
args = strdup (args+1);
|
||||
nargs = r_str_word_set0 (args+1);
|
||||
if (nargs == 0)
|
||||
R_FREE (args);
|
||||
for (i=0; i<nargs; i++) {
|
||||
int len = strlen (r_str_word_get0 (args+1, i));
|
||||
if (len>maxl) maxl = len;
|
||||
}
|
||||
l++;
|
||||
snprintf (namefmt, sizeof (namefmt), "%%%ds : ", maxl);
|
||||
}
|
||||
|
||||
/* go format */
|
||||
i = 0;
|
||||
if (!times) otimes = times = 1;
|
||||
for (; times; times--) { // repeat N times
|
||||
const char * orig = arg;
|
||||
idx = 0;
|
||||
arg = orig;
|
||||
for (idx=0; arg<argend && *arg; idx++, arg++) {
|
||||
tmp = *arg;
|
||||
feed_me_again:
|
||||
if (tmp == 0 && last != '*')
|
||||
break;
|
||||
/* skip chars */
|
||||
switch (tmp) {
|
||||
case '*':
|
||||
if (i<=0) break;
|
||||
tmp = last;
|
||||
arg--;
|
||||
idx--;
|
||||
goto feed_me_again;
|
||||
case '+':
|
||||
idx--;
|
||||
viewflags = !viewflags;
|
||||
continue;
|
||||
case 'e': // tmp swap endian
|
||||
idx--;
|
||||
endian ^= 1;
|
||||
continue;
|
||||
case '.': // skip char
|
||||
i++;
|
||||
idx--;
|
||||
continue;
|
||||
case 'p':
|
||||
tmp = (sizeof (void*)==8)? 'q': 'x';
|
||||
break;
|
||||
case '?': // help
|
||||
idx--;
|
||||
return 0;
|
||||
}
|
||||
switch (tmp) {
|
||||
case 'e': i += 8; break;
|
||||
case 'q': i += 8; break;
|
||||
case 'b': i++; break;
|
||||
case 'c': i++; break;
|
||||
case 'B': i += 4; break;
|
||||
case 'i': i += 4; break;
|
||||
case 'd': i += 4; break;
|
||||
case 'x': i += 4; break;
|
||||
case 'w':
|
||||
case '1': i+=2; break;
|
||||
case 'z': // XXX unsupported
|
||||
case 'Z': // zero terminated wide string
|
||||
break;
|
||||
case 's': i += 4; break; // S for 8?
|
||||
case 'S': i += 8; break; // S for 8?
|
||||
default:
|
||||
/* ignore unknown chars */
|
||||
break;
|
||||
}
|
||||
last = tmp;
|
||||
}
|
||||
arg = orig;
|
||||
idx = 0;
|
||||
}
|
||||
// free((void *)&args);
|
||||
return i;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,76 @@
|
|||
/* radare - LGPL - Copyright 2013 - pancake */
|
||||
|
||||
#include <r_util.h>
|
||||
|
||||
static void r_strht_init(RStrHT *s) {
|
||||
s->ht = r_hashtable_new ();
|
||||
s->sp = r_strpool_new (0);
|
||||
s->ls = r_list_new ();
|
||||
}
|
||||
|
||||
static void r_strht_fini(RStrHT *s) {
|
||||
r_hashtable_free (s->ht);
|
||||
r_strpool_free (s->sp);
|
||||
r_list_free (s->ls);
|
||||
}
|
||||
|
||||
R_API RStrHT *r_strht_new() {
|
||||
RStrHT *s = R_NEW0 (RStrHT);
|
||||
r_strht_init (s);
|
||||
return s;
|
||||
}
|
||||
|
||||
R_API void r_strht_free(RStrHT *s) {
|
||||
r_strht_fini (s);
|
||||
free (s);
|
||||
}
|
||||
|
||||
R_API void r_strht_del(RStrHT *s, const char *key) {
|
||||
int i, *_i;
|
||||
const char *k;
|
||||
RListIter *iter;
|
||||
ut32 h = r_str_hash (key);
|
||||
r_hashtable_remove (s->ht, h);
|
||||
r_list_foreach (s->ls, iter, _i) {
|
||||
i = (int)(size_t)_i;
|
||||
k = r_strpool_get (s->sp, i);
|
||||
if (!strcmp (key, k)) {
|
||||
r_list_delete (s->ls, iter);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
R_API const char *r_strht_get(RStrHT *s, const char *key) {
|
||||
ut32 h = r_str_hash (key);
|
||||
int p = (int)(size_t)r_hashtable_lookup (s->ht, h);
|
||||
if (p) return r_strpool_get (s->sp, p-1);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
R_API int r_strht_set(RStrHT *s, const char *key, const char *val) {
|
||||
ut32 h = r_str_hash (key);
|
||||
int v, p = (int)(size_t) r_hashtable_lookup (s->ht, h);
|
||||
if (!p) {
|
||||
int k = r_strpool_append (s->sp, key);
|
||||
r_list_append (s->ls, (void*)(size_t)k+1);
|
||||
}
|
||||
r_hashtable_remove (s->ht, h);
|
||||
v = r_strpool_append (s->sp, val);
|
||||
r_hashtable_insert (s->ht, h, (void*)(size_t)v+1);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
R_API void r_strht_clear(RStrHT *s) {
|
||||
r_strht_fini (s);
|
||||
r_strht_init (s);
|
||||
}
|
||||
|
||||
#if MAIN
|
||||
main() {
|
||||
RStrHT *h = r_strht_new ();
|
||||
r_strht_set (h, "foo", "hello world");
|
||||
printf ("%s\n", r_strht_get (h, "foo"));
|
||||
r_strht_free (h);
|
||||
}
|
||||
#endif
|
|
@ -1,6 +1,6 @@
|
|||
{
|
||||
"name": "radare2.js",
|
||||
"version": "0.1.3",
|
||||
"version": "0.1.5",
|
||||
"url": "http://www.radare.org",
|
||||
"description": "radare2 valabind-ffi bindings for nodejs",
|
||||
"dependencies": {
|
||||
|
|
Loading…
Reference in New Issue