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
|
/* makehole.c - original by HJ Lu */
/* Patched by faith@cs.unc.edu, Wed Oct 6 18:01:39 1993 based on
information from Michael Bischoff <mbi@mo.math.nat.tu-bs.de> (Fri, 18
Jun 93 10:10:19 +0200). */
#include <unistd.h>
#include <fcntl.h>
#include <stdlib.h>
#include <stdio.h>
#include <errno.h>
#include <a.out.h>
#define BUFSIZE 1024
#undef DEBUG
void usage(char *name, char *message)
{
if (message)
fprintf(stderr, "%s: %s\n", name, message);
if (errno)
perror(name);
fprintf(stderr, "Usage:%s Imagefile\n", name);
exit(1);
}
int ishole(char *buf, int size)
{
int i;
for (i = 0; i < size; i++)
if (buf[i])
return 0;
return 1;
}
void main(int argc, char *argv[])
{
char buf[BUFSIZE];
char tmp_file[64];
int fdin, fdout;
int ret;
int abs_offset;
int hole;
struct exec *header = (struct exec *) buf;
#ifndef DEBUG
if (geteuid()) {
fprintf(stderr, "%s: must be root to run!\n", *argv);
exit(1);
}
#endif
switch (argc) {
case 2:
break;
default:
usage(*argv, NULL);
}
errno = 0;
sprintf( tmp_file, "hole%d", getpid() );
if (tmp_file == NULL) {
usage(*argv, "Unable to get a temporary image filename!");
}
#ifdef DEBUG
else {
fprintf(stderr, "Temparory image file: %s\n", tmp_file);
}
#endif
errno = 0;
fdin = open(argv[1], O_RDONLY);
if (fdin == -1) {
usage(*argv, "unable to open file.");
}
fprintf(stderr, "Making holes in %s...\n", argv[1]);
errno = 0;
if ((ret = read(fdin, header, BUFSIZE)) != BUFSIZE
|| N_MAGIC(*header) != ZMAGIC) {
usage(*argv, "file must be pure executable.");
}
fdout = creat(tmp_file, 0555);
if (fdout == -1) {
perror("Unable to create the temparory image file!");
exit(1);
}
if (write(fdout, header, ret) != ret) {
perror("Fail to write header to the temparory image file!");
unlink(tmp_file);
exit(1);
}
abs_offset = ret;
hole = 0;
while ((ret = read(fdin, buf, BUFSIZE)) > 0) {
abs_offset += ret;
if (ishole(buf, ret)) {
#ifdef DEBUG
fprintf(stderr, "There is a %d byte hole from 0x%x to 0x%x.\n", ret, abs_offset - ret, abs_offset);
#endif
hole += ret;
if (lseek(fdout, abs_offset, SEEK_SET) != abs_offset) {
perror("Fail to make a hole in the temparory image file!");
unlink(tmp_file);
exit(1);
}
} else {
#ifdef DEBUG
fprintf(stderr, "Writing %d bytes from 0x%x to 0x%x.\n", ret, abs_offset - ret, abs_offset);
#endif
if (write(fdout, buf, ret) != ret) {
perror("Fail to write the temparory image file!");
unlink(tmp_file);
exit(1);
}
}
}
if (ftruncate(fdout, abs_offset)) {
perror("Fail to truncate the temparory image file!");
unlink(tmp_file);
exit(1);
}
close(fdout);
close(fdin);
if (rename(tmp_file, argv[1])) {
perror("Fail to rename the temparory image file to the old image file!");
unlink(tmp_file);
exit(1);
}
fprintf(stderr, "There are %d byte holes out of %d bytes in `%s'.\n", hole, abs_offset, argv[1]);
}
|