141 lines
3.0 KiB
C
141 lines
3.0 KiB
C
/* 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]);
|
|
}
|