ÜberWall

UWelfviewer

/* $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 <unistd.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <elf.h>
#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;
}