📄 sstrip.c
字号:
* to it in the ELF header. \ */ \ if (EGET(ehdr->e_shoff) >= newsize) { \ ESET(ehdr->e_shoff,0); \ ESET(ehdr->e_shnum,0); \ ESET(ehdr->e_shentsize,sizeof(Elf ## CLASS ## _Shdr)); \ ESET(ehdr->e_shstrndx,0); \ } \ \ /* The program adjusts the file size of any segment that was \ * truncated. The case of a segment being completely stripped out \ * is handled separately. \ */ \ for (i = 0, phdr = phdrs ; i < EGET(ehdr->e_phnum) ; ++i, ++phdr) { \ if (EGET(phdr->p_offset) >= newsize) { \ ESET(phdr->p_offset,newsize); \ ESET(phdr->p_filesz,0); \ } else if (EGET(phdr->p_offset) + EGET(phdr->p_filesz) > newsize) { \ newsize -= EGET(phdr->p_offset); \ ESET(phdr->p_filesz, newsize); \ } \ } \ \ return TRUE; \} \ \/* commitchanges() writes the new headers back to the original file \ * and sets the file to its new size. \ */ \static int commitchanges ## CLASS (int fd, Elf ## CLASS ## _Ehdr const *ehdr, \ Elf ## CLASS ## _Phdr *phdrs, \ unsigned long newsize) \{ \ size_t n; \ \ /* Save the changes to the ELF header, if any. \ */ \ if (lseek(fd, 0, SEEK_SET)) \ return ferr("could not rewind file"); \ errno = 0; \ if (write(fd, ehdr, sizeof *ehdr) != (ssize_t)sizeof *ehdr) \ return err("could not modify file"); \ \ /* Save the changes to the program segment header table, if any. \ */ \ if (lseek(fd, EGET(ehdr->e_phoff), SEEK_SET) == (off_t)-1) { \ err("could not seek in file."); \ goto warning; \ } \ n = EGET(ehdr->e_phnum) * sizeof *phdrs; \ if (write(fd, phdrs, n) != (ssize_t)n) { \ err("could not write to file"); \ goto warning; \ } \ \ /* Eleventh-hour sanity check: don't truncate before the end of \ * the program segment header table. \ */ \ if (newsize < EGET(ehdr->e_phoff) + n) \ newsize = EGET(ehdr->e_phoff) + n; \ \ /* Chop off the end of the file. \ */ \ if (ftruncate(fd, newsize)) { \ err("could not resize file"); \ goto warning; \ } \ \ return TRUE; \ \ warning: \ return err("ELF file may have been corrupted!"); \}/* First elements of Elf32_Ehdr and Elf64_Ehdr are common. */static int readelfheaderident(int fd, Elf32_Ehdr *ehdr){ errno = 0; if (read(fd, ehdr, EI_NIDENT) != EI_NIDENT) return ferr("missing or incomplete ELF header."); /* Check the ELF signature. */ if (!(ehdr->e_ident[EI_MAG0] == ELFMAG0 && ehdr->e_ident[EI_MAG1] == ELFMAG1 && ehdr->e_ident[EI_MAG2] == ELFMAG2 && ehdr->e_ident[EI_MAG3] == ELFMAG3)) { err("missing ELF signature."); return -1; } /* Compare the file's class and endianness with the program's. */#if __BYTE_ORDER == __LITTLE_ENDIAN if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) { do_reverse_endian = 0; } else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) {/* fprintf(stderr, "ELF file has different endianness.\n"); */ do_reverse_endian = 1; }#elif __BYTE_ORDER == __BIG_ENDIAN if (ehdr->e_ident[EI_DATA] == ELFDATA2LSB) {/* fprintf(stderr, "ELF file has different endianness.\n"); */ do_reverse_endian = 1; } else if (ehdr->e_ident[EI_DATA] == ELFDATA2MSB) { do_reverse_endian = 0; }#else#error unkown endianness#endif else { err("Unsupported endianness"); return -1; } /* Check the target architecture. *//* if (EGET(ehdr->e_machine) != ELF_ARCH) { *//* /\* return err("ELF file created for different architecture."); *\/ *//* fprintf(stderr, "ELF file created for different architecture.\n"); *//* } */ return ehdr->e_ident[EI_CLASS];}HEADER_FUNCTIONS(32)HEADER_FUNCTIONS(64)/* truncatezeros() examines the bytes at the end of the file's * size-to-be, and reduces the size to exclude any trailing zero * bytes. */static int truncatezeros(int fd, unsigned long *newsize){ unsigned char contents[1024]; unsigned long size, n; size = *newsize; do { n = sizeof contents; if (n > size) n = size; if (lseek(fd, size - n, SEEK_SET) == (off_t)-1) return ferr("cannot seek in file."); if (read(fd, contents, n) != (ssize_t)n) return ferr("cannot read file contents"); while (n && !contents[--n]) --size; } while (size && !n); /* Sanity check. */ if (!size) return err("ELF file is completely blank!"); *newsize = size; return TRUE;}/* main() loops over the cmdline arguments, leaving all the real work * to the other functions. */int main(int argc, char *argv[]){ int fd; union { Elf32_Ehdr ehdr32; Elf64_Ehdr ehdr64; } e; union { Elf32_Phdr *phdrs32; Elf64_Phdr *phdrs64; } p; unsigned long newsize; char **arg; int failures = 0; if (argc < 2 || argv[1][0] == '-') { printf("Usage: sstrip FILE...\n" "sstrip discards all nonessential bytes from an executable.\n\n" "Version 2.0-X Copyright (C) 2000,2001 Brian Raiter.\n" "Cross-devel hacks Copyright (C) 2004 Manuel Novoa III.\n" "This program is free software, licensed under the GNU\n" "General Public License. There is absolutely no warranty.\n"); return EXIT_SUCCESS; } progname = argv[0]; for (arg = argv + 1 ; *arg != NULL ; ++arg) { filename = *arg; fd = open(*arg, O_RDWR); if (fd < 0) { ferr("can't open"); ++failures; continue; } switch (readelfheaderident(fd, &e.ehdr32)) { case ELFCLASS32: if (!(readelfheader32(fd, &e.ehdr32) && readphdrtable32(fd, &e.ehdr32, &p.phdrs32) && getmemorysize32(&e.ehdr32, p.phdrs32, &newsize) && truncatezeros(fd, &newsize) && modifyheaders32(&e.ehdr32, p.phdrs32, newsize) && commitchanges32(fd, &e.ehdr32, p.phdrs32, newsize))) ++failures; break; case ELFCLASS64: if (!(readelfheader64(fd, &e.ehdr64) && readphdrtable64(fd, &e.ehdr64, &p.phdrs64) && getmemorysize64(&e.ehdr64, p.phdrs64, &newsize) && truncatezeros(fd, &newsize) && modifyheaders64(&e.ehdr64, p.phdrs64, newsize) && commitchanges64(fd, &e.ehdr64, p.phdrs64, newsize))) ++failures; break; default: ++failures; break; } close(fd); } return failures ? EXIT_FAILURE : EXIT_SUCCESS;}/*vi:ts=4:et:nowrap*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -