diff options
Diffstat (limited to 'distrib')
-rw-r--r-- | distrib/crunch/crunchide/Makefile | 2 | ||||
-rw-r--r-- | distrib/crunch/crunchide/crunchide.c | 20 | ||||
-rw-r--r-- | distrib/crunch/crunchide/elf_hide.c | 445 |
3 files changed, 466 insertions, 1 deletions
diff --git a/distrib/crunch/crunchide/Makefile b/distrib/crunch/crunchide/Makefile index f6e1a8a4526..08ab814ac82 100644 --- a/distrib/crunch/crunchide/Makefile +++ b/distrib/crunch/crunchide/Makefile @@ -1,4 +1,4 @@ - PROG= crunchide +SRCS=crunchide.c elf_hide.c .include <bsd.prog.mk> diff --git a/distrib/crunch/crunchide/crunchide.c b/distrib/crunch/crunchide/crunchide.c index 30d924697a7..2b34454440a 100644 --- a/distrib/crunch/crunchide/crunchide.c +++ b/distrib/crunch/crunchide/crunchide.c @@ -214,6 +214,7 @@ void hide_syms(char *filename) struct stat infstat; struct relocation_info *relp; struct nlist *symp; + char buf[4]; /* * Open the file and do some error checking. @@ -236,6 +237,25 @@ void hide_syms(char *filename) return; } + if((rc = read(inf, &buf, 4)) < 4) { + fprintf(stderr, "%s: read error: %s\n", filename, + rc == -1? strerror(errno) : "short read"); + close(inf); + return; + } + + if (buf[0] == 0x7f && + (buf[1] == 'E' || buf[1] == 'O') && + buf[2] == 'L' && + buf[3] == 'F') + { + + printf("processing elf/olf file\n"); + elf_hide(inf); + return; + } + + /* * Read the entire file into memory. XXX - Really, we only need to * read the header and from TRELOFF to the end of the file. diff --git a/distrib/crunch/crunchide/elf_hide.c b/distrib/crunch/crunchide/elf_hide.c new file mode 100644 index 00000000000..37e98522d69 --- /dev/null +++ b/distrib/crunch/crunchide/elf_hide.c @@ -0,0 +1,445 @@ +/* $OpenBSD: elf_hide.c,v 1.1 1997/01/09 04:16:52 rahnds Exp $ */ + +/* + * Copyright (c) 1997 Dale Rahn. All rights reserved. + * + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by Dale Rahn. + * 4. The name of the author may not be used to endorse or promote products + * derived from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES + * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. + * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include <sys/types.h> +#include <sys/mman.h> +#include <sys/stat.h> +#include <fcntl.h> +#include <unistd.h> +#include <stdio.h> +#include <assert.h> +#include <sys/exec_elf.h> + +void load_strtab(Elf32_Ehdr *pehdr, char *pexe); +void dump_strtab(); +char *get_str(int indx); + +void load_symtab(Elf32_Ehdr *pehdr, char *pexe); +void dump_symtab(); + +void load_shstr_tab(Elf32_Ehdr *pehdr, char *pexe); +char *get_shstr(int indx); +void fprint_shstr(FILE * channel, int indx); + +void hide_sym(); + +void reorder_syms(Elf32_Ehdr *ehdr, Elf32_Shdr *symsect, + Elf32_Sym *symtab, int symtabsize, int symtabsecnum); + +typedef int Symmap; + +void renum_reloc_syms(Elf32_Ehdr *ehdr, Symmap *symmap, int symtabsecnum); + +char * pexe; +elf_hide(int pfile) +{ + int i; + + Elf32_Ehdr *pehdr; + Elf32_Shdr *pshdr; + Elf32_Phdr *pphdr; + struct stat sb; + + fstat(pfile, &sb); + pexe = mmap(0, sb.st_size, PROT_READ|PROT_WRITE, + MAP_FILE | MAP_SHARED, pfile, 0); + + pehdr = (Elf32_Ehdr *)pexe; + +#ifdef DEBUG + printf("elf header\n"); + printf("e_type %x\n", pehdr->e_type); + printf("e_machine %x\n", pehdr->e_machine); + printf("e_version %x\n", pehdr->e_version); + printf("e_entry %x\n", pehdr->e_entry); + printf("e_phoff %x\n", pehdr->e_phoff); + printf("e_shoff %x\n", pehdr->e_shoff); + printf("e_flags %x\n", pehdr->e_flags); + printf("e_ehsize %x\n", pehdr->e_ehsize); + printf("e_phentsize %x\n", pehdr->e_phentsize); + printf("e_phnum %x\n", pehdr->e_phnum); + printf("e_shentsize %x\n", pehdr->e_shentsize); + printf("e_shnum %x\n", pehdr->e_shnum); + printf("e_shstrndx %x\n", pehdr->e_shstrndx); +#endif + + load_shstr_tab(pehdr, pexe); +#ifdef DEBUG + for (i = 0; i < pehdr->e_shnum; i++) { + pshdr = (Elf32_Phdr *) (pexe + pehdr->e_shoff + + (i * pehdr->e_shentsize)); + + printf("section header %d\n",i); + printf("sh_name %x ", pshdr->sh_name); + fprint_shstr(stdout, pshdr->sh_name); + printf("\n"); + printf("sh_type %x\n", pshdr->sh_type); + printf("sh_flags %x\n", pshdr->sh_flags); + printf("sh_addr %x\n", pshdr->sh_addr); + printf("sh_offset %x\n", pshdr->sh_offset); + printf("sh_size %x\n", pshdr->sh_size); + printf("sh_link %x\n", pshdr->sh_link); + printf("sh_info %x\n", pshdr->sh_info); + printf("sh_addralign %x\n", pshdr->sh_addralign); + printf("sh_entsize %x\n", pshdr->sh_entsize); + } +#endif /* DEBUG */ + +#ifdef DEBUG + for (i = 0; i < pehdr->e_phnum; i++) { + pshdr = (Elf32_Phdr *) (pexe + pehdr->e_phoff + + (i * pehdr->e_phentsize); + + printf("program header %d\n", i); + printf("p_type %x\n", pphdr->p_type); + printf("p_offset %x\n", pphdr->p_offset); + printf("p_vaddr %x\n", pphdr->p_vaddr); + printf("p_paddr %x\n", pphdr->p_paddr); + printf("p_filesz %x\n", pphdr->p_filesz); + printf("p_memsz %x\n", pphdr->p_memsz); + printf("p_flags %x\n", pphdr->p_flags); + printf("p_align %x\n", pphdr->p_align); + } +#endif /* DEBUG */ +#if 0 + for (i = 0; i < pehdr->e_shnum; i++) { + pshdr = (Elf32_Phdr *) (pexe + pehdr->e_shoff + + (i * pehdr->e_shentsize); + if (0 == strcmp(".strtab", get_shstr(pshdr->sh_name))) { + break; + } + } + fprint_shstr(stdout, pshdr->sh_name); + printf("\n"); +#endif + + load_strtab(pehdr, pexe); + load_symtab(pehdr, pexe); + + munmap(pexe, sb.st_size); + close (pfile); +} +char *shstrtab; + +void +load_shstr_tab(Elf32_Ehdr *pehdr, char *pexe) +{ + Elf32_Shdr *pshdr; + shstrtab = NULL; + if (pehdr->e_shstrndx == 0) { + return; + } + pshdr = (Elf32_Shdr *)(pexe + pehdr->e_shoff + + (pehdr->e_shstrndx * pehdr->e_shentsize)); + + shstrtab = (char *)(pexe + pshdr->sh_offset); +} + +void +fprint_shstr(FILE * channel, int indx) +{ + if (shstrtab != NULL) { + fprintf(channel, "\"%s\"", &(shstrtab[indx])); + } + return; +} + +char * +get_shstr(int indx) +{ + return &(shstrtab[indx]); +} + +void +load_symtab(Elf32_Ehdr *pehdr, char *pexe) +{ + Elf32_Sym *symtab; + Elf32_Shdr *symsect; + int symtabsize; + Elf32_Shdr *pshdr; + Elf32_Shdr *psymshdr; + char *shname; + int i; + symtab = NULL; + for (i = 0; i < pehdr->e_shnum; i++) { + pshdr = (Elf32_Shdr *)(pexe + pehdr->e_shoff + + (i * pehdr->e_shentsize) ); + if (SHT_REL != pshdr->sh_type && SHT_RELA != pshdr->sh_type){ + continue; + } + psymshdr = (Elf32_Shdr *)(pexe + pehdr->e_shoff + + (pshdr->sh_link * pehdr->e_shentsize) ); +#ifdef DEBUG + fprint_shstr(stdout, pshdr->sh_name); + printf("\n"); +#endif + symtab = (Elf32_Sym *)(pexe + psymshdr->sh_offset); + symsect = psymshdr; + symtabsize = psymshdr->sh_size; + +#ifdef DEBUG + dump_symtab(symsect, symtab, symtabsize); +#endif + hide_sym(pehdr, symsect, symtab, symtabsize, pshdr->sh_link); + } + +} + +void +dump_symtab (Elf32_Shdr *symsect, Elf32_Sym *symtab, int symtabsize) +{ + int i; + Elf32_Sym *psymtab; + + for (i = 0 ; i < (symtabsize/sizeof(Elf32_Sym)); i++) { + psymtab = &(symtab[i]); + if ((psymtab->st_info & 0xf0) == 0x10 && + (psymtab->st_shndx != SHN_UNDEF)) { + printf("symbol %d:\n", i); + printf("st_name %x \"%s\"\n", psymtab->st_name, + get_str(psymtab->st_name)); + printf("st_value %x\n", psymtab->st_value); + printf("st_size %x\n", psymtab->st_size); + printf("st_info %x\n", psymtab->st_info); + printf("st_other %x\n", psymtab->st_other); + printf("st_shndx %x\n", psymtab->st_shndx); + } + } +} + +char * strtab; +int strtabsize; +void +load_strtab(Elf32_Ehdr *pehdr, char *pexe) +{ + Elf32_Shdr *pshdr; + char *shname; + int i; + strtab = NULL; + for (i = 0; i < pehdr->e_shnum; i++) { + pshdr = (Elf32_Shdr *) (pexe + pehdr->e_shoff + + (i * pehdr->e_shentsize)); + + shname = get_shstr(pshdr->sh_name); + if (0 == strcmp(".strtab", shname)) { + break; + } + } +#ifdef DEBUG + fprint_shstr(stdout, pshdr->sh_name); + printf("\n"); +#endif + + strtab = (char *) (pexe + pshdr->sh_offset); + + strtabsize = pshdr->sh_size; + +#ifdef DEBUG + dump_strtab(); +#endif +} + +void +dump_strtab() +{ + int index; + char *pstr; + char *pnstr; + int i = 0; + index = 0; + pstr = strtab; + while (index < strtabsize) { + printf("string %x: \"%s\"\n",i, pstr); + pnstr = (char *) ((int)strchr(pstr, '\0') + 1); + index = pnstr - strtab; + pstr = pnstr; + i++; + } + +} +fprint_str(FILE * channel, int indx) +{ + if (strtab != NULL) { + fprintf(channel, "\"%s\"", &(strtab[indx])); + } + return; +} +char * +get_str(int indx) +{ + return &(strtab[indx]); +} + +int in_keep_list(char *symbol); + +void +hide_sym(Elf32_Ehdr *ehdr, Elf32_Shdr *symsect, + Elf32_Sym *symtab, int symtabsize, int symtabsecnum) +{ + int i; + unsigned char info; + Elf32_Sym *psymtab; + + for (i = 0 ; i < (symtabsize/sizeof(Elf32_Sym)); i++) { + psymtab = &(symtab[i]); + if ((psymtab->st_info & 0xf0) == 0x10 && + (psymtab->st_shndx != SHN_UNDEF)) { + if (in_keep_list(get_str(psymtab->st_name))) { + continue; + } +#ifdef DEBUG + printf("symbol %d:\n", i); + printf("st_name %x \"%s\"\n", psymtab->st_name, + get_str(psymtab->st_name)); + printf("st_info %x\n", psymtab->st_info); +#endif + info = psymtab->st_info; + info = info & 0xf; + psymtab->st_info = info; +#ifdef DEBUG + printf("st_info %x\n", psymtab->st_info); +#endif + } + } +#ifdef DEBUG +#endif + reorder_syms(ehdr, symsect, symtab, symtabsize, symtabsecnum); +} +void +reorder_syms(Elf32_Ehdr *ehdr, Elf32_Shdr *symsect, + Elf32_Sym *symtab, int symtabsize, int symtabsecnum) +{ + int i; + int nsyms; + int cursym; + Elf32_Sym *tmpsymtab; + Symmap *symmap; + + + nsyms = symtabsize / sizeof(Elf32_Sym); + + tmpsymtab = (Elf32_Sym *)malloc(symtabsize); + symmap = (Symmap *)malloc( sizeof(Symmap) * (nsyms)); + + assert (NULL != tmpsymtab); + + bcopy (symtab, tmpsymtab, symtabsize); + + cursym = 1; + for (i = 1; i < nsyms; i++) { + if ((tmpsymtab[i].st_info & 0xf0) == 0x00) { +#ifdef DEBUG + printf("copying l o%d n%d <%s>\n",i, cursym, + get_str(tmpsymtab[i].st_name)); +#endif + bcopy (&(tmpsymtab[i]), + &(symtab[cursym]), sizeof(Elf32_Sym)); + symmap[i] = cursym; + cursym++; + } + } + symsect->sh_info = cursym; + for (i = 1; i < nsyms; i++) { + if ((tmpsymtab[i].st_info & 0xf0) != 0x00) { +#ifdef DEBUG + printf("copying nl o%d n%d <%s>\n",i, cursym, + get_str(tmpsymtab[i].st_name)); +#endif + bcopy (&(tmpsymtab[i]), + &(symtab[cursym]), sizeof(Elf32_Sym)); + symmap[i] = cursym; + cursym++; + } + } + if (cursym != nsyms) { + printf("miscounted symbols somewhere c %d n %d \n", + cursym, nsyms); + exit (5); + } + renum_reloc_syms(ehdr, symmap, symtabsecnum); + free (tmpsymtab); + free (symmap); +} +void +renum_reloc_syms(Elf32_Ehdr *ehdr, Symmap *symmap, int symtabsecnum) +{ + Elf32_Shdr *pshdr; + int i, j; + int num_reloc; + Elf32_Rel *prel; + Elf32_Rela *prela; + int symnum; + + for (i = 0; i < ehdr->e_shnum; i++) { + pshdr = (Elf32_Shdr *)(pexe + ehdr->e_shoff + + (i * ehdr->e_shentsize) ); + if ((pshdr->sh_type == SHT_RELA) && + pshdr->sh_link == symtabsecnum) + { + +#ifdef DEBUG + printf ("section %d has rela relocations in symtab\n", i); +#endif + prela = (Elf32_Rela *)(pexe + pshdr->sh_offset); + num_reloc = pshdr->sh_size /sizeof (Elf32_Rela); + for (j = 0; j < num_reloc; j++) { + symnum = ELF32_R_SYM(prela[j].r_info); +#ifdef DEBUG + printf("sym num o %d n %d\n", symnum, + symmap[symnum]); +#endif + prela[j].r_info = ELF32_R_INFO (symmap[symnum], + ELF32_R_TYPE(prela[j].r_info)); + } + + } + if ((pshdr->sh_type == SHT_REL) && + pshdr->sh_link == symtabsecnum) + { +#ifdef DEBUG + printf ("section %d has rel relocations in symtab\n", i); +#endif + prel = (Elf32_Rel *)(pexe + pshdr->sh_offset); + num_reloc = pshdr->sh_size /sizeof (Elf32_Rel); + for (j = 0; j < num_reloc; j++) { + symnum = ELF32_R_SYM(prel[j].r_info); +#ifdef DEBUG + printf("sym num o %d n %d\n", symnum, + symmap[symnum]); +#endif + prel[j].r_info = ELF32_R_INFO (symmap[symnum], + ELF32_R_TYPE(prel[j].r_info)); + } + } + } + +} |