Improve code, add cfg.charset, use pse, add test ##print

This commit is contained in:
pancake 2020-12-13 10:21:46 +01:00 committed by pancake
parent f16168fa36
commit cb33fdb420
19 changed files with 214 additions and 212 deletions

View File

@ -14,7 +14,7 @@ BUILDSEC=$(shell date -u -d "@$(SOURCE_DATE_EPOCH)" "+__%H:%M:%S" 2>/dev/null ||
else
BUILDSEC=$(shell date "+__%H:%M:%S")
endif
DATADIRS=libr/cons/d libr/flag/d libr/bin/d libr/asm/d libr/syscall/d libr/magic/d libr/anal/d
DATADIRS=libr/cons/d libr/flag/d libr/bin/d libr/asm/d libr/syscall/d libr/magic/d libr/anal/d libr/util/d
USE_ZIP=YES
ZIP=zip

View File

@ -137,7 +137,6 @@ R_API RAnal *r_anal_new(void) {
r_anal_add (anal, anal_static_plugins[i]);
}
}
anal->charset_db = sdb_ns (anal->sdb, "charset", 1);
return anal;
}

View File

@ -1,6 +1,7 @@
/* radare - LGPL - Copyright 2009-2020 - pancake */
#include <r_core.h>
#include <r_types_base.h>
#define NODECB(w,x,y) r_config_set_cb (cfg,w,x,y)
#define NODEICB(w,x,y) r_config_set_i_cb (cfg,w,x,y)
@ -1194,6 +1195,48 @@ static bool cb_bigendian(void *user, void *data) {
return true;
}
static void list_available_plugins(const char *path) {
RListIter *iter;
const char *fn;
RList *files = r_sys_dir (path);
r_list_foreach (files, iter, fn) {
if (*fn && *fn != '.' && r_str_endswith (fn, ".sdb")) {
char *f = strdup (fn);
f[strlen (f) - 4] = 0;
r_cons_println (f);
free (f);
}
}
r_list_free (files);
}
static bool cb_cfgcharset(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
const char *cf = r_str_trim_head_ro (node->value);
if (!*cf) {
return false;
}
const char *cs = R2_PREFIX R_SYS_DIR R2_SDB R_SYS_DIR "charsets" R_SYS_DIR;
bool rc = true;
if (*cf == '?') {
list_available_plugins (cs);
} else {
char *syscs = r_str_newf ("%s%s.sdb", cs, cf);
if (r_file_exists (syscs)) {
rc = r_charset_open (core->charset, syscs);
} else {
rc = r_charset_open (core->charset, cf);
}
if (!rc) {
eprintf ("Warning: Cannot load charset file '%s' '%s'.\n", syscs, cf);
}
free (syscs);
}
return rc;
}
static bool cb_cfgdatefmt(void *user, void *data) {
RCore *core = (RCore*) user;
RConfigNode *node = (RConfigNode*) data;
@ -3296,6 +3339,7 @@ R_API int r_core_config_init(RCore *core) {
SETBPREF ("prj.simple", "false", "Use simple project saving style (functions, comments, options)");
/* cfg */
SETCB ("cfg.charset", "", &cb_cfgcharset, "Specify encoding to use in pse");
SETBPREF ("cfg.r2wars", "false", "Enable some tweaks for the r2wars game");
SETBPREF ("cfg.plugins", "true", "Load plugins at startup");
SETCB ("time.fmt", "%Y-%m-%d %H:%M:%S %z", &cb_cfgdatefmt, "Date format (%Y-%m-%d %H:%M:%S %z)");

View File

@ -1816,11 +1816,13 @@ static int cmd_kuery(void *data, const char *input) {
break;
case ' ':
out = sdb_querys (s, NULL, 0, input + 1);
if (out) {
r_cons_print (out);
if (s) {
out = sdb_querys (s, NULL, 0, input + 1);
if (out) {
r_cons_print (out);
}
R_FREE (out);
}
free (out);
break;
//case 's': r_pair_save (s, input + 3); break;
//case 'l': r_pair_load (sdb, input + 3); break;

View File

@ -3349,60 +3349,6 @@ cleanup:
return result;
}
static void list_avaible_plugins(char *path) {
RList *files;
RListIter *iter;
const char *fn;
if (path) {
files = r_sys_dir (path);
r_list_foreach (files, iter, fn) {
if (*fn && *fn != '.') {
r_cons_println (fn);
}
}
r_list_free (files);
free (path);
}
}
static void load_charset_plugin(RCore *core, char *charset_plugin_path) {
if (!sdb_query_file (core->anal->charset_db, charset_plugin_path)) {
eprintf ("Path: %s not found\n", charset_plugin_path);
}
SdbListIter *iter;
SdbKv *kv;
SdbList *sdbls = sdb_foreach_list (core->anal->charset_db, true);
size_t i = 0;
core->custom = r_charset_new ();
ls_foreach (sdbls, iter, kv) {
ut8 *buff_hex = (ut8 *) sdbkv_key (kv);
ut8 *buff_char = (ut8 *) sdbkv_value (kv);
ut64 mylonglong = r_num_get (NULL, (const char *)buff_hex);
ut8 *hex = (ut8 *) ut64_new (mylonglong);
core->custom->custom_charset = add_rune (core->custom->custom_charset, buff_char, hex);
i++;
}
ls_free (sdbls);
}
static bool cmd_pse(RCore *core, const char *input) {
char *path = r_str_r2_prefix (R_JOIN_2_PATHS (R2_SDB, "util"));
char *plugin_folder = r_str_newf (R_JOIN_2_PATHS ("%s", "d"), path);
const char *plugin_file = r_str_trim_head_ro (input + 3);
char *plugin_file_path = r_str_newf (R_JOIN_2_PATHS ("%s", "%s"), plugin_folder, plugin_file);
if (input[2] == ' ') {
load_charset_plugin (core, plugin_file_path);
} else {
list_avaible_plugins (plugin_folder);
}
return true;
}
static bool checkAnalType(RAnalOp *op, int t) {
if (t == 'c') {
switch (op->type) {
@ -5886,22 +5832,23 @@ l = use_blocksize;
}
}
break;
case 't': // "pst"
if (len > 0) {
ut8 *var = malloc (len);
if (!var) {
eprintf ("Error: failed to malloc memory");
break;
}
r_charset_encode_str (var, core->block, len, core->custom);
r_print_string (core->print, core->offset, var, len, R_PRINT_STRING_ZEROEND);
free (var);
}
break;
case 'e': // "pse"
cmd_pse (core, input);
// should be done in `ps` when cfg.charset is set
if (len > 0) {
size_t out_len = len * 10;
ut8 *out = calloc (len, 10);
if (out) {
ut8 *data = calloc (1, len);
if (data) {
r_io_read_at (core->io, core->offset, data, len);
r_charset_encode_str (core->charset, out, out_len, data, len);
r_print_string (core->print, core->offset,
out, len, R_PRINT_STRING_ZEROEND);
free (data);
}
free (out);
}
}
break;
default:
if (l > 0) {

View File

@ -2710,6 +2710,8 @@ R_API bool r_core_init(RCore *core) {
core->printidx = 0;
core->lastcmd = NULL;
core->cmdlog = NULL;
core->charset = r_charset_new ();
core->charset->db = sdb_ns (core->sdb, "charset", 1);
core->stkcmd = NULL;
core->cmdqueue = NULL;
core->cmdrepeat = true;
@ -2897,6 +2899,7 @@ R_API void r_core_fini(RCore *c) {
if (!c) {
return;
}
r_charset_free (c->charset); // TODO. maybe move into RPrint?
r_core_task_break_all (&c->tasks);
r_core_task_join (&c->tasks, NULL, -1);
r_core_wait (c);

View File

@ -686,7 +686,6 @@ typedef struct r_anal_t {
SetU *visited;
RStrConstPool constpool;
RList *leaddrs;
Sdb *charset_db;
} RAnal;
typedef enum r_anal_addr_hint_type_t {

View File

@ -331,7 +331,7 @@ struct r_core_t {
bool log_events; // core.c:cb_event_handler : log actions from events if cfg.log.events is set
RList *ropchain;
bool use_tree_sitter_r2cmd;
RCharset *custom;
RCharset *charset;
bool marks_init;
ut64 marks[UT8_MAX + 1];

View File

@ -8,6 +8,7 @@
#include "r_util/r_str_util.h"
#include <r_userconf.h>
#include <stddef.h>
#include <stdlib.h>
#include <assert.h>
// TODO: fix this to make it crosscompile-friendly: R_SYS_OSTYPE ?
@ -71,6 +72,7 @@
#define R_PERM_ACCESS 32
#define R_PERM_CREAT 64
// HACK to fix capstone-android-mips build
#undef mips
#define mips mips

View File

@ -29,6 +29,7 @@ typedef struct r_charset_rune_t {
} RCharsetRune;
typedef struct r_charset_t {
Sdb *db;
RCharsetRune *custom_charset;
size_t remaining;
} RCharset;
@ -41,9 +42,13 @@ R_API RCharset *r_charset_new(void);
R_API void r_charset_free(RCharset *charset);
R_API RCharsetRune *r_charset_rune_new(const ut8 *ch, const ut8 *hx);
R_API void r_charset_rune_free(RCharsetRune *rcr);
R_API size_t r_charset_encode_str(RCharset *r_char, ut8 *out, size_t out_len, const ut8 *in, size_t len_input);
R_API bool r_charset_open(RCharset *c, const char *cs);
R_API RCharsetRune * add_rune(RCharsetRune *rcsr, const ut8 *ch, const ut8 *hx);
R_API RCharsetRune *search_from_hex(RCharsetRune *rcsr, const ut8 *hx);
R_API RCharsetRune *search_from_char(RCharsetRune *rcsr, const ut8 *ch);
// str
R_API char *r_str_repeat(const char *ch, int sz);
R_API const char *r_str_pad(const char ch, int len);
R_API const char *r_str_rstr(const char *base, const char *p);
@ -224,7 +229,6 @@ R_API const char *r_str_rsep(const char *base, const char *p, const char *sep);
R_API char *r_str_donut(int size);
R_API char *r_str_version(const char *program);
R_API size_t r_charset_encode_str(ut8 *asciistr, ut8 *in, size_t len_input, RCharset *r_char);
#ifdef __cplusplus
}
#endif

View File

@ -11,7 +11,7 @@ LINK=-lm
endif
endif
OBJS=binheap.o mem.o unum.o str.o hex.o file.o range.o
OBJS=binheap.o mem.o unum.o str.o hex.o file.o range.o charset.o
OBJS+=prof.o cache.o sys.o buf.o w32-sys.o ubase64.o base85.o base91.o
OBJS+=list.o flist.o chmod.o graph.o event.o alloc.o donut.o print_code.o
OBJS+=regex/regcomp.o regex/regerror.o regex/regexec.o uleb128.o
@ -37,13 +37,8 @@ endif
include deps.mk
SDBCHARSETPATH=$(DESTDIR)$(DATADIR)/radare2/$(VERSION)/util
CWD=$(shell pwd)
all:
mkdir -p "${SDBCHARSETPATH}/d"
${MAKE} -C "${CWD}/d"
LDFLAGS+=${BN_LIBS}
LDFLAGS+=${TH_LIBS}
LDFLAGS+=${DL_LIBS}
@ -72,12 +67,15 @@ ifeq (${BUILD_OS},haiku)
endif
EXTRA_PRE+=spp_config
EXTRA_PRE+=charsets
include ../rules.mk
include sdb.mk
include spp.mk
charsets:
$(MAKE) -C d
.PHONY: charsets
sync-regex regex-sync:
-rm -rf src/

91
libr/util/charset.c Normal file
View File

@ -0,0 +1,91 @@
/* radare - LGPL - Copyright 2020 - gogo, pancake */
#include <r_util.h>
#define USE_RUNES 0
R_API RCharset *r_charset_new(void) {
RCharset* c = R_NEW0 (RCharset);
if (!c) {
return NULL;
}
c->db = NULL; // must be set after calling new by the caller
return c;
}
R_API void r_charset_free(RCharset *c) {
sdb_free (c->db);
free (c);
}
R_API bool r_charset_open(RCharset *c, const char *cs) {
r_return_val_if_fail (c && cs, false);
sdb_reset (c->db);
sdb_open (c->db, cs);
return true;
}
// rune
R_API RCharsetRune *r_charset_rune_new(const ut8 *ch, const ut8 *hx) {
RCharsetRune* c = R_NEW0 (RCharsetRune);
if (!c) {
return NULL;
}
c->ch = (ut8 *) strdup ((char *) ch);
c->hx = (ut8 *) strdup ((char *) hx);
c->left = NULL;
c->right = NULL;
return c;
}
R_API void r_charset_rune_free(RCharsetRune *c) {
free (c->ch);
free (c->hx);
free (c);
}
R_API RCharsetRune *add_rune(RCharsetRune *r, const ut8 *ch, const ut8 *hx) {
if (!r) {
r = r_charset_rune_new (ch, hx);
}
int cmp = strcmp ((char *)hx, (char *)r->hx);
if (cmp < 0) {
r->left = add_rune (r->left, ch, hx);
} else if (cmp > 0) {
r->right = add_rune (r->right, ch, hx);
} else {
int cmp = strcmp ((char *)ch, (char *)r->ch);
if (cmp > 0) {
r->left = add_rune (r->left, ch, hx);
} else if (cmp < 0) {
r->right = add_rune (r->right, ch, hx);
}
}
return r;
}
R_API RCharsetRune *search_from_hex(RCharsetRune *r, const ut8 *hx) {
if (!r) {
return NULL;
}
if (!strcmp ((char *)r->hx, (char *)hx)) {
return r;
}
RCharsetRune *left = search_from_hex (r->left, hx);
return left? left: search_from_hex (r->right, hx);
}
// assumes out is as big as in_len
R_API size_t r_charset_encode_str(RCharset *rc, ut8 *out, size_t out_len, const ut8 *in, size_t in_len) {
char k[32];
char *o = (char*)out;
int i;
for (i = 0; i < in_len; i++) {
ut8 ch_in = in[i];
snprintf (k, sizeof (k), "0x%02x", ch_in);
const char *v = sdb_const_get (rc->db, k, 0);
strcpy (o, v?v:"?");
o += strlen (o);
}
return o - (char*)out;
}

View File

@ -1,27 +1,29 @@
FILES=pokered
F_SDB=$(addsuffix .sdb,$(FILES))
SDB=../../../shlr/sdb/sdb
include ../../../config-user.mk
include ../../../global.mk
SDBCHARSETPATH=$(DESTDIR)$(DATADIR)/radare2/$(VERSION)/util
R2_CHARSETS_PATH=$(DESTDIR)$(DATADIR)/radare2/$(VERSION)/charsets
CWD=$(shell pwd)
all:
for FILE in * ; do \
if [ "$$FILE" != Makefile && "$$FILE" != meson.build ]; then \
cp "${CWD}/$$FILE" "${SDBCHARSETPATH}/d/$$FILE" ; \
fi ; \
done
alle: $(F_SDB)
%.sdb: %.sdb.txt
${SDB} $@ = < $<
test -f $@
install:
for FILE in * ; do \
if [ "$$FILE" != Makefile && "$$FILE" != meson.build ]; then \
cp "${CWD}/$$FILE" "${SDBCHARSETPATH}/d/$$FILE" ; \
fi ; \
mkdir -p "$(R2_CHARSETS_PATH)"
for FILE in *.sdb ; do \
cp "${CWD}/$$FILE" "${R2_CHARSETS_PATH}/$$FILE" ; \
done
symstall install-symlink:
for FILE in * ; do \
if [ "$$FILE" != Makefile && "$$FILE" != meson.build ]; then \
cp "${CWD}/$$FILE" "${SDBCHARSETPATH}/d/$$FILE" ; \
fi ; \
mkdir -p "$(R2_CHARSETS_PATH)"
for FILE in *.sdb ; do \
ln -fs "${CWD}/$$FILE" "${R2_CHARSETS_PATH}/$$FILE" ; \
done
.PHONY: all install symstall
.PHONY: all install symstall

1
libr/util/d/deps.mk Normal file
View File

@ -0,0 +1 @@
R2_CHARSETS_PATH=$(DESTDIR)$(DATADIR)/radare2/$(VERSION)/charsets

View File

@ -12,6 +12,6 @@ foreach file : sdb_files
depends: sdb_exe,
build_by_default: true,
install: true,
install_dir: join_paths(r2_sdb, 'util', 'd')
install_dir: join_paths(r2_sdb, 'charsets')
)
endforeach
endforeach

View File

@ -4,6 +4,7 @@ r_util_sources = [
'ascii_table.c',
'assert.c',
'alloc.c',
'charset.c',
'donut.c',
'table.c',
'getopt.c',

View File

@ -11,72 +11,6 @@
#include <stdarg.h>
#include <r_util/r_base64.h>
R_API RCharset *r_charset_new(void) {
RCharset* rcs = R_NEW0 (RCharset);
if (!rcs) {
return NULL;
}
rcs->custom_charset = NULL;
rcs->remaining = 0;
return rcs;
}
R_API void r_charset_free(RCharset *charset) {
r_charset_rune_free (charset->custom_charset);
free (charset);
}
R_API RCharsetRune *r_charset_rune_new(const ut8 *ch, const ut8 *hx) {
RCharsetRune* rcr = R_NEW0 (RCharsetRune);
if (!rcr) {
return NULL;
}
rcr->ch = (ut8 *) strdup ((char *) ch);
rcr->hx = (ut8 *) strdup ((char *) hx);
rcr->left = NULL;
rcr->right = NULL;
return rcr;
}
R_API void r_charset_rune_free(RCharsetRune *rcr) {
free (rcr->ch);
free (rcr->hx);
free (rcr);
}
R_API RCharsetRune *add_rune(RCharsetRune *rcsr, const ut8 *ch, const ut8 *hx) {
if (rcsr == NULL) {
rcsr = r_charset_rune_new (ch, hx);
}
if (strcmp ((char *)hx, (char *)rcsr->hx) < 0) {
rcsr->left = add_rune (rcsr->left, ch, hx);
} else if (strcmp ((char *)hx, (char *)rcsr->hx) > 0) {
rcsr->right = add_rune (rcsr->right, ch, hx);
} else {
if(strcmp ((char *)ch, (char *)rcsr->ch) > 0) {
rcsr->left = add_rune (rcsr->left, ch, hx);
} else if(strcmp ((char *)ch, (char *)rcsr->ch) < 0) {
rcsr->right = add_rune (rcsr->right, ch, hx);
}
}
return rcsr;
}
R_API RCharsetRune *search_from_hex(RCharsetRune *rcsr, const ut8 *hx) {
if (!rcsr) {
return NULL;
}
else if ( !strcmp ((char *)rcsr->hx, (char *)hx) ) {
return rcsr;
}
else {
RCharsetRune *left = search_from_hex(rcsr->left, hx);
return left? left: search_from_hex(rcsr->right, hx);
}
}
/* stable code */
static const char *nullstr = "";
static const char *nullstr_c = "(null)";
@ -3792,47 +3726,6 @@ R_API const char *r_str_str_xy(const char *s, const char *word, const char *prev
return d;
}
R_API size_t r_charset_encode_str(ut8 *asciistr, ut8 *in, size_t len_input, RCharset *r_char) {
bool is_in_set = false;
size_t j, k, l;
size_t current_ascii = 0;
ut8 * buff_hex = (ut8 *) malloc (len_input);
if (!buff_hex) {
return -1;
}
for (j = 0; j < len_input; j ++) {
is_in_set = true;
buff_hex[0] = in[j];
buff_hex[1] = '\0';
for (k = 0; !search_from_hex (r_char->custom_charset, buff_hex) && k < (len_input - j); k ++) {
buff_hex[k] = in[j+k];
if (k >= (len_input - j) - 1) {
is_in_set = false;
}
}
buff_hex[k+1] = '\0';
if (!is_in_set) {
break;
}
ut8 * tmp = search_from_hex (r_char->custom_charset, buff_hex)->ch;
if (!tmp) {
return -1;
}
for (l = 0; l < strlen ( (char *) tmp); l ++) {
asciistr[current_ascii] = tmp[l];
current_ascii ++;
}
}
asciistr[current_ascii] = '\0';
free (buff_hex);
return j;
}
// version.c
#include <r_userconf.h>

17
test/db/cmd/charset Normal file
View File

@ -0,0 +1,17 @@
NAME=pse
FILE=-
CMDS=<<EOF
e cfg.charset=?
b 32
wx a6b1aeb4ada37fb3ae7fafb1aeb3a4a2b349a8b3b2a4aba57fa5b1aeac7fa8b3
pse
e cfg.charset=pokered
pse
EOF
EXPECT=<<EOF
pokered
????????????????????????????????
ground-to-protect?itself-from-it
EOF
RUN

View File

@ -2692,8 +2692,7 @@ EXPECT=<<EOF
"stdcall=cc",
"watcom=cc",
"zigns",
"classes",
"charset"
"classes"
]
}
}