1 /* radare - LGPL - Copyright 2019 - pancake */
2
3 #include <r_core.h>
4
5 typedef struct {
6 ut64 addr;
7 ut64 faddr;
8 RAnalFunction *fcn;
9 int pos; // related to columns
10 int cur; // current row selected
11 RList *columns;
12 RCore *core;
13 bool canLeft;
14 bool canRight;
15 } RCoreVisualViewZigns;
16
17 static const char *cur_name = NULL;
18
print_item(void * _core,void * _item,bool selected)19 static char *print_item (void *_core, void *_item, bool selected) {
20 RSignItem *item = _item;
21 int i;
22 int bytes_mask = 0;
23 int bytes_size = item->bytes->size;
24 // int bytes_null = bytes_size - bytes_mask;
25 if (item->bytes->mask) {
26 for (i = 0; i < bytes_size;i++) {
27 if (item->bytes->mask[i]) {
28 bytes_mask++;
29 }
30 }
31 }
32 if (selected && item->name) {
33 cur_name = strdup (item->name);
34 }
35 return r_str_newf ("%c 0x%08"PFMT64x" bytes=%d/%d %20s\n", selected?'>':' ',
36 item->addr, bytes_mask, bytes_size, item->name);
37 }
38
__signs(RCoreVisualViewZigns * status,ut64 addr,bool update)39 static RList *__signs(RCoreVisualViewZigns *status, ut64 addr, bool update) {
40 RCore *core = status->core;
41 return r_sign_get_list (core->anal);
42 }
43
__core_visual_view_zigns_update(RCore * core,RCoreVisualViewZigns * status)44 R_API int __core_visual_view_zigns_update(RCore *core, RCoreVisualViewZigns *status) {
45 int h, w = r_cons_get_size (&h);
46 r_cons_clear00 ();
47 int colh = h -2;
48 int colw = w -1;
49 RList *col0 = __signs (status, status->addr, true);
50 char *col0str = r_str_widget_list (core, col0, colh, status->cur, print_item);
51
52 char *title = r_str_newf ("[r2-visual-signatures] 0x%08"PFMT64x" 0x%08"PFMT64x, status->addr, status->faddr);
53 if (title) {
54 r_cons_strcat_at (title, 0, 0, w - 1, 2);
55 free (title);
56 }
57 r_cons_strcat_at (col0str, 0, 2, colw, colh);
58 r_list_free (col0);
59 r_cons_flush();
60 return 0;
61 }
62
r_core_visual_view_zigns(RCore * core)63 R_API int r_core_visual_view_zigns(RCore *core) {
64 RCoreVisualViewZigns status = {0};
65 status.core = core;
66 status.addr = core->offset;
67 status.fcn = NULL;
68
69 while (true) {
70 __core_visual_view_zigns_update (core, &status);
71 int ch = r_cons_readchar ();
72 if (ch == -1 || ch == 4) {
73 return true;
74 }
75 ch = r_cons_arrow_to_hjkl (ch); // get ESC+char, return 'hjkl' char
76 switch (ch) {
77 case 'g':
78 r_core_cmd0 (core, "zg");
79 break;
80 case 'h':
81 if (status.canLeft) {
82 if (status.pos) {
83 status.addr = status.faddr;
84 }
85 status.pos = 1;
86 status.cur = 0;
87 }
88 break;
89 case 'l':
90 if (status.canRight) {
91 if (status.pos) {
92 status.addr = status.faddr;
93 }
94 status.pos = 2;
95 status.cur = 0;
96 }
97 break;
98 case 'd':
99 if (cur_name && *cur_name) {
100 r_sign_delete (core->anal, cur_name);
101 R_FREE (cur_name);
102 }
103 break;
104 case 'J':
105 status.cur += 10;
106 break;
107 case 'K':
108 if (status.cur > 10) {
109 status.cur -= 10;
110 } else {
111 status.cur = 0;
112 }
113 break;
114 case '.':
115 status.pos = 0;
116 break;
117 case 9:
118 case ' ':
119 case '\r':
120 case '\n':
121 if (status.pos) {
122 r_core_seek (core, status.faddr, true);
123 } else {
124 r_core_seek (core, status.addr, true);
125 }
126 return true;
127 break;
128 case '_':
129 r_core_cmd0 (core, "z*~...");
130 break;
131 case 'j':
132 status.cur++;
133 break;
134 case 'k':
135 if (status.cur > 0) {
136 status.cur--;
137 } else {
138 status.cur = 0;
139 }
140 break;
141 case '?':
142 r_cons_clear00 ();
143 r_cons_printf (
144 "vbz: Visual Zignatures:\n\n"
145 " jkJK - scroll up/down\n"
146 " d - delete current signature\n"
147 " g - regenerate signatures\n"
148 " q - quit this visual mode\n"
149 " _ - enter the hud\n"
150 " : - enter command\n");
151 r_cons_flush ();
152 r_cons_any_key (NULL);
153 break;
154 case 'q':
155 R_FREE (cur_name);
156 return false;
157 case ':': // TODO: move this into a separate helper function
158 {
159 char cmd[1024];
160 r_cons_show_cursor (true);
161 r_cons_set_raw (0);
162 cmd[0]='\0';
163 r_line_set_prompt (":> ");
164 if (r_cons_fgets (cmd, sizeof (cmd), 0, NULL) < 0) {
165 cmd[0] = '\0';
166 }
167 r_core_cmd_task_sync (core, cmd, 1);
168 r_cons_set_raw (1);
169 r_cons_show_cursor (false);
170 if (cmd[0]) {
171 r_cons_any_key (NULL);
172 }
173 r_cons_clear ();
174 }
175 break;
176 }
177 }
178 return false;
179 }
180