/* cmd.c - MIT - Copyright 2009-2023 -- pancake /at/ nopcode /dot/ org */ #ifndef HAVE_SYSTEM #define HAVE_SYSTEM 1 #endif #define USE_DISASM 1 #if USE_DISASM_X86 #include "dis/x86.c" #elif USE_DISASM_X32 #include "dis/x32.c" #elif USE_DISASM_8086 #include "dis/8086.c" #elif USE_DISASM_ARM #include "dis/arm.c" #elif USE_DISASM_M68K // #define M68030 1 // #define M68020 1 // #define M68010 1 #include "dis/m68k.c" #else #undef USE_DISASM #define USE_DISASM 0 #endif static int cmd_hexdump(const char *arg) { int len = bsize; ut8 *buf = getcurblk(arg, &len); if(buf && len>0) { hexdump(buf, len, 16); free(buf); return 1; } return 2; } static int cmd_print(const char *arg) { ut8 *buf; int len = bsize; if(*arg) { buf = getcurblk(arg, &len); if(!buf) return 2; print_fmt(buf, arg, len); free(buf); } else printf( "ob/wW/dD/qQ byte (oct,hex), word, dword, qword (lil, big endian)\n" "i/I/f/F int32 (lil, big), float (lil, big)\n" "s/S short int16 (lil, big)\n" "z/Z zero-terminatted string (ascii, wide-ascii)\n" "./:/* skip 1 or 4 chars, repeat last format instead of cycle\n"); return 1; } static int cmd_system(const char *arg) { int len = bsize; char str[1024]; ut8 *buf; if(strstr(arg, "BLOCK")) { FILE *fd = fopen(".curblk", "wb"); if(fd) { if((buf = getcurblk("", &len))) { setenv("BLOCK", ".curblk", 1); fwrite(buf, len, 1, fd); free(buf); } fclose(fd); } } if(strstr(arg, "BSIZE")) { sprintf(str, "%d", len); setenv("BSIZE", str, 1); } if(strstr(arg, "OFFSET")) { sprintf(str, "%"LLF"d", curseek); setenv("OFFSET", str, 1); } if(strstr(arg, "XOFFSET")) { sprintf(str, "0x%"LLF"x", curseek); setenv("XOFFSET", str, 1); } #if HAVE_SYSTEM if(io_system(arg)<0) perror("system"); #endif unlink(".curblk"); return 1; } #if USE_DISASM static int cmd_disasm(const char *arg) { char output[256]; int i, j, len = bsize, ilen; int pad = 8; ut8 *buf = getcurblk(arg, &len); if (!buf) { return 2; } for(i = 0; i < len ;i++) { *output = 0; ilen = disasm(buf + i, len - i, curseek+i, output); printf("0x%08"LLF"x ", curseek+i); pad = 10; if (ilen > 0) { pad -= ilen; for(j=i;j < i+ilen && j < len;j++) printf("%02x", buf[j]); i += ilen - 1; if (pad > 0) for (j = i; j< i+pad;j++) printf(" "); } else { strcpy(output, "invalid"); } printf("%s\n", output); } free(buf); return 1; } #else static int cmd_disasm(const char *arg) { return cmd_system("echo X | r0 -n $BLOCK | rasm2 -o $OFFSET -D -"); // |head -n $(($LINES-1))"); } #endif static int cmd_bytedump(const char *arg) { int i, len = bsize; ut8 *buf = getcurblk(arg, &len); if(!buf) return 2; for(i=0;i0); free(buf); free(barg); return 1; } static int cmd_bsize(const char *arg) { if(!*arg) printf("%d\n", bsize); else if(*arg=='+') bsize += (int)calc(arg+1); else if(*arg=='-') bsize -= (int)calc(arg+1); else bsize = calc(arg); if(bsize<1) bsize = 1; obsize = bsize; return 1; } static int cmd_seek(const char *arg) { if(!*arg) printf("%"LLF"d\n", curseek); else if(*arg=='+') curseek += calc(arg+1); else if(*arg=='-') curseek -= calc(arg+1); else curseek = calc(arg); io_seek((oldseek=curseek), 0); return 1; } static int cmd_dump(const char *file) { int len = bsize; ut8 *buf = getcurblk("", &len); if(len<1 || buf) { FILE *fd = fopen(file, "wb"); if (!fd) { free (buf); return -1; } if(fwrite(buf, len, 1, fd)0 && buf) { int len = fread(buf, 1, bsize, fd); if(len[file] dump current block to file\n" "!cmd run shell command\n" "?expr calculate numeric expression\n" "q quit\n"); return 1; } static int cmd_resize(const char *arg) { ut8 *buf; ut64 tail, n; int i, len, ret = 0; switch(*arg) { case '\0': printf("%"LLF"d\n", (ut64)io_seek(0, SEEK_END)); break; case '+': // XXX: needs cleanup n = calc(arg+1); len = (ut64)io_seek(0, SEEK_END); tail = len-curseek; if((buf=malloc(tail))) { // XXX: Use block io_seek(curseek, SEEK_SET); i = io_read(buf, tail); if (i > 0) { io_seek(curseek+n, SEEK_SET); if (io_write(buf, tail) < 1) perror ("write"); free (buf); } } else perror("malloc"); break; case '-': buf = malloc(bsize); if(buf) { n = calc(arg+1); for(i=0;!ret;i+=len) { io_seek(curseek+n+i, SEEK_SET); if((len = io_read(buf, bsize))>0) { io_seek(curseek+i, SEEK_SET); if(io_write(buf, len)n) ret = io_truncate(ret-n); } else perror("malloc"); break; default: ret = io_truncate(calc(arg)); } if(ret<0) perror("truncate"); return 1; }