1 /*- 2 * Copyright (c) 1996 S�ren Schmidt 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer 10 * in this position and unchanged. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software withough specific prior written permission 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 * 28 * $FreeBSD$ 29 */ 30 31 #include <elf.h> 32 #include <fcntl.h> 33 #include <stdio.h> 34 #include <stdlib.h> 35 #include <string.h> 36 #include <unistd.h> 37 #include <err.h> 38 39 static int iselftype(const char *); 40 static void printelftypes(void); 41 static void usage __P((void)); 42 43 int 44 main(int argc, char **argv) 45 { 46 47 const char *type = "FreeBSD"; 48 int retval = 0; 49 int ch, change = 0, verbose = 0, force = 0, listed = 0; 50 51 while ((ch = getopt(argc, argv, "flt:v")) != -1) 52 switch (ch) { 53 case 'f': 54 force = 1; 55 break; 56 case 'l': 57 printelftypes(); 58 listed = 1; 59 break; 60 case 'v': 61 verbose = 1; 62 break; 63 case 't': 64 change = 1; 65 type = optarg; 66 break; 67 default: 68 usage(); 69 } 70 argc -= optind; 71 argv += optind; 72 if (!argc) { 73 if (listed) 74 exit(0); 75 else { 76 warnx("no file(s) specified"); 77 usage(); 78 } 79 } 80 81 if (!force && !iselftype(type)) { 82 warnx("invalid ELF type '%s'", type); 83 printelftypes(); 84 usage(); 85 } 86 87 while (argc) { 88 int fd; 89 char buffer[EI_NIDENT]; 90 char string[(EI_NIDENT-EI_BRAND)+1]; 91 92 if ((fd = open(argv[0], change? O_RDWR: O_RDONLY, 0)) < 0) { 93 warn("error opening file %s", argv[0]); 94 retval = 1; 95 goto fail; 96 } 97 if (read(fd, buffer, EI_NIDENT) < EI_NIDENT) { 98 warnx("file '%s' too short", argv[0]); 99 retval = 1; 100 goto fail; 101 } 102 if (buffer[0] != ELFMAG0 || buffer[1] != ELFMAG1 || 103 buffer[2] != ELFMAG2 || buffer[3] != ELFMAG3) { 104 warnx("file '%s' is not ELF format", argv[0]); 105 retval = 1; 106 goto fail; 107 } 108 if (!change) { 109 bzero(string, sizeof(string)); 110 strncpy(string, &buffer[EI_BRAND], EI_NIDENT-EI_BRAND); 111 if (strlen(string)) { 112 fprintf(stdout, 113 "File '%s' is of brand '%s'.\n", 114 argv[0], string); 115 if (!force && !iselftype(string)) { 116 warnx("Brand '%s' is unknown", 117 string); 118 printelftypes(); 119 } 120 } 121 else 122 fprintf(stdout, "File '%s' has no branding.\n", 123 argv[0]); 124 } 125 else { 126 strncpy(&buffer[EI_BRAND], type, EI_NIDENT-EI_BRAND); 127 lseek(fd, 0, SEEK_SET); 128 if (write(fd, buffer, EI_NIDENT) != EI_NIDENT) { 129 warnx("error writing %s", argv[0]); 130 retval = 1; 131 goto fail; 132 } 133 } 134 fail: 135 argc--; 136 argv++; 137 } 138 139 return retval; 140 } 141 142 static void 143 usage() 144 { 145 fprintf(stderr, "usage: brandelf [-f] [-v] [-l] [-t string] file ...\n"); 146 exit(1); 147 } 148 149 /* XXX - any more types? */ 150 static const char *elftypes[] = { "FreeBSD", "Linux", "SVR4" }; 151 152 static int 153 iselftype(const char *elftype) 154 { 155 int elfwalk; 156 157 for (elfwalk = 0; 158 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 159 elfwalk++) 160 if (strcmp(elftype, elftypes[elfwalk]) == 0) 161 return 1; 162 return 0; 163 } 164 165 static void 166 printelftypes() 167 { 168 int elfwalk; 169 170 fprintf(stderr, "known ELF types are: "); 171 for (elfwalk = 0; 172 elfwalk < sizeof(elftypes)/sizeof(elftypes[0]); 173 elfwalk++) 174 fprintf(stderr, "%s ", elftypes[elfwalk]); 175 fprintf(stderr, "\n"); 176 } 177