146
144
" :<cmd> radare command (vi like)\n"
147
145
" ; edit or add comment\n"
148
" \" change metadata of current cursor seek\n"
146
" \" change metadata of current cursor seek\n"
149
147
" ,. ',' marks an offset, '.' seeks to mark or eip if no mark\n"
150
148
" m' m1 -> mark current position as char '1'. '1 will jump to mark 1\n"
151
149
" g,G seek to beggining or end of file\n"
157
155
" f,F seek between flag list (f = forward, F = backward)\n"
158
156
" n,N seek between hits of the hit0 search\n"
159
157
" t visual track/browse flagspaces and flags\n"
160
" e visual eval configuration variables\n"
158
" e,E visual eval configuration variables, Edit notes file\n"
161
159
" C toggle scr.color\n"
162
160
" d convert cursor selected bytes to ascii, code or hex\n"
163
161
// " b[k][cmd] binds key 'k' to the specified command\n"
170
168
" H,L scroll left, right by 2 bytes (16 bits).\n"
171
169
" p,P switch between hex, bin and string formats\n"
172
170
" x show xrefs of the current offset\n"
171
" v visual code analysis mode (edit/view functions, variables, ...)\n"
173
172
" w write hexpair bytes in cursor\n"
174
" q exits visual mode\n");
173
" q exits visual mode\n"
174
" z, Z zoom full file, reset zoom preferences\n");
176
176
cons_printf("\nCursor mode:\n");
214
214
const char *ed = config_get("cfg.editor");
215
215
if (!strnull(ed)) {
216
216
/* TODO: Handle errors, put a different file name for */
217
snprintf(buf, 1023, "%s/.radare/screen-filter.txt", getenv("HOME"));
217
snprintf(buf, 1023, "%s/.radare/screen-filter.txt", get_home_directory());
218
218
config_set("file.scrfilter", buf);
219
219
eprintf(":!!%s '%s'\n", ed, buf);
269
int inv = config_get_i("cfg.inverse")^1;
270
config_set("cfg.inverse", inv?"true":"false");
269
int inv = (int) config_get_i ("cfg.inverse")^1;
270
config_set ("cfg.inverse", inv?"true":"false");
274
274
CMD_DECL(zoom_reset)
276
config.zoom.from = 0;
277
config.zoom.size = config.size;
278
config.zoom.piece = config.zoom.size/config.block_size;
276
config_set_i ("zoom.from", 0);
277
config_set_i ("zoom.to", config.size);
281
static void visual_edit ()
287
snprintf (file, sizeof (file), "%s.txt", config_get("file.project"));
288
// TODO: append screen dump to file
289
snprintf (cmd, sizeof (cmd), "%s '%s'", config_get("cfg.editor"), file);
291
eprintf ("command error (%s)\n", cmd);
282
296
static void visual_convert_bytes(int fmt, int defkey)
284
298
char argstr[128];
351
if (config.zoom.size == 0)
352
config.zoom.size = config.size;
355
config.zoom.enabled ^= 1;
356
if (config.zoom.enabled) {
357
config.cursor = config.block_size * config.seek/config.size;
358
// config.cursor_mode = 1;
359
config.zoom.size = config.block_size;
366
if (config.cursor_mode && config.ocursor == -1) {
367
config_set_i("zoom.from",
368
config.zoom.from + config.cursor * config.zoom.piece);
369
config_set_i("zoom.to", config.zoom.from + config.zoom.piece);
370
config.seek = config.zoom.from;
360
371
radare_cmd("pO", 0);
362
if (config.cursor_mode && ( config.ocursor != -1)) {
363
config.zoom.from = config.cursor * config.zoom.piece;
364
config.zoom.size = config.cursor-config.ocursor;
365
if (config.zoom.size<0) config.zoom.size *= -1;
366
config.zoom.size *=config.zoom.piece;
367
config.zoom.piece = (config.zoom.size-config.zoom.from)/config.block_size;
368
config.zoom.enabled = 1;
369
config.seek = config.zoom.from;
372
} else if (config.cursor_mode) {
374
if (config.ocursor > config.cursor) {
375
cfrom = config.cursor;
376
cto = config.ocursor;
372
if (config.cursor_mode)
373
config.seek = config.zoom.from + config.cursor * config.zoom.piece;
378
cfrom = config.ocursor;
377
config.cursor_mode = 0;
381
config_set_i("zoom.from",
382
config.zoom.from + cfrom * config.zoom.piece);
383
config_set_i("zoom.to",
384
config.zoom.from + (cto - cfrom) * config.zoom.piece);
385
config.seek = config.zoom.from;
388
config_set_i("zoom.from", 0);
389
config_set_i("zoom.to", config.size);
578
591
CMD_DECL(step_in_dbg)
580
593
if (!config.debug) {
581
eprintf("not in debugger\n");
584
radare_cmd("!step", 0);
594
char *str = strdup (config_get("asm.profile"));
595
#warning non-debugger code emulation is not integrated correctly
596
/* this is not working properly yet */
597
radare_cmd ("avx 1", 0); // USE THE VM HERE
598
radare_cmd (".av*", 0);
599
radare_cmd("f vm.eip@vm.eip+$$$", 0);
600
config_set ("asm.profile", str);
601
} else radare_cmd ("!step", 0);
586
603
//trace_add(get_offset("eip"));
682
696
if (config.debug) {
683
radare_cmd("!hack", 0);
697
radare_cmd ("!hack", 0);
685
699
/* for non debugger -- all of them must be available !! */
686
printf(" 0 - nop one opcode\n");
687
printf(" 1 - negate jump (jz->jnz , ja->jbe, ..)\n");
688
printf(" 2 - force jmp (only for { 0f, 0x80-0x8f })\n");
689
printf(" 5 - add ret\n");
690
printf(" 6 - add ret with eax=0\n");
691
printf(" 7 - negate zero flag (TODO)\n");
700
printf (" 0 - nop one opcode\n");
701
printf (" 1 - negate jump (jz->jnz , ja->jbe, ..)\n");
702
printf (" 2 - force jmp (only for { 0f, 0x80-0x8f })\n");
703
printf (" 5 - add ret\n");
704
printf (" 6 - add ret with eax=0\n");
705
printf (" 7 - negate zero flag (TODO)\n");
695
buf[0]=cons_readchar();
709
buf[0] = cons_readchar();
852
cons_printf("No user keybindings defined.\n");
854
860
cons_printf("Keybindings:");
856
for(i=0;i<nbds;i++) {
857
cons_printf(" key '%c' = \"%s\"", bds[i].key, bds[i].cmd);
863
cons_printf(" key '%c' = \"%s\"\n", bds[i].key, bds[i].cmd);
864
} else cons_printf("No user keybindings defined.\n");
934
938
strcpy(buf, "<insert assembly> ('tab')");
937
string_flag_offset(buf, config.seek, -2);
941
string_flag_offset(NULL, buf, config.seek, -2);
938
942
if (config.cursor!=-1)
939
string_flag_offset(buf2, config.seek+config.cursor, -1);
943
string_flag_offset(NULL, buf2, config.seek+config.cursor, -1);
943
947
ptr = config_get("scr.seek");
944
948
if (ptr&&ptr[0]&&last_print_format==FMT_REF) {
945
u64 off = get_math(ptr);
949
ut64 off = get_math(ptr);
947
951
radare_seek(off, SEEK_SET);
970
972
cons_printf("[ 0x%llx (bs=%d mark=0x%llx) %s %s] %s \n",
971
973
(config.seek+config.vaddr),
972
974
(unsigned int)config.block_size,
973
mark, get_print_format_name(last_print_format),
974
(inv)?"inv ":"", buf);
975
mark, strget(get_print_format_name(last_print_format)),
976
strget((char *)(size_t)inv),
975
978
/* Spaguetti monster lives here ! */
976
979
ptr = config_get("cmd.vprompt");
977
980
if (ptr&&ptr[0]) {
1061
void visual_change_metadata(u64 seek)
1064
void visual_change_metadata(ut64 seek)
1065
1068
char buf2[128];
1067
1070
eprintf("\nCurrent seek: 0x%08llx\n\n", seek);
1068
eprintf("q quit this menu\n");
1069
eprintf("f Analyze code here to define a function\n");
1070
eprintf("F Remove function definition\n");
1071
eprintf("; Add comment\n");
1072
eprintf("- Remove comment\n");
1073
eprintf("c Convert to code (remove previous type conversions)\n");
1074
eprintf("d Convert type of full block or selected bytes to hex data\n");
1075
eprintf("x Add xref\n");
1076
eprintf("X Remove xref\n");
1077
eprintf("\n=> Press key: \n");
1071
eprintf("q quit this menu\n"
1072
"f Analyze code here to define a function\n"
1073
"F Remove function definition\n"
1075
"- Remove comment\n"
1076
"c Convert to code (remove previous type conversions)\n"
1077
"d Convert type of full block or selected bytes to hex data\n"
1080
"\n=> Press key: \n");
1078
1081
key = cons_readchar();
1101
1104
radare_cmd(buf, 0);
1106
1107
visual_prompt_entry("type (code/data): ", buf2, sizeof(buf2));
1108
case 'c': type = 0; break;
1109
case 'd': type = 1; break;
1108
if (buf2[0] == 'd') key = 1; else key = 0;
1111
1109
off = get_math(visual_prompt_entry("xref addr: ", buf, sizeof(buf)));
1112
data_xrefs_add(seek, off, type);
1110
data_xrefs_add(seek, off, key);
1116
1113
off = get_math(visual_prompt_entry("xref addr: ", buf, sizeof(buf)));
1122
1119
void visual_f(int f)
1125
1122
struct bp_t *bp;
1126
1123
char line[128];
1131
radare_cmd("!help", 0);
1128
radare_cmd("!help", 0);
1137
addr = config.seek + (config.cursor_mode?config.acursor:0);
1138
bp = debug_bp_get(addr);
1140
sprintf(line, "!bp -0x%08x", (unsigned int)addr);
1142
//debug_rm_bp(addr, 0);
1144
sprintf(line, "!bp 0x%08x", (unsigned int)addr);
1147
if (!debug_bp_get(addr))
1148
flag_clear_by_addr(addr);
1153
printf("Watchpoint at: ");
1154
strcpy(line, "!drw ");
1155
fgets(line+5, sizeof(line), stdin);
1156
line[strlen(line)-1]='\0';
1163
if (config.cursor_mode) {
1164
sprintf(line, "!bp 0x%08llx", config.seek+config.cursor);
1165
radare_cmd_raw(line, 0);
1166
radare_cmd_raw("!cont", 0);
1167
sprintf(line, "!bp -0x%08llx", config.seek+config.cursor);
1168
radare_cmd_raw(line, 0);
1170
radare_cmd("!contuh", 0);
1175
arch_jmp(config.seek + (config.cursor_mode?config.acursor:0));
1134
addr = config.seek + (config.cursor_mode?config.acursor:0);
1135
bp = debug_bp_get(addr);
1137
sprintf(line, "!bp -0x%08x", (unsigned int)addr);
1139
//debug_rm_bp(addr, 0);
1141
sprintf(line, "!bp 0x%08x", (unsigned int)addr);
1144
if (!debug_bp_get(addr))
1145
flag_clear_by_addr(addr);
1150
printf("Watchpoint at: ");
1151
strcpy(line, "!drw ");
1152
fgets(line+5, sizeof(line), stdin);
1153
line[strlen(line)-1]='\0';
1160
if (config.cursor_mode) {
1161
sprintf(line, "!bp 0x%08llx", config.seek+config.cursor);
1162
radare_cmd_raw(line, 0);
1163
radare_cmd_raw("!cont", 0);
1164
sprintf(line, "!bp -0x%08llx", config.seek+config.cursor);
1165
radare_cmd_raw(line, 0);
1167
radare_cmd("!contuh", 0);
1172
arch_jmp(config.seek + (config.cursor_mode?config.acursor:0));
1179
radare_cmd("!contsc", 0);
1182
if (config_get("trace.libs")) {
1183
//CMD_NAME(step)(NULL);
1186
CMD_NAME(stepu_in_dbg)(NULL);
1191
CMD_NAME(stepo_in_dbg)(NULL);
1176
radare_cmd("!contsc", 0);
1179
if (config_get("trace.libs")) {
1180
//CMD_NAME(step)(NULL);
1183
CMD_NAME(stepu_in_dbg)(NULL);
1188
CMD_NAME(stepo_in_dbg)(NULL);
1215
1212
cons_get_real_columns();
1216
1213
config_set_i("scr.width", config.width);
1217
1214
config_set_i("scr.height", config.height);
1219
1215
nibble = 1; // high first
1224
config.height = config_get_i("scr.height");
1225
if (config.height<1)
1226
config_set_i("scr.height", 24);
1229
1218
if (bds == NULL)
1230
1219
bds = (struct binding *)malloc(sizeof(struct binding));
1253
1242
visual_draw_screen();
1254
1243
cons_flushit();
1257
if (config.debug&&last_print_format == FMT_VISUAL&&scrseek&&scrseek[0]) {
1258
u64 off = get_math(scrseek);
1246
if (config.debug&&last_print_format==FMT_VISUAL&&scrseek&&scrseek[0]) {
1247
ut64 off = get_math(scrseek);
1259
1248
if ((off < config.seek) || ((config.seek+config.block_size) < off)) {
1260
1249
radare_seek(off, SEEK_SET);
1265
1254
__go_read_a_key:
1266
1255
/* user input */
1267
key = cons_readchar();
1258
strcpy(input, input+1);
1259
} else key = cons_readchar();
1269
1261
/* insert mode . 'i' key */
1270
switch(config.insert_mode) {
1262
switch (config.insert_mode) {
1272
1264
key = cons_get_arrow(key); // get ESC+char, return 'hjkl' char
1275
key = cons_readchar();
1277
// TODO: must also work in interactive visual write ascii mode
1278
key = cons_readchar();
1280
case 0x35: key='K'; break; // re.pag
1281
case 0x36: key='J'; break; // av.pag
1282
case 0x41: key='k'; break; // up
1283
case 0x42: key='j'; break; // down
1284
case 0x43: key='l'; break; // right
1285
case 0x44: key='h'; break; // left
1296
1267
if (last_print_format == FMT_DISAS
1638
1608
ret = cons_fgets(ptr, 128, 0, NULL);
1641
radare_cmd(line, 1);
1644
1613
dl_prompt = ":> ";
1645
1614
if (cons_fgets(line, 1000, 0, NULL) <0)
1647
1616
//line[strlen(line)-1]='\0';
1648
radare_cmd(line, 1);
1618
if (strchr(line, '>') || strchr(line, '|') || strchr(line,'`'))
1619
eprintf("Cannot execute pipes in visual mode\n");
1620
else radare_cmd(line, 1);
1652
1623
config.visual=1;
1653
1624
last_print_format = lpf;
1654
1625
cons_set_raw(1);
1656
1627
cons_any_key();
1698
u8 buf = (u8)cons_readchar();
1699
if (visual_seeks_init && visual_seeks[buf] != 0xFFFFFFFF)
1668
byte = (u8)cons_readchar();
1669
if (visual_seeks_init && visual_seeks[byte] != U64_MAX) {
1701
radare_seek(visual_seeks[buf], SEEK_SET);
1671
radare_seek(visual_seeks[byte], SEEK_SET);
1706
u8 buf = (u8)cons_readchar();
1675
byte = (u8)cons_readchar();
1707
1676
if (visual_seeks_init == 0) {
1709
1678
for (i=0;i<255;i++)
1710
visual_seeks[i] = 0xFFFFFFFF;
1679
visual_seeks[i] = U64_MAX;
1711
1680
visual_seeks_init = 1;
1713
visual_seeks[buf] = config.seek;
1717
printf("\nrfile magic:\n\n");
1718
radare_dump_and_process( DUMP_MAGIC, config.block_size);
1682
visual_seeks[byte] = config.seek;
1723
1685
visual_convert_bytes(-1, 0);
1915
1882
// unexpand function or close folder
1916
1883
int type = data_type_range(config.seek+config.cursor);
1917
1884
if (type == -1 || type == DATA_FOLD_O) {
1918
data_set((u64)(config.seek+config.cursor), DATA_FOLD_C);
1885
data_set((ut64)(config.seek+config.cursor), DATA_FOLD_C);
1922
visual_convert_bytes(DATA_FOLD_C, 0);
1888
} else visual_convert_bytes(DATA_FOLD_C, 0);
1925
1890
config.seek -= config.block_size;
1926
1891
if (config.seek % config.block_size)
1931
1896
if (config.cursor_mode) {
1932
1897
int type = data_type_range(config.seek+config.cursor);
1933
if (type == DATA_FOLD_C) {
1898
if (type == DATA_FOLD_C)
1934
1899
data_set(config.seek+config.cursor, DATA_FOLD_O);
1938
1901
// unfold or expand
1939
1902
// check if current cursor position is jump -> open it
1940
1903
// check if current cursor position is a folder -> open it
1942
config.seek += config.block_size - (config.seek % config.block_size);
1904
} else config.seek += config.block_size - (config.seek % config.block_size);
1946
1907
if (config.cursor_mode) {
1954
1915
config.ocursor = config.cursor+1;
1955
1916
if (IS_LTZ(config.cursor))
1956
1917
config.cursor =0;
1918
} else config.seek -= 2;
1961
1921
if (config.cursor_mode) {
1962
1922
if (++config.cursor>=config.block_size)
1963
1923
config.cursor = config.block_size - 1;
1964
1924
config.ocursor = -1;
1925
} else config.seek++;
1968
1927
case '(': cons_skipxy(0,-1); break;
1969
1928
case ')': cons_skipxy(0,1); break;
2004
1963
if (config.cursor>=0 && config.cursor< config.block_size) {
2005
1964
c = config.cursor;
2006
1965
ch = config.block[config.cursor];
2007
sprintf(buf, "wx %02x @ 0x%llx", (unsigned char)(--ch), config.seek); //+config.cursor);
1966
sprintf(buf, "wx %02x @ 0x%llx", (ut8)(--ch), config.seek);
2008
1967
radare_cmd(buf, 0);
2009
1968
config.cursor = c;
2010
1969
config.ocursor = -1;
2012
} else radare_set_block_size_i(config.block_size-1);
1971
} else radare_set_block_size_i (config.block_size-1);