1 #include <u.h> 2 #include <libc.h> 3 #include <a.out.h> 4 5 int strip(char*); 6 int stripfilt(int, int); 7 void 8 main(int argc, char *argv[]) 9 { 10 int i; 11 int rv; 12 13 rv = 0; 14 15 if(argc == 1) { 16 if(stripfilt(0, 1)) 17 exits("error"); 18 exits(0); 19 } 20 21 for(i = 1; i < argc; i++) 22 rv |= strip(argv[i]); 23 if(rv) 24 exits("error"); 25 exits(0); 26 } 27 28 long 29 ben(long xen) 30 { 31 union 32 { 33 long xen; 34 uchar uch[sizeof(long)]; 35 } u; 36 37 u.xen = xen; 38 return (u.uch[0] << 24) | (u.uch[1] << 16) | (u.uch[2] << 8) | (u.uch[3] << 0); 39 } 40 41 int 42 stripfilt(int in, int out) 43 { 44 Exec exec; 45 int i, j, n, m, len; 46 char buf[8192]; 47 48 /* 49 * read header 50 */ 51 52 if(readn(in, &exec, sizeof(Exec)) != sizeof(Exec)) { 53 fprint(2, "strip: short read\n"); 54 return 1; 55 } 56 i = ben(exec.magic); 57 for (j = MIN_MAGIC; j <= MAX_MAGIC; j++) 58 if (i == _MAGIC(j)) 59 break; 60 if (j > MAX_MAGIC) { 61 fprint(2, "strip: not a recognizable binary\n"); 62 return 1; 63 } 64 65 len = ben(exec.data) + ben(exec.text); 66 67 /* 68 * copy exec, text and data 69 */ 70 exec.syms = 0; 71 exec.spsz = 0; 72 exec.pcsz = 0; 73 write(out, &exec, sizeof(exec)); 74 75 for(n=0; n<len; n+=m) { 76 m = len - n; 77 if(m > sizeof(buf)) 78 m = sizeof(buf); 79 if((m = read(in, buf, m)) < 0) { 80 fprint(2, "strip: premature eof: %r\n"); 81 return 1; 82 } 83 if(write(out, buf, m) != m) { 84 fprint(2, "strip: write error; %r\n"); 85 return 1; 86 } 87 } 88 89 return 0; 90 } 91 92 93 int 94 strip(char *file) 95 { 96 int fd; 97 Exec exec; 98 char *data; 99 Dir *d; 100 long n, len; 101 int i, j; 102 103 /* 104 * make sure file is executable 105 */ 106 d = dirstat(file); 107 if(d == nil){ 108 perror(file); 109 return 1; 110 } 111 if((d->qid.path & (DMDIR|DMAPPEND|DMEXCL))){ 112 fprint(2, "strip: %s must be executable\n", file); 113 return 1; 114 } 115 /* 116 * read its header and see if that makes sense 117 */ 118 fd = open(file, OREAD); 119 if(fd < 0){ 120 perror(file); 121 free(d); 122 return 1; 123 } 124 n = read(fd, &exec, sizeof exec); 125 if (n != sizeof(exec)) { 126 fprint(2, "strip: Unable to read header of %s\n", file); 127 close(fd); 128 free(d); 129 return 1; 130 } 131 i = ben(exec.magic); 132 for (j = MIN_MAGIC; j <= MAX_MAGIC; j++) 133 if (i == _MAGIC(j)) 134 break; 135 if (j > MAX_MAGIC) { 136 fprint(2, "strip: %s is not a recognizable binary\n", file); 137 close(fd); 138 free(d); 139 return 1; 140 } 141 142 len = ben(exec.data) + ben(exec.text); 143 if(len+sizeof(exec) == d->length) { 144 fprint(2, "strip: %s is already stripped\n", file); 145 close(fd); 146 free(d); 147 return 0; 148 } 149 if(len+sizeof(exec) > d->length) { 150 fprint(2, "strip: %s has strange length\n", file); 151 close(fd); 152 free(d); 153 return 1; 154 } 155 /* 156 * allocate a huge buffer, copy the header into it, then 157 * read the file. 158 */ 159 data = malloc(len+sizeof(exec)); 160 if (!data) { 161 fprint(2, "strip: Malloc failure. %s too big to strip.\n", file); 162 close(fd); 163 free(d); 164 return 1; 165 } 166 /* 167 * copy exec, text and data 168 */ 169 exec.syms = 0; 170 exec.spsz = 0; 171 exec.pcsz = 0; 172 memcpy(data, &exec, sizeof(exec)); 173 n = read(fd, data+sizeof(exec), len); 174 if (n != len) { 175 perror(file); 176 close(fd); 177 free(d); 178 return 1; 179 } 180 close(fd); 181 if(remove(file) < 0) { 182 perror(file); 183 free(data); 184 free(d); 185 return 1; 186 } 187 fd = create(file, OWRITE, d->mode); 188 if (fd < 0) { 189 perror(file); 190 free(data); 191 free(d); 192 return 1; 193 } 194 n = write(fd, data, len+sizeof(exec)); 195 if (n != len+sizeof(exec)) { 196 perror(file); 197 close(fd); 198 free(data); 199 free(d); 200 return 1; 201 } 202 close(fd); 203 free(data); 204 free(d); 205 return 0; 206 } 207