Last active
June 11, 2022 17:26
-
-
Save wernsey/30456ebe845b95938ee8959e84f30dcd to your computer and use it in GitHub Desktop.
A small program to dump the contents of a binary file in hex or to a C header
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* $ gcc -o xdmp.exe xdmp.c | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <ctype.h> | |
#include <unistd.h> | |
unsigned char *read_file(const char *fname, size_t *plen) { | |
FILE *f; | |
size_t len,r; | |
unsigned char *bytes; | |
if(plen) | |
*plen = 0; | |
if(!(f = fopen(fname, "rb"))) | |
return NULL; | |
fseek(f, 0, SEEK_END); | |
len = ftell(f); | |
rewind(f); | |
if(!(bytes = malloc(len+2))) | |
return NULL; | |
r = fread(bytes, 1, len, f); | |
if(r != len) { | |
free(bytes); | |
return NULL; | |
} | |
fclose(f); | |
bytes[len] = '\0'; | |
if(plen) | |
*plen = len; | |
return bytes; | |
} | |
void usage(const char *exe) { | |
fprintf(stderr, "Usage: %s [-c] file...\n", exe); | |
fprintf(stderr, "Where:\n"); | |
fprintf(stderr, " -c - outputs file as C code\n"); | |
} | |
void dump_file_x(const char *name, unsigned char *bytes, size_t len) { | |
printf("** File: %s; Size: %u bytes\n", name, len); | |
size_t i, j; | |
for(i = 0; i < (len >> 4) + 1; i++) { | |
if(len > 0xFFFF) | |
printf("%08X: ", i << 4); | |
else | |
printf("%04X: ", i << 4); | |
for(j = 0; j < 16; j++) { | |
size_t a = (i << 4) + j; | |
if(a >= len) break; | |
if(j == 8) | |
printf(" "); | |
printf("%02X ", bytes[a]); | |
} | |
for(; j < 16; j++) { | |
fputs(" ", stdout); | |
} | |
fputs(" ", stdout); | |
for(j = 0; j < 16; j++) { | |
size_t a = (i << 4) + j; | |
if(a >= len) break; | |
if(j == 8) | |
printf(" "); | |
printf("%c", isprint(bytes[a])?bytes[a]:'.'); | |
} | |
printf("\n"); | |
} | |
} | |
void dump_file_code(const char *name, unsigned char *bytes, size_t len) { | |
char varname[50]; | |
snprintf(varname, sizeof varname, "%s", name); | |
size_t i, j; | |
for(i = 0; varname[i]; i++) { | |
if(!isalnum(varname[i])) | |
varname[i] = '_'; | |
} | |
printf("/* File: %s; Size: %u bytes */\n", name, len); | |
printf("static const unsigned char %s[] = {\n", varname); | |
for(i = 0; i < (len >> 4) + 1; i++) { | |
for(j = 0; j < 16; j++) { | |
size_t a = (i << 4) + j; | |
if(a >= len) break; | |
if(j == 8) | |
printf(" "); | |
printf("0x%02X, ", bytes[a]); | |
} | |
printf("\n"); | |
} | |
printf("};\nstatic long %s_len = %u;\n", varname, len); | |
} | |
int main(int argc, char *argv[]) { | |
int opt, code_mode = 0; | |
while((opt = getopt(argc, argv, "c?")) != -1) { | |
switch(opt) { | |
case 'c': { | |
code_mode = 1; | |
} break; | |
case '?' : { | |
usage(argv[0]); | |
return 1; | |
} | |
} | |
} | |
if(optind >= argc) { | |
usage(argv[0]); | |
return 1; | |
} | |
int f; | |
for(f = optind; f < argc; f++) { | |
size_t len; | |
unsigned char *bytes = read_file(argv[f], &len); | |
if(!bytes) { | |
fprintf(stderr, "error: unable to read '%s'\n", argv[f]); | |
return 1; | |
} | |
if(f > 1) fputs("\n", stdout); | |
if(code_mode) | |
dump_file_code(argv[f], bytes, len); | |
else | |
dump_file_x(argv[f], bytes, len); | |
free(bytes); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment