/* $Id: UWelfviewer.c,v 1.8 2018/04/16 00:51:46 khorben Exp $ */ /* ELF file parser * UberWall security team \../. .\../ */ /* Copyright (c) 2010 khorben of UberWall */ /* This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* FIXME: * - list the libraries required, RPATH set, etc */ #include #include #include #include #include #include #include #include "elf.h" #include "UWelfviewer.h" #include "config.h" /* UWelfviewer */ /* private */ /* prototypes */ static int _UWelfviewer(char const * pathname); static int _UWelfviewer_do(FILE * fp, char const * pathname); static int _usage(void); /* UWelfviewer */ /* public */ /* functions */ /* UWelfviewer_error */ int UWelfviewer_error(char const * format, ...) { va_list ap; fputs(PACKAGE ": ", stderr); va_start(ap, format); vfprintf(stderr, format, ap); va_end(ap); fputc('\n', stderr); return 1; } /* private */ /* functions */ /* UWelfviewer */ static int _UWelfviewer(char const * pathname) { int ret; FILE * fp; if((fp = fopen(pathname, "r")) == NULL) return UWelfviewer_error("%s: %s", pathname, strerror(errno)); ret = _UWelfviewer_do(fp, pathname); if(fclose(fp) != 0) return UWelfviewer_error("%s: %s", pathname, strerror(errno)); return ret; } /* UWelfviewer_do */ static int _do_ident(FILE * fp, char const * pathname, unsigned char * ident, size_t size); static int _UWelfviewer_do(FILE * fp, char const * pathname) { int ret; unsigned char ident[ELF_NIDENT]; if((ret = _do_ident(fp, pathname, ident, sizeof(ident))) != 0) return ret; if(fseeko(fp, 0, SEEK_SET) != 0) return UWelfviewer_error("%s: %s", strerror(errno)); switch(ident[EI_CLASS]) { case ELFCLASS32: ret = elf32(fp, pathname); break; case ELFCLASS64: ret = elf64(fp, pathname); break; default: ret = UWelfviewer_error("%u: %s", ident[EI_CLASS], "Unsupported ELF class"); break; } return ret; } static int _do_ident(FILE * fp, char const * pathname, unsigned char * ident, size_t size) { if(fread(ident, size, 1, fp) != 1) return UWelfviewer_error("%s: %s", pathname, strerror(errno)); if(memcmp(ident, ELFMAG, sizeof(ELFMAG) - 1) != 0) return UWelfviewer_error("%s: %s", pathname, "Not an ELF file"); return 0; } /* usage */ static int _usage(void) { fputs("Usage: " PACKAGE " filename\n", stderr); return 1; } /* public */ /* functions */ /* main */ int main(int argc, char * argv[]) { int o; while((o = getopt(argc, argv, "")) != -1) return _usage(); if(optind + 1 != argc) return _usage(); return _UWelfviewer(argv[optind]) == 0 ? 0 : 2; }