-
Notifications
You must be signed in to change notification settings - Fork 5
/
hexdump.c
125 lines (99 loc) · 3.37 KB
/
hexdump.c
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
/*
This file contains a simple hex dump routine.
THIS CODE COPYRIGHT DOMINIC GIAMPAOLO. NO WARRANTY IS EXPRESSED
OR IMPLIED. YOU MAY USE THIS CODE AND FREELY DISTRIBUTE IT FOR
NON-COMMERCIAL USE AS LONG AS THIS NOTICE REMAINS ATTACHED.
FOR COMMERCIAL USE, CONTACT DOMINIC GIAMPAOLO (dbg@be.com).
Dominic Giampaolo
dbg@be.com
*/
#include <stdio.h>
#include <ctype.h>
#include "compat.h"
/*
* This routine is a simple memory dumper. It's nice and simple, and works
* well.
*
* The bad things about it are that it assumes roughly an 80 column output
* device and that output is fixed at BYTES_PER_LINE/2 columns (separated
* every two bytes).
*
* Obviously the bad things are fixable, but I don't need the extra
* flexibility at the moment, so I don't feel like doing it.
*
* Dominic Giampaolo
* (dbg@be.com)
*/
#define BYTES_PER_LINE 16 /* a reasonable power of two */
void hexdump(void *address, int size)
{
int i;
int offset, num_spaces;
unsigned char *mem, *tmp;
offset = 0;
mem = (unsigned char *)address;
/*
* Each line contains BYTES_PER_LINE bytes of data (presently 16). I
* chose 16 because it is a nice power of two and makes reading the
* hex offset column much easier. I used to use a value of 18 to fit
* more info on the screen, and 20 is also doable but much too crowded.
* Ideally it should be an argument or settable parameter...
*
* The data is formatted into BYTES_PER_LINE/2 (8) columns of 2 bytes
* each (printed in hex).
*
* The offset is formatted as a 4 byte hex number (i.e. 8 characters).
*/
while(offset < size)
{
printf("%.8x: ", offset);
for(i=0,tmp=mem; i < BYTES_PER_LINE && (offset+i) < size; i++,tmp++)
{
printf("%.2x", *tmp);
if (((i+1) % 4) == 0)
printf(" ");
}
/*
* This formula for the number of spaces to print is as follows:
* 10 is the number of characters printed at the beginning of
* the line (8 hex digits, the colon and a space).
* i*2 is the number of characters of data we dumped in hex.
* i/2 is the number of blanks we printed between columns.
* i is the number of bytes we will print in ascii.
*
* Then we subtract all that from 74 (the width of the output
* device) to decide how many spaces we need to push the ascii
* column as far to the right as possible.
*
* The number 58 is the column where we start we start printing
* the ascii dump. We subtract how many characters we've already
* printed and that gets us to where we need to be to start the
* ascii portion of the dump.
*
*/
num_spaces = 58 - (12 + i*2 + i/4);
for(i=0; i < num_spaces; i++)
printf(" ");
for(i=0,tmp=mem; i < BYTES_PER_LINE && (offset+i) < size; i++, tmp++)
if (isprint(*tmp))
printf("%c", *tmp);
else
printf(".");
printf("\n");
offset += BYTES_PER_LINE;
mem = tmp;
}
}
#ifdef TEST
char buff[] = "!blah, blah blah blah blah asldfj lkasjdf lka lkjasdflasdlj"
"asdj lasdfj lasdjf lasdjf lkasjdfl kjasdlf jasldfj lasdfj l"
"asdjflkasjdflk;ja sdfljasdfjk asjkfl;kasjfl;asjdfl;azzzzzzz";
main(int argc, char **argv)
{
int i,j,k;
FILE *fp;
hexdump(buff, 171);
printf("---------\n");
hexdump(main, 57);
}
#endif /* TEST */