/* * Copyright 2002 John W. De Boskey * 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. * * THIS SOFTWARE IS PROVIDED BY JOHN W. DE BOSKEY ``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 JOHN W. DE BOSKEY 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 #include #include #include #include #include #include #include #include "elfutil.h" void open_elf_image(filename,fdp,filebufp) char *filename; int *fdp; char **filebufp; { int fd; int rc; char *filebuf; struct stat sb; Elf32_Ehdr *eh; fd = open(filename, O_RDONLY); if (fd < 0) err(1,"open(\"%s\")",filename); rc = fstat(fd, &sb); if (rc < 0) err(1,"fstat()"); filebuf = mmap(0, sb.st_size, PROT_READ, MAP_SHARED, fd, 0); if (filebuf == MAP_FAILED) err(1,"mmap()"); eh = (Elf32_Ehdr *)filebuf; if (eh->e_ident[EI_MAG1] != 'E' || eh->e_ident[EI_MAG2] != 'L' || eh->e_ident[EI_MAG3] != 'F') { fprintf(stderr,"%s is not an ELF format image\n",filename); exit(1); } *fdp = fd; *filebufp = filebuf; return; } /* * Given a pointer to an elf object, find the interpreter */ char * get_elf_interp(elf) char *elf; { Elf32_Ehdr *eh = (Elf32_Ehdr *)elf; Elf32_Shdr *sh = (Elf32_Shdr *)&elf[eh->e_shoff]; Elf32_Shdr *si = &sh[eh->e_shstrndx]; char *shstrtab = &elf[si->sh_offset]; char *interp = NULL; int i; for (i=1; ie_shnum; i++) if (!strcmp(&shstrtab[sh[i].sh_name], ".interp")) { interp = &elf[sh[i].sh_offset]; break; } if (interp) return(strdup(interp)); return(interp); } /* * Locate a function within an elf section table */ unsigned get_function_offset(elf,table,func) char *elf; char *table; char *func; { Elf32_Ehdr *eh = (Elf32_Ehdr *)elf; Elf32_Shdr *sh = (Elf32_Shdr *)&elf[eh->e_shoff]; Elf32_Shdr *si = &sh[eh->e_shstrndx]; char *shstrtab = &elf[si->sh_offset]; Elf32_Sym *st = NULL; int symcnt = NULL; char *strtab = NULL; int offset; int i; for (i=1; ie_shnum; i++) if (!strcmp(&shstrtab[sh[i].sh_name], table)) { st = (Elf32_Sym *)&elf[sh[i].sh_offset]; strtab = &elf[sh[sh[i].sh_link].sh_offset]; symcnt = sh[i].sh_size / sh[i].sh_entsize; break; } if (!st) { fprintf(stderr,"Could not locate %s section\n",table); exit(1); } for (i=0; ie_entry); } /* * Return information about the interpreter */ #define HOOKSECT ".dynsym" #define HOOKNAME "r_debug_state" void get_interp_info(interp) __interp *interp; { int fd; char *i_buf; open_elf_image(interp->name,&fd,&i_buf); interp->hookpt = get_function_offset(i_buf,HOOKSECT,HOOKNAME); if (! interp->hookpt) { fprintf(stderr,"[%s] not found in [%s]\n",HOOKNAME,HOOKSECT); exit(1); } interp->entrypt = get_image_entrypt(i_buf); if (! interp->entrypt) { fprintf(stderr,"Could not locate entrypt in %s\n",interp->name); exit(1); } return; }