Here is a program, in C, which will display the contents of a file in hexadecimal. Compile the code and then run it from the command-line. It takes a list of files as arguments.
Some of the code is a little ugly, namely the way I make it print colour - using
#define 'd ANSI escape sequences. Not only are they ugly, but they won't work on all terminal emulators. I've checked and they work on Windows 7 (cmd.exe), Cygwin (mintty), GNOME (gnome-terminal), KDE (Konsole) and X (xterm) and they SHOULD work on whatever terminal emulator Mac OS uses, so that's like 90% of terminal emulators.
If your terminal emulator doesn't support ANSI escape sequences simply define NO_COLOR on the command-line (e.g., "gcc -DNO_COLOR -o hexview hexview.c").
If you're wondering,
while (n --> 1)
uses the 'hidden' "goes-to" operator.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
|
#include <ctype.h>
#include <errno.h>
#include <math.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
/*
* ANSI escape sequences for colours.
*
* XXX These may not work on your terminal emulator.
* TODO Change the method of printing colours
*
* If it doesn't work, try compiling with -DNO_COLOR (or /DNO_COLOR) to remove
* the escape sequences
*/
#ifndef NO_COLOR
# define FGC_BLACK "\033[30m"
# define FGC_DARK_RED "\033[31m"
# define FGC_DARK_GREEN "\033[32m"
# define FGC_DARK_YELLOW "\033[33m"
# define FGC_DARK_BLUE "\033[34m"
# define FGC_DARK_MAGENTA "\033[35m"
# define FGC_DARK_CYAN "\033[36m"
# define FGC_GRAY "\033[37m"
# define FGC_DARK_GRAY "\033[1;30m"
# define FGC_RED "\033[1;31m"
# define FGC_GREEN "\033[1;32m"
# define FGC_YELLOW "\033[1;33m"
# define FGC_BLUE "\033[1;34m"
# define FGC_MAGENTA "\033[1;35m"
# define FGC_CYAN "\033[1;36m"
# define FGC_WHITE "\033[1;37m"
# define BGC_BLACK "\033[40m"
# define BGC_DARK_RED "\033[41m"
# define BGC_DARK_GREEN "\033[42m"
# define BGC_DARK_YELLOW "\033[43m"
# define BGC_DARK_BLUE "\033[44m"
# define BGC_DARK_MAGENTA "\033[45m"
# define BGC_DARK_CYAN "\033[46m"
# define BGC_GRAY "\033[47m"
# define BGC_DARK_GRAY "\033[1;40m"
# define BGC_RED "\033[1;41m"
# define BGC_GREEN "\033[1;42m"
# define BGC_YELLOW "\033[1;43m"
# define BGC_BLUE "\033[1;44m"
# define BGC_MAGENTA "\033[1;45m"
# define BGC_CYAN "\033[1;46m"
# define BGC_WHITE "\033[1;47m"
# define OFFSET_COLOR BGC_DARK_RED FGC_WHITE
# define HEX_COLOR BGC_DARK_BLUE FGC_WHITE
# define STRING_COLOR BGC_DARK_GREEN FGC_WHITE
# define NORMAL_COLOR BGC_BLACK FGC_WHITE
# define INFO_COLOR BGC_BLACK FGC_BLUE
# define ERROR_COLOR BGC_BLACK FGC_RED
#else
# define OFFSET_COLOR
# define HEX_COLOR
# define STRING_COLOR
# define NORMAL_COLOR
# define INFO_COLOR
# define ERROR_COLOR
#endif
#define BUFFERSIZE 14
typedef uint8_t byte;
/**
* \brief Prints the data in hexadecimal representation
* \param p A pointer to the string containing characters to print
* \param n The size of the string
*/
*/
static void printhex(const void* p, size_t n)
{
const byte* s = (const byte*)p;
while (n --> 1) {
byte c = *s++;
printf(HEX_COLOR "%02X" NORMAL_COLOR, c);
if (n > 0)
putchar(' ');
}
}
/**
* \brief Prints the strings in a file
* \param p A pointer to the string containing characters to print
* \param n The size of the string
*/
static void printhexstr(const void* p, size_t n)
{
const char* s = (const char*)p;
while (n --> 1) {
char c = *s++;
if (!(isprint(c)))
c = '.';
if (c == '\n')
c = '.';
printf(STRING_COLOR "%c", c);
if (n > 0)
putchar(' ');
printf(NORMAL_COLOR);
}
}
/**
* \brief Prints the hex and strings in a file
* \param stream A pointer to an open FILE
* \return On success, 0 is returned. On error, -1 is returned.
*/
static int fviewhex(FILE* stream)
{
size_t offset = 0;
/*
* Read file in small blocks
*/
while (!(feof(stream))) {
static char buffer[BUFFERSIZE + 1] = {0};
fgets(buffer, BUFFERSIZE, stream);
/* Hex offset */
printf(OFFSET_COLOR "%08X" NORMAL_COLOR " ", offset);
/* Print hex */
printhex(buffer, BUFFERSIZE);
printf(" ");
/* Print strings */
printhexstr(buffer, BUFFERSIZE);
putchar('\n');
offset += BUFFERSIZE;
}
return 0;
}
/**
* \brief Prints the hex and strings in a file
* \param path The path to the file
* \return On success, 0 is returned. On error, -1 is returned.
*/
static int viewhex(const char* path)
{
FILE* stream = fopen(path, "r");
int ret;
if (!(stream)) {
fprintf(stderr, ERROR_COLOR "%s: fopen %s r: %s\n", __func__, path,
strerror(errno));
return -1;
}
ret = fviewhex(stream);
fclose(stream);
return ret;
}
int main(int argc, char* argv[])
{
int i;
if (argc < 2) {
fprintf(stderr, ERROR_COLOR "Usage: %s [file [file 2 [... [file n]]]]\n",
argv[0]);
exit(EXIT_FAILURE);
}
for (i = 1; i < argc; ++i) {
viewhex(argv[i]);
printf(NORMAL_COLOR "File: %s\n", argv[i]);
}
return 0;
}
|
Example output: http://pastebin.com/u4YGPCBi