Skip to content

Instantly share code, notes, and snippets.

@wernsey
Last active June 11, 2022 17:26
Show Gist options
  • Save wernsey/30456ebe845b95938ee8959e84f30dcd to your computer and use it in GitHub Desktop.
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
/*
* $ 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