#include #include #include #include #define SAVE_CHAR '@' #define D_PROMPT ">" #define D_ADDRC ':' #define D_ADDRF "%08d" #define D_DETCH 6 #define D_COMMAND_LEN 1024 #define D_BUFFER_LEN 10 #define D_LINE_LEN 12 #define D_ISIZE 4 #define D_DSIZE 8 #define D_CSIZE 1 #define char2int(ch) ((ch < 0) ? ch + 256 : ch) // // Global variables // char *filename; char *file; int fverbose = 0; int fsize = 0; int changed = 0; int inbound(int offs) { return (offs >= 0 && offs < fsize) ? 1 : 0; } int load(char *filename) { FILE *fin; fin = fopen(filename, "rb+"); if (fin == NULL) return 0; fseek(fin, 0L, SEEK_END); fsize = ftell(fin); file = malloc(fsize); if (file != NULL) { fseek(fin, 0L, SEEK_SET); fread(file, 1, fsize, fin); } fclose(fin); return file != NULL ? 1 : 0; } int save(char *filename) { FILE *fin; fin = fopen(filename, "wb"); if (fin == NULL) return 0; fwrite(file, 1, fsize, fin); fclose(fin); return 1; } void init(int argc, char *argv[]) { int i; // // Check number of command line args // if (argc < 2) { printf("Usage: drill []\n"); exit(EXIT_FAILURE); } // // Print banner // printf("Drill 0.99 Alpha Rel. 4-Dec-2005\n"); printf("Hardcore file viewer/editor/analyzer\n\n"); // // Load the file to drill // filename = malloc(strlen(argv[1])); strcpy(filename, argv[1]); printf("Drilling \"%s\"\n",filename); if (!load(filename)) { printf("! Unable to load the file %s\n", filename); } for (i = 2; i < argc; i++) { if (argv[i][0] == '-' || argv[i][0] == '/') { switch (argv[i][1]) { case 'v': case 'V': printf(" + verbose mode on"); fverbose = 1; break; default : printf(" - ignoring unknown option \"%s\"...", argv[i]); } } else { printf(" - ignoring illegal command-line switch \"%s\"...", argv[i]); } } } void showhelp() { printf("c[x|d|o][ ] - show char(s)\n"); printf("i[x|o][ ] - show 32-bit integer(s)\n"); printf("d[x|s][ ] - show 64-bit double(s)\n"); printf("@c ] - set char\n"); printf("@i - set 32-bit integer(s)\n"); printf("@d - set 64-bit double(s)\n"); printf("s - save file\n"); printf("? - available information on current file\n"); printf("q|x - quit\n\n"); } void showchar(char *cmd) { int pos = 0, rep = 1, i, offs; int fhex = 0, curr; char buf[D_BUFFER_LEN] = {0}; if (isalpha(cmd[0])) { switch(toupper(cmd[0])) { case 'X': fhex = 1; break; } cmd++; } sscanf(cmd, "%d %d", &pos, &rep); for (i = 0; i < rep; i++) { offs = pos + i * D_CSIZE; memset(buf, 0, D_BUFFER_LEN); if (inbound(offs)) curr = (int) file[offs]; else curr = -1; if (i % D_LINE_LEN == 0) { if (i > 0) printf("\n"); printf(D_ADDRF ":", offs); } if (fhex) printf("0x%02X", char2int(curr)); else printf("%c", curr); if (fhex) { if (rep <= D_DETCH) printf(" \'%c\', ", curr); else printf(" "); } } printf("\n"); } void setchar(char *cmd) { int pos = 0, i, offs; char hodnota; sscanf(cmd, "%d %c", &pos, &hodnota); if (pos < fsize) memcpy(&(file[pos]), &hodnota, D_CSIZE); printf("\n"); } void showint(char *cmd) { int pos = 0, rep = 1, i, offs; char fmt[32] = {0}; strcpy(fmt, "%08d%c%11d\n"); if (isalpha(cmd[0])) { switch(toupper(cmd[0])) { case 'X': strcpy(fmt, "%08d%c0x%08X\n"); break; } cmd++; } sscanf(cmd, "%d %d", &pos, &rep); for (i = 0; i < rep; i++) { offs = pos + i * D_ISIZE; printf(fmt, offs, D_ADDRC, *((int *) (file + offs))); } printf("\n"); } void setint(char *cmd) { int pos = 0, i, offs; int hodnota; sscanf(cmd, "%d %d", &pos, &hodnota); if (pos < fsize) memcpy(&(file[pos]), &hodnota, D_DSIZE); printf("\n"); } void showdouble(char *cmd) { int pos = 0, rep = 1, i, offs; char fmt[32] = {0}; strcpy(fmt, "%08d%c%e\n"); if (isalpha(cmd[0])) { switch(toupper(cmd[0])) { case 'X': strcpy(fmt, "%08d%c0x%016X\n"); break; } cmd++; } sscanf(cmd, "%d %d", &pos, &rep); for (i = 0; i < rep; i++) { offs = pos + i * D_DSIZE; printf(fmt, offs, D_ADDRC, *((double *) (file + offs))); } printf("\n"); } void setdouble(char *cmd) { int pos = 0, i, offs; double hodnota; sscanf(cmd, "%d %lf", &pos, &hodnota); if (pos < fsize) memcpy(&(file[pos]), &hodnota, D_DSIZE); printf("\n"); } void run() { int fterm = 0; char buffer[D_COMMAND_LEN] = {0}; char command; int do_save; printf("Listening... (type \'h\' to get help)\n\n"); do { printf(D_PROMPT); memset(buffer, 0, D_COMMAND_LEN); fgets(buffer, D_COMMAND_LEN, stdin); // // Parse the command // do_save = 0; command = toupper(buffer[0]); if (command == SAVE_CHAR) { command = toupper(buffer[1]); do_save = 1; } switch (command) { case 'Q': case 'X': printf("Bye.\n"); fterm = 1; break; case 'C': if (do_save==1) { setchar(buffer + 2); } else { showchar(buffer + 1); } break; case 'I': if (do_save==1) { setint(buffer + 2); } else { showint(buffer + 1); } break; case 'D': if (do_save==1) { setdouble(buffer + 2); } else { showdouble(buffer + 1); } break; case 'H': showhelp(); break; case 'S': if (!save(filename)) { printf("! Unable to save the file %s\n", filename); } else { printf("File was been saved."); } break; case '?': printf("\"%s\", size = %d B\n", filename, fsize); break; default : printf("! Unknown command\n"); } } while (!fterm); } void shutdown() { char c; if (changed == 1) { printf("File was been changed. Do you wan't save it? [Y/N] "); c = getchar(); while(getchar() != '\n'); if (c == 'a' || c == 'A') if (!save(filename)) printf("! Unable to save the file %s\n", filename); } if (filename != NULL) free(filename); if (file != NULL) free(file); } int main(int argc, char *argv[]) { init(argc, argv); run(); shutdown(); return EXIT_SUCCESS; }