radare2/libr/core/vmenus_zigns.c

180 lines
3.8 KiB
C

/* radare - LGPL - Copyright 2019 - pancake */
#include <r_core.h>
typedef struct {
ut64 addr;
ut64 faddr;
RAnalFunction *fcn;
int pos; // related to columns
int cur; // current row selected
RList *columns;
RCore *core;
bool canLeft;
bool canRight;
} RCoreVisualViewZigns;
static const char *cur_name = NULL;
static char *print_item (void *_core, void *_item, bool selected) {
RSignItem *item = _item;
int i;
int bytes_mask = 0;
int bytes_size = item->bytes->size;
// int bytes_null = bytes_size - bytes_mask;
if (item->bytes->mask) {
for (i = 0; i < bytes_size;i++) {
if (item->bytes->mask[i]) {
bytes_mask++;
}
}
}
if (selected && item->name) {
cur_name = strdup (item->name);
}
return r_str_newf ("%c 0x%08"PFMT64x" bytes=%d/%d %20s\n", selected?'>':' ',
item->addr, bytes_mask, bytes_size, item->name);
}
static RList *__signs(RCoreVisualViewZigns *status, ut64 addr, bool update) {
RCore *core = status->core;
return r_sign_get_list (core->anal);
}
R_API int __core_visual_view_zigns_update(RCore *core, RCoreVisualViewZigns *status) {
int h, w = r_cons_get_size (&h);
r_cons_clear00 ();
int colh = h -2;
int colw = w -1;
RList *col0 = __signs (status, status->addr, true);
char *col0str = r_str_widget_list (core, col0, colh, status->cur, print_item);
char *title = r_str_newf ("[r2-visual-signatures] 0x%08"PFMT64x" 0x%08"PFMT64x, status->addr, status->faddr);
if (title) {
r_cons_strcat_at (title, 0, 0, w - 1, 2);
free (title);
}
r_cons_strcat_at (col0str, 0, 2, colw, colh);
r_list_free (col0);
r_cons_flush();
return 0;
}
R_API int r_core_visual_view_zigns(RCore *core) {
RCoreVisualViewZigns status = {0};
status.core = core;
status.addr = core->offset;
status.fcn = NULL;
while (true) {
__core_visual_view_zigns_update (core, &status);
int ch = r_cons_readchar ();
if (ch == -1 || ch == 4) {
return true;
}
ch = r_cons_arrow_to_hjkl (ch); // get ESC+char, return 'hjkl' char
switch (ch) {
case 'g':
r_core_cmd0 (core, "zg");
break;
case 'h':
if (status.canLeft) {
if (status.pos) {
status.addr = status.faddr;
}
status.pos = 1;
status.cur = 0;
}
break;
case 'l':
if (status.canRight) {
if (status.pos) {
status.addr = status.faddr;
}
status.pos = 2;
status.cur = 0;
}
break;
case 'd':
if (cur_name && *cur_name) {
r_sign_delete (core->anal, cur_name);
R_FREE (cur_name);
}
break;
case 'J':
status.cur += 10;
break;
case 'K':
if (status.cur > 10) {
status.cur -= 10;
} else {
status.cur = 0;
}
break;
case '.':
status.pos = 0;
break;
case 9:
case ' ':
case '\r':
case '\n':
if (status.pos) {
r_core_seek (core, status.faddr, 1);
} else {
r_core_seek (core, status.addr, 1);
}
return true;
break;
case '_':
r_core_cmd0 (core, "z*~...");
break;
case 'j':
status.cur++;
break;
case 'k':
if (status.cur > 0) {
status.cur--;
} else {
status.cur = 0;
}
break;
case '?':
r_cons_clear00 ();
r_cons_printf (
"vbz: Visual Zignatures:\n\n"
" jkJK - scroll up/down\n"
" d - delete current signature\n"
" g - regenerate signatures\n"
" q - quit this visual mode\n"
" _ - enter the hud\n"
" : - enter command\n");
r_cons_flush ();
r_cons_any_key (NULL);
break;
case 'q':
R_FREE (cur_name);
return false;
case ':': // TODO: move this into a separate helper function
{
char cmd[1024];
r_cons_show_cursor (true);
r_cons_set_raw (0);
cmd[0]='\0';
r_line_set_prompt (":> ");
if (r_cons_fgets (cmd, sizeof (cmd)-1, 0, NULL) < 0) {
cmd[0] = '\0';
}
r_core_cmd_task_sync (core, cmd, 1);
r_cons_set_raw (1);
r_cons_show_cursor (false);
if (cmd[0]) {
r_cons_any_key (NULL);
}
r_cons_clear ();
}
break;
}
}
return false;
}