[1] | 1 | /* sstrip, version 2.0: Copyright (C) 1999-2001 by Brian Raiter, under the
|
---|
| 2 | * GNU General Public License. No warranty. See LICENSE for details.
|
---|
| 3 | */
|
---|
| 4 |
|
---|
[48] | 5 | /* Modified for portability and 64bit/32bit elf executables, Rainer Wichmann */
|
---|
| 6 |
|
---|
| 7 | #include "config.h"
|
---|
[1] | 8 |
|
---|
| 9 | #include <stdio.h>
|
---|
| 10 | #include <stdlib.h>
|
---|
| 11 | #include <string.h>
|
---|
| 12 | #include <errno.h>
|
---|
| 13 | #include <unistd.h>
|
---|
| 14 | #include <fcntl.h>
|
---|
| 15 |
|
---|
| 16 | #if !defined(__ia64) && !defined(__ia64__) && !defined(__itanium__) && \
|
---|
| 17 | !defined(__alpha) && !defined(__alpha__) && \
|
---|
[48] | 18 | (defined(HAVE_ELF_H) || defined(HAVE_LINUX_ELF_H)) && \
|
---|
| 19 | (defined(__linux__) || defined(__FreeBSD__)) && \
|
---|
| 20 | (defined(__i386__) || defined(__i386) || defined(i386))
|
---|
[1] | 21 |
|
---|
| 22 | /* || defined(__sun) || defined(__sun__) || defined(sun) */
|
---|
| 23 |
|
---|
[48] | 24 |
|
---|
| 25 | #if defined(HAVE_ELF_H)
|
---|
| 26 | #include <elf.h>
|
---|
| 27 | #else
|
---|
[1] | 28 | #include <linux/elf.h>
|
---|
| 29 | #endif
|
---|
| 30 |
|
---|
| 31 | #ifndef TRUE
|
---|
| 32 | #define TRUE 1
|
---|
| 33 | #define FALSE 0
|
---|
| 34 | #endif
|
---|
| 35 |
|
---|
[48] | 36 | #ifndef ELFCLASS32
|
---|
| 37 | #define ELFCLASS32 1 /* 32-bit objects */
|
---|
[1] | 38 | #endif
|
---|
[48] | 39 | #ifndef ELFCLASS64
|
---|
| 40 | #define ELFCLASS64 2 /* 64-bit objects */
|
---|
| 41 | #endif
|
---|
[1] | 42 |
|
---|
[48] | 43 |
|
---|
| 44 |
|
---|
[1] | 45 | /* The name of the program.
|
---|
| 46 | */
|
---|
| 47 | static char const *progname;
|
---|
| 48 |
|
---|
| 49 | /* The name of the current file.
|
---|
| 50 | */
|
---|
| 51 | static char const *filename;
|
---|
| 52 |
|
---|
| 53 |
|
---|
| 54 | /* A simple error-handling function. FALSE is always returned for the
|
---|
| 55 | * convenience of the caller.
|
---|
| 56 | */
|
---|
| 57 | static int err(char const *errmsg)
|
---|
| 58 | {
|
---|
| 59 | fprintf(stderr, "%s: %s: %s\n", progname, filename, errmsg);
|
---|
| 60 | return FALSE;
|
---|
| 61 | }
|
---|
| 62 |
|
---|
| 63 | /* A macro for I/O errors: The given error message is used only when
|
---|
| 64 | * errno is not set.
|
---|
| 65 | */
|
---|
| 66 | #define ferr(msg) (err(errno ? strerror(errno) : (msg)))
|
---|
| 67 |
|
---|
| 68 | /* readelfheader() reads the ELF header into our global variable, and
|
---|
| 69 | * checks to make sure that this is in fact a file that we should be
|
---|
| 70 | * munging.
|
---|
| 71 | */
|
---|
[48] | 72 | static int readelfheader_32(int fd, Elf32_Ehdr *ehdr)
|
---|
[1] | 73 | {
|
---|
| 74 | errno = 0;
|
---|
| 75 | if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
|
---|
| 76 | return ferr("missing or incomplete ELF header.");
|
---|
| 77 |
|
---|
| 78 | /* Check the ELF signature.
|
---|
| 79 | */
|
---|
| 80 | if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 &&
|
---|
| 81 | ehdr->e_ident[EI_MAG1] == ELFMAG1 &&
|
---|
| 82 | ehdr->e_ident[EI_MAG2] == ELFMAG2 &&
|
---|
| 83 | ehdr->e_ident[EI_MAG3] == ELFMAG3))
|
---|
| 84 | return err("missing ELF signature.");
|
---|
| 85 |
|
---|
| 86 | /* Compare the file's class and endianness with the program's.
|
---|
| 87 | */
|
---|
[48] | 88 | #ifdef ELF_DATA
|
---|
[1] | 89 | if (ehdr->e_ident[EI_DATA] != ELF_DATA)
|
---|
| 90 | return err("ELF file has different endianness.");
|
---|
[48] | 91 | #endif
|
---|
| 92 |
|
---|
| 93 | if (ehdr->e_ident[EI_CLASS] != ELFCLASS32)
|
---|
| 94 | return FALSE;
|
---|
| 95 |
|
---|
| 96 | /* Check the target architecture.
|
---|
| 97 | */
|
---|
| 98 | #ifdef ELF_ARCH
|
---|
| 99 | if (ehdr->e_machine != ELF_ARCH)
|
---|
| 100 | return err("ELF file created for different architecture.");
|
---|
| 101 | #endif
|
---|
| 102 |
|
---|
| 103 | /* Verify the sizes of the ELF header and the program segment
|
---|
| 104 | * header table entries.
|
---|
| 105 | */
|
---|
| 106 | if (ehdr->e_ehsize != sizeof(Elf32_Ehdr))
|
---|
| 107 | return err("unrecognized ELF header size.");
|
---|
| 108 | if (ehdr->e_phentsize != sizeof(Elf32_Phdr))
|
---|
| 109 | return err("unrecognized program segment header size.");
|
---|
| 110 |
|
---|
| 111 | /* Finally, check the file type.
|
---|
| 112 | */
|
---|
| 113 | if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
|
---|
| 114 | return err("not an executable or shared-object library.");
|
---|
| 115 |
|
---|
| 116 | return TRUE;
|
---|
| 117 | }
|
---|
| 118 |
|
---|
| 119 | static int readelfheader_64(int fd, Elf64_Ehdr *ehdr)
|
---|
| 120 | {
|
---|
| 121 | errno = 0;
|
---|
| 122 |
|
---|
| 123 | if (lseek(fd, 0, SEEK_SET))
|
---|
| 124 | return ferr("could not rewind file");
|
---|
| 125 |
|
---|
| 126 | if (read(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
|
---|
| 127 | return ferr("missing or incomplete ELF header.");
|
---|
| 128 |
|
---|
| 129 | /* Check the ELF signature.
|
---|
| 130 | */
|
---|
| 131 | if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 &&
|
---|
| 132 | ehdr->e_ident[EI_MAG1] == ELFMAG1 &&
|
---|
| 133 | ehdr->e_ident[EI_MAG2] == ELFMAG2 &&
|
---|
| 134 | ehdr->e_ident[EI_MAG3] == ELFMAG3))
|
---|
| 135 | return err("missing ELF signature.");
|
---|
| 136 |
|
---|
| 137 | /* Compare the file's class and endianness with the program's.
|
---|
| 138 | */
|
---|
| 139 | #ifdef ELF_DATA
|
---|
| 140 | if (ehdr->e_ident[EI_DATA] != ELF_DATA)
|
---|
| 141 | return err("ELF file has different endianness.");
|
---|
| 142 | #endif
|
---|
| 143 |
|
---|
| 144 | if (ehdr->e_ident[EI_CLASS] != ELFCLASS64)
|
---|
[1] | 145 | return err("ELF file has different word size.");
|
---|
| 146 |
|
---|
| 147 | /* Check the target architecture.
|
---|
| 148 | */
|
---|
[48] | 149 | #ifdef ELF_ARCH
|
---|
[1] | 150 | if (ehdr->e_machine != ELF_ARCH)
|
---|
| 151 | return err("ELF file created for different architecture.");
|
---|
[48] | 152 | #endif
|
---|
[1] | 153 |
|
---|
| 154 | /* Verify the sizes of the ELF header and the program segment
|
---|
| 155 | * header table entries.
|
---|
| 156 | */
|
---|
[48] | 157 | if (ehdr->e_ehsize != sizeof(Elf64_Ehdr))
|
---|
[1] | 158 | return err("unrecognized ELF header size.");
|
---|
[48] | 159 | if (ehdr->e_phentsize != sizeof(Elf64_Phdr))
|
---|
[1] | 160 | return err("unrecognized program segment header size.");
|
---|
| 161 |
|
---|
| 162 | /* Finally, check the file type.
|
---|
| 163 | */
|
---|
| 164 | if (ehdr->e_type != ET_EXEC && ehdr->e_type != ET_DYN)
|
---|
| 165 | return err("not an executable or shared-object library.");
|
---|
| 166 |
|
---|
| 167 | return TRUE;
|
---|
| 168 | }
|
---|
| 169 |
|
---|
| 170 | /* readphdrtable() loads the program segment header table into memory.
|
---|
| 171 | */
|
---|
[48] | 172 | static int readphdrtable_32(int fd, Elf32_Ehdr const *ehdr, Elf32_Phdr **phdrs)
|
---|
[1] | 173 | {
|
---|
| 174 | size_t size;
|
---|
| 175 |
|
---|
| 176 | if (!ehdr->e_phoff || !ehdr->e_phnum)
|
---|
| 177 | return err("ELF file has no program header table.");
|
---|
| 178 |
|
---|
| 179 | size = ehdr->e_phnum * sizeof **phdrs;
|
---|
| 180 | if (!(*phdrs = malloc(size)))
|
---|
| 181 | return err("Out of memory!");
|
---|
| 182 |
|
---|
| 183 | errno = 0;
|
---|
| 184 | if (read(fd, *phdrs, size) != (ssize_t)size)
|
---|
| 185 | return ferr("missing or incomplete program segment header table.");
|
---|
| 186 |
|
---|
| 187 | return TRUE;
|
---|
| 188 | }
|
---|
| 189 |
|
---|
[48] | 190 | static int readphdrtable_64(int fd, Elf64_Ehdr const *ehdr, Elf64_Phdr **phdrs)
|
---|
| 191 | {
|
---|
| 192 | size_t size;
|
---|
| 193 |
|
---|
| 194 | if (!ehdr->e_phoff || !ehdr->e_phnum)
|
---|
| 195 | return err("ELF file has no program header table.");
|
---|
| 196 |
|
---|
| 197 | size = ehdr->e_phnum * sizeof **phdrs;
|
---|
| 198 | if (!(*phdrs = malloc(size)))
|
---|
| 199 | return err("Out of memory!");
|
---|
| 200 |
|
---|
| 201 | errno = 0;
|
---|
| 202 | if (read(fd, *phdrs, size) != (ssize_t)size)
|
---|
| 203 | return ferr("missing or incomplete program segment header table.");
|
---|
| 204 |
|
---|
| 205 | return TRUE;
|
---|
| 206 | }
|
---|
| 207 |
|
---|
[1] | 208 | /* getmemorysize() determines the offset of the last byte of the file
|
---|
| 209 | * that is referenced by an entry in the program segment header table.
|
---|
| 210 | * (Anything in the file after that point is not used when the program
|
---|
| 211 | * is executing, and thus can be safely discarded.)
|
---|
| 212 | */
|
---|
[48] | 213 | static int getmemorysize_32(Elf32_Ehdr const *ehdr, Elf32_Phdr const *phdrs,
|
---|
| 214 | unsigned long *newsize)
|
---|
[1] | 215 | {
|
---|
[48] | 216 | Elf32_Phdr const *phdr;
|
---|
[1] | 217 | unsigned long size, n;
|
---|
| 218 | int i;
|
---|
| 219 |
|
---|
| 220 | /* Start by setting the size to include the ELF header and the
|
---|
| 221 | * complete program segment header table.
|
---|
| 222 | */
|
---|
| 223 | size = ehdr->e_phoff + ehdr->e_phnum * sizeof *phdrs;
|
---|
| 224 | if (size < sizeof *ehdr)
|
---|
| 225 | size = sizeof *ehdr;
|
---|
| 226 |
|
---|
| 227 | /* Then keep extending the size to include whatever data the
|
---|
| 228 | * program segment header table references.
|
---|
| 229 | */
|
---|
| 230 | for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
|
---|
| 231 | if (phdr->p_type != PT_NULL) {
|
---|
| 232 | n = phdr->p_offset + phdr->p_filesz;
|
---|
| 233 | if (n > size)
|
---|
| 234 | size = n;
|
---|
| 235 | }
|
---|
| 236 | }
|
---|
| 237 |
|
---|
| 238 | *newsize = size;
|
---|
| 239 | return TRUE;
|
---|
| 240 | }
|
---|
| 241 |
|
---|
[48] | 242 | static int getmemorysize_64(Elf64_Ehdr const *ehdr, Elf64_Phdr const *phdrs,
|
---|
| 243 | unsigned long *newsize)
|
---|
| 244 | {
|
---|
| 245 | Elf64_Phdr const *phdr;
|
---|
| 246 | unsigned long size, n;
|
---|
| 247 | int i;
|
---|
| 248 |
|
---|
| 249 | /* Start by setting the size to include the ELF header and the
|
---|
| 250 | * complete program segment header table.
|
---|
| 251 | */
|
---|
| 252 | size = ehdr->e_phoff + ehdr->e_phnum * sizeof *phdrs;
|
---|
| 253 | if (size < sizeof *ehdr)
|
---|
| 254 | size = sizeof *ehdr;
|
---|
| 255 |
|
---|
| 256 | /* Then keep extending the size to include whatever data the
|
---|
| 257 | * program segment header table references.
|
---|
| 258 | */
|
---|
| 259 | for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
|
---|
| 260 | if (phdr->p_type != PT_NULL) {
|
---|
| 261 | n = phdr->p_offset + phdr->p_filesz;
|
---|
| 262 | if (n > size)
|
---|
| 263 | size = n;
|
---|
| 264 | }
|
---|
| 265 | }
|
---|
| 266 |
|
---|
| 267 | *newsize = size;
|
---|
| 268 | return TRUE;
|
---|
| 269 | }
|
---|
| 270 |
|
---|
[1] | 271 | /* truncatezeros() examines the bytes at the end of the file's
|
---|
| 272 | * size-to-be, and reduces the size to exclude any trailing zero
|
---|
| 273 | * bytes.
|
---|
| 274 | */
|
---|
| 275 | static int truncatezeros(int fd, unsigned long *newsize)
|
---|
| 276 | {
|
---|
| 277 | unsigned char contents[1024];
|
---|
| 278 | unsigned long size, n;
|
---|
| 279 |
|
---|
| 280 | size = *newsize;
|
---|
| 281 | do {
|
---|
| 282 | n = sizeof contents;
|
---|
| 283 | if (n > size)
|
---|
| 284 | n = size;
|
---|
| 285 | if (lseek(fd, size - n, SEEK_SET) == (off_t)-1)
|
---|
| 286 | return ferr("cannot seek in file.");
|
---|
| 287 | if (read(fd, contents, n) != (ssize_t)n)
|
---|
| 288 | return ferr("cannot read file contents");
|
---|
| 289 | while (n && !contents[--n])
|
---|
| 290 | --size;
|
---|
| 291 | } while (size && !n);
|
---|
| 292 |
|
---|
| 293 | /* Sanity check.
|
---|
| 294 | */
|
---|
| 295 | if (!size)
|
---|
| 296 | return err("ELF file is completely blank!");
|
---|
| 297 |
|
---|
| 298 | *newsize = size;
|
---|
| 299 | return TRUE;
|
---|
| 300 | }
|
---|
| 301 |
|
---|
| 302 | /* modifyheaders() removes references to the section header table if
|
---|
| 303 | * it was stripped, and reduces program header table entries that
|
---|
| 304 | * included truncated bytes at the end of the file.
|
---|
| 305 | */
|
---|
[48] | 306 | static int modifyheaders_32(Elf32_Ehdr *ehdr, Elf32_Phdr *phdrs,
|
---|
| 307 | unsigned long newsize)
|
---|
[1] | 308 | {
|
---|
[48] | 309 | Elf32_Phdr *phdr;
|
---|
| 310 | int i;
|
---|
[1] | 311 |
|
---|
| 312 | /* If the section header table is gone, then remove all references
|
---|
| 313 | * to it in the ELF header.
|
---|
| 314 | */
|
---|
| 315 | if (ehdr->e_shoff >= newsize) {
|
---|
| 316 | ehdr->e_shoff = 0;
|
---|
| 317 | ehdr->e_shnum = 0;
|
---|
| 318 | ehdr->e_shentsize = 0;
|
---|
| 319 | ehdr->e_shstrndx = 0;
|
---|
| 320 | }
|
---|
| 321 |
|
---|
| 322 | /* The program adjusts the file size of any segment that was
|
---|
| 323 | * truncated. The case of a segment being completely stripped out
|
---|
| 324 | * is handled separately.
|
---|
| 325 | */
|
---|
| 326 | for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
|
---|
| 327 | if (phdr->p_offset >= newsize) {
|
---|
| 328 | phdr->p_offset = newsize;
|
---|
| 329 | phdr->p_filesz = 0;
|
---|
| 330 | } else if (phdr->p_offset + phdr->p_filesz > newsize) {
|
---|
| 331 | phdr->p_filesz = newsize - phdr->p_offset;
|
---|
| 332 | }
|
---|
| 333 | }
|
---|
| 334 |
|
---|
| 335 | return TRUE;
|
---|
| 336 | }
|
---|
| 337 |
|
---|
[48] | 338 | static int modifyheaders_64(Elf64_Ehdr *ehdr, Elf64_Phdr *phdrs,
|
---|
| 339 | unsigned long newsize)
|
---|
| 340 | {
|
---|
| 341 | Elf64_Phdr *phdr;
|
---|
| 342 | int i;
|
---|
| 343 |
|
---|
| 344 | /* If the section header table is gone, then remove all references
|
---|
| 345 | * to it in the ELF header.
|
---|
| 346 | */
|
---|
| 347 | if (ehdr->e_shoff >= newsize) {
|
---|
| 348 | ehdr->e_shoff = 0;
|
---|
| 349 | ehdr->e_shnum = 0;
|
---|
| 350 | ehdr->e_shentsize = 0;
|
---|
| 351 | ehdr->e_shstrndx = 0;
|
---|
| 352 | }
|
---|
| 353 |
|
---|
| 354 | /* The program adjusts the file size of any segment that was
|
---|
| 355 | * truncated. The case of a segment being completely stripped out
|
---|
| 356 | * is handled separately.
|
---|
| 357 | */
|
---|
| 358 | for (i = 0, phdr = phdrs ; i < ehdr->e_phnum ; ++i, ++phdr) {
|
---|
| 359 | if (phdr->p_offset >= newsize) {
|
---|
| 360 | phdr->p_offset = newsize;
|
---|
| 361 | phdr->p_filesz = 0;
|
---|
| 362 | } else if (phdr->p_offset + phdr->p_filesz > newsize) {
|
---|
| 363 | phdr->p_filesz = newsize - phdr->p_offset;
|
---|
| 364 | }
|
---|
| 365 | }
|
---|
| 366 |
|
---|
| 367 | return TRUE;
|
---|
| 368 | }
|
---|
| 369 |
|
---|
[1] | 370 | /* commitchanges() writes the new headers back to the original file
|
---|
| 371 | * and sets the file to its new size.
|
---|
| 372 | */
|
---|
[48] | 373 | static int commitchanges_32(int fd, Elf32_Ehdr const *ehdr, Elf32_Phdr *phdrs,
|
---|
| 374 | unsigned long newsize)
|
---|
[1] | 375 | {
|
---|
| 376 | size_t n;
|
---|
| 377 |
|
---|
| 378 | /* Save the changes to the ELF header, if any.
|
---|
| 379 | */
|
---|
| 380 | if (lseek(fd, 0, SEEK_SET))
|
---|
| 381 | return ferr("could not rewind file");
|
---|
| 382 | errno = 0;
|
---|
| 383 | if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
|
---|
| 384 | return err("could not modify file");
|
---|
| 385 |
|
---|
| 386 | /* Save the changes to the program segment header table, if any.
|
---|
| 387 | */
|
---|
| 388 | if (lseek(fd, ehdr->e_phoff, SEEK_SET) == (off_t)-1) {
|
---|
| 389 | err("could not seek in file.");
|
---|
| 390 | goto warning;
|
---|
| 391 | }
|
---|
| 392 | n = ehdr->e_phnum * sizeof *phdrs;
|
---|
| 393 | if (write(fd, phdrs, n) != (ssize_t)n) {
|
---|
| 394 | err("could not write to file");
|
---|
| 395 | goto warning;
|
---|
| 396 | }
|
---|
| 397 |
|
---|
| 398 | /* Eleventh-hour sanity check: don't truncate before the end of
|
---|
| 399 | * the program segment header table.
|
---|
| 400 | */
|
---|
| 401 | if (newsize < ehdr->e_phoff + n)
|
---|
| 402 | newsize = ehdr->e_phoff + n;
|
---|
| 403 |
|
---|
| 404 | /* Chop off the end of the file.
|
---|
| 405 | */
|
---|
| 406 | if (ftruncate(fd, newsize)) {
|
---|
| 407 | err("could not resize file");
|
---|
| 408 | goto warning;
|
---|
| 409 | }
|
---|
| 410 |
|
---|
| 411 | return TRUE;
|
---|
| 412 |
|
---|
| 413 | warning:
|
---|
| 414 | return err("ELF file may have been corrupted!");
|
---|
| 415 | }
|
---|
| 416 |
|
---|
[48] | 417 | static int commitchanges_64(int fd, Elf64_Ehdr const *ehdr, Elf64_Phdr *phdrs,
|
---|
| 418 | unsigned long newsize)
|
---|
| 419 | {
|
---|
| 420 | size_t n;
|
---|
| 421 |
|
---|
| 422 | /* Save the changes to the ELF header, if any.
|
---|
| 423 | */
|
---|
| 424 | if (lseek(fd, 0, SEEK_SET))
|
---|
| 425 | return ferr("could not rewind file");
|
---|
| 426 | errno = 0;
|
---|
| 427 | if (write(fd, ehdr, sizeof *ehdr) != sizeof *ehdr)
|
---|
| 428 | return err("could not modify file");
|
---|
| 429 |
|
---|
| 430 | /* Save the changes to the program segment header table, if any.
|
---|
| 431 | */
|
---|
| 432 | if (lseek(fd, ehdr->e_phoff, SEEK_SET) == (off_t)-1) {
|
---|
| 433 | err("could not seek in file.");
|
---|
| 434 | goto warning;
|
---|
| 435 | }
|
---|
| 436 | n = ehdr->e_phnum * sizeof *phdrs;
|
---|
| 437 | if (write(fd, phdrs, n) != (ssize_t)n) {
|
---|
| 438 | err("could not write to file");
|
---|
| 439 | goto warning;
|
---|
| 440 | }
|
---|
| 441 |
|
---|
| 442 | /* Eleventh-hour sanity check: don't truncate before the end of
|
---|
| 443 | * the program segment header table.
|
---|
| 444 | */
|
---|
| 445 | if (newsize < ehdr->e_phoff + n)
|
---|
| 446 | newsize = ehdr->e_phoff + n;
|
---|
| 447 |
|
---|
| 448 | /* Chop off the end of the file.
|
---|
| 449 | */
|
---|
| 450 | if (ftruncate(fd, newsize)) {
|
---|
| 451 | err("could not resize file");
|
---|
| 452 | goto warning;
|
---|
| 453 | }
|
---|
| 454 |
|
---|
| 455 | return TRUE;
|
---|
| 456 |
|
---|
| 457 | warning:
|
---|
| 458 | return err("ELF file may have been corrupted!");
|
---|
| 459 | }
|
---|
| 460 |
|
---|
[1] | 461 | /* main() loops over the cmdline arguments, leaving all the real work
|
---|
| 462 | * to the other functions.
|
---|
| 463 | */
|
---|
| 464 | int main(int argc, char *argv[])
|
---|
| 465 | {
|
---|
| 466 | int fd;
|
---|
[48] | 467 | int is_32bit_elf;
|
---|
| 468 | Elf32_Ehdr ehdr32;
|
---|
| 469 | Elf32_Phdr *phdrs32 = NULL;
|
---|
| 470 | Elf64_Ehdr ehdr64;
|
---|
| 471 | Elf64_Phdr *phdrs64 = NULL;
|
---|
[1] | 472 | unsigned long newsize;
|
---|
| 473 | char **arg;
|
---|
| 474 | int failures = 0;
|
---|
| 475 |
|
---|
| 476 | if (argc < 2 || argv[1][0] == '-') {
|
---|
| 477 | printf("Usage: sstrip FILE...\n"
|
---|
| 478 | "sstrip discards all nonessential bytes from an executable.\n\n"
|
---|
| 479 | "Version 2.0 Copyright (C) 2000,2001 Brian Raiter.\n"
|
---|
| 480 | "This program is free software, licensed under the GNU\n"
|
---|
| 481 | "General Public License. There is absolutely no warranty.\n");
|
---|
| 482 | return EXIT_SUCCESS;
|
---|
| 483 | }
|
---|
| 484 |
|
---|
| 485 | progname = argv[0];
|
---|
| 486 |
|
---|
| 487 | for (arg = argv + 1 ; *arg != NULL ; ++arg) {
|
---|
| 488 | filename = *arg;
|
---|
| 489 |
|
---|
| 490 | fd = open(*arg, O_RDWR);
|
---|
| 491 | if (fd < 0) {
|
---|
| 492 | ferr("can't open");
|
---|
| 493 | ++failures;
|
---|
| 494 | continue;
|
---|
| 495 | }
|
---|
| 496 |
|
---|
[48] | 497 | if (readelfheader_32(fd, &ehdr32)) {
|
---|
| 498 | is_32bit_elf = TRUE;
|
---|
| 499 | }
|
---|
| 500 | else if (readelfheader_64(fd, &ehdr64)) {
|
---|
| 501 | is_32bit_elf = FALSE;
|
---|
| 502 | }
|
---|
| 503 | else {
|
---|
| 504 | close(fd);
|
---|
| 505 | return EXIT_FAILURE;
|
---|
| 506 | }
|
---|
| 507 |
|
---|
| 508 | if (is_32bit_elf) {
|
---|
| 509 | if (!(readphdrtable_32(fd, &ehdr32, &phdrs32) &&
|
---|
| 510 | getmemorysize_32(&ehdr32, phdrs32, &newsize) &&
|
---|
| 511 | truncatezeros(fd, &newsize) &&
|
---|
| 512 | modifyheaders_32(&ehdr32, phdrs32, newsize) &&
|
---|
| 513 | commitchanges_32(fd, &ehdr32, phdrs32, newsize)))
|
---|
[1] | 514 | ++failures;
|
---|
[48] | 515 | }
|
---|
| 516 | else {
|
---|
| 517 | if (!(readphdrtable_64(fd, &ehdr64, &phdrs64) &&
|
---|
| 518 | getmemorysize_64(&ehdr64, phdrs64, &newsize) &&
|
---|
| 519 | truncatezeros(fd, &newsize) &&
|
---|
| 520 | modifyheaders_64(&ehdr64, phdrs64, newsize) &&
|
---|
| 521 | commitchanges_64(fd, &ehdr64, phdrs64, newsize)))
|
---|
| 522 | ++failures;
|
---|
| 523 | }
|
---|
[1] | 524 |
|
---|
| 525 | close(fd);
|
---|
| 526 | }
|
---|
| 527 |
|
---|
| 528 | return failures ? EXIT_FAILURE : EXIT_SUCCESS;
|
---|
| 529 | }
|
---|
| 530 |
|
---|
| 531 | #else
|
---|
| 532 |
|
---|
| 533 | int main()
|
---|
| 534 | {
|
---|
| 535 | return (EXIT_SUCCESS);
|
---|
| 536 | }
|
---|
| 537 |
|
---|
| 538 | #endif
|
---|