exec_elf32.c (246278) | exec_elf32.c (246296) |
---|---|
1/* 2 * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 20 unchanged lines hidden (view full) --- 29 */ 30 31#include <sys/cdefs.h> 32#ifndef lint 33#if 0 34__RCSID("$NetBSD: exec_elf32.c,v 1.6 1999/09/20 04:12:16 christos Exp $"); 35#endif 36#endif | 1/* 2 * Copyright (c) 1997 Christopher G. Demetriou. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. --- 20 unchanged lines hidden (view full) --- 29 */ 30 31#include <sys/cdefs.h> 32#ifndef lint 33#if 0 34__RCSID("$NetBSD: exec_elf32.c,v 1.6 1999/09/20 04:12:16 christos Exp $"); 35#endif 36#endif |
37__FBSDID("$FreeBSD: head/usr.sbin/crunch/crunchide/exec_elf32.c 246278 2013-02-03 01:54:25Z pfg $"); | 37__FBSDID("$FreeBSD: head/usr.sbin/crunch/crunchide/exec_elf32.c 246296 2013-02-03 20:35:37Z pfg $"); |
38 39#ifndef ELFSIZE 40#define ELFSIZE 32 41#endif 42 43#include <sys/types.h> 44#include <sys/endian.h> 45#include <sys/stat.h> 46 47#include <errno.h> | 38 39#ifndef ELFSIZE 40#define ELFSIZE 32 41#endif 42 43#include <sys/types.h> 44#include <sys/endian.h> 45#include <sys/stat.h> 46 47#include <errno.h> |
48#include <limits.h> |
|
48#include <stdio.h> 49#include <stdlib.h> 50#include <string.h> 51#include <unistd.h> 52 53#include "extern.h" 54 55#if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \ --- 21 unchanged lines hidden (view full) --- 77#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) 78#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) 79#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) 80 81#define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) 82#define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 83#define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 84 | 49#include <stdio.h> 50#include <stdlib.h> 51#include <string.h> 52#include <unistd.h> 53 54#include "extern.h" 55 56#if (defined(NLIST_ELF32) && (ELFSIZE == 32)) || \ --- 21 unchanged lines hidden (view full) --- 78#define ELFNAME2(x,y) CONCAT(x,CONCAT(_elf,CONCAT(ELFSIZE,CONCAT(_,y)))) 79#define ELFNAMEEND(x) CONCAT(x,CONCAT(_elf,ELFSIZE)) 80#define ELFDEFNNAME(x) CONCAT(ELF,CONCAT(ELFSIZE,CONCAT(_,x))) 81 82#define xe16toh(x) ((data == ELFDATA2MSB) ? be16toh(x) : le16toh(x)) 83#define xe32toh(x) ((data == ELFDATA2MSB) ? be32toh(x) : le32toh(x)) 84#define htoxe32(x) ((data == ELFDATA2MSB) ? htobe32(x) : htole32(x)) 85 |
85struct listelem { 86 struct listelem *next; 87 void *mem; 88 off_t file; 89 size_t size; | 86struct shlayout { 87 Elf_Shdr *shdr; 88 void *bufp; |
90}; 91 92static ssize_t 93xreadatoff(int fd, void *buf, off_t off, size_t size, const char *fn) 94{ 95 ssize_t rv; 96 97 if (lseek(fd, off, SEEK_SET) != off) { --- 132 unchanged lines hidden (view full) --- 230 * The new renaming behaviour doesn't take global symbols out of the 231 * namespace. However, it's ... unlikely that there will ever be 232 * any collisions in practice because of the new method. 233 */ 234int 235ELFNAMEEND(hide)(int fd, const char *fn) 236{ 237 Elf_Ehdr ehdr; | 89}; 90 91static ssize_t 92xreadatoff(int fd, void *buf, off_t off, size_t size, const char *fn) 93{ 94 ssize_t rv; 95 96 if (lseek(fd, off, SEEK_SET) != off) { --- 132 unchanged lines hidden (view full) --- 229 * The new renaming behaviour doesn't take global symbols out of the 230 * namespace. However, it's ... unlikely that there will ever be 231 * any collisions in practice because of the new method. 232 */ 233int 234ELFNAMEEND(hide)(int fd, const char *fn) 235{ 236 Elf_Ehdr ehdr; |
238 Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr; | 237 struct shlayout *layoutp = NULL; 238 Elf_Shdr *shdrp = NULL, *symtabshdr, *strtabshdr, *shstrtabshdr; 239 Elf_Shdr shdrshdr; |
239 Elf_Sym *symtabp = NULL; | 240 Elf_Sym *symtabp = NULL; |
240 char *strtabp = NULL; 241 Elf_Size nsyms, ewi; | 241 char *shstrtabp = NULL, *strtabp = NULL; 242 Elf_Size nsyms, ewi; 243 Elf_Off off; |
242 ssize_t shdrsize; | 244 ssize_t shdrsize; |
243 int rv, i, weird; 244 size_t nstrtab_size, nstrtab_nextoff, fn_size; | 245 int rv, i, weird, l, m, r, strtabidx; 246 size_t nstrtab_size, nstrtab_nextoff, fn_size, size; |
245 char *nstrtabp = NULL; 246 unsigned char data; | 247 char *nstrtabp = NULL; 248 unsigned char data; |
247 Elf_Off maxoff, stroff; | |
248 const char *weirdreason = NULL; | 249 const char *weirdreason = NULL; |
250 void *buf; |
|
249 250 rv = 0; 251 if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr) 252 goto bad; 253 254 data = ehdr.e_ident[EI_DATA]; 255 256 shdrsize = xe16toh(ehdr.e_shnum) * xe16toh(ehdr.e_shentsize); 257 if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL) 258 goto bad; 259 if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != 260 shdrsize) 261 goto bad; 262 | 251 252 rv = 0; 253 if (xreadatoff(fd, &ehdr, 0, sizeof ehdr, fn) != sizeof ehdr) 254 goto bad; 255 256 data = ehdr.e_ident[EI_DATA]; 257 258 shdrsize = xe16toh(ehdr.e_shnum) * xe16toh(ehdr.e_shentsize); 259 if ((shdrp = xmalloc(shdrsize, fn, "section header table")) == NULL) 260 goto bad; 261 if (xreadatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != 262 shdrsize) 263 goto bad; 264 |
263 symtabshdr = strtabshdr = NULL; | 265 symtabshdr = strtabshdr = shstrtabshdr = NULL; |
264 weird = 0; | 266 weird = 0; |
265 maxoff = stroff = 0; | |
266 for (i = 0; i < xe16toh(ehdr.e_shnum); i++) { | 267 for (i = 0; i < xe16toh(ehdr.e_shnum); i++) { |
267 if (xewtoh(shdrp[i].sh_offset) > maxoff) 268 maxoff = xewtoh(shdrp[i].sh_offset); | |
269 switch (xe32toh(shdrp[i].sh_type)) { 270 case SHT_SYMTAB: | 268 switch (xe32toh(shdrp[i].sh_type)) { 269 case SHT_SYMTAB: |
271 if (symtabshdr != NULL) | 270 if (symtabshdr != NULL) { |
272 weird = 1; | 271 weird = 1; |
272 weirdreason = "multiple symbol tables"; 273 } |
|
273 symtabshdr = &shdrp[i]; 274 strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)]; | 274 symtabshdr = &shdrp[i]; 275 strtabshdr = &shdrp[xe32toh(shdrp[i].sh_link)]; |
275 276 /* Check whether the string table is the last section */ 277 stroff = xewtoh(shdrp[xe32toh(shdrp[i].sh_link)].sh_offset); 278 if (!weird && xe32toh(shdrp[i].sh_link) != (xe16toh(ehdr.e_shnum) - 1)) { 279 weird = 1; 280 weirdreason = "string table not last section"; 281 } | |
282 break; | 276 break; |
277 case SHT_STRTAB: 278 if (i == xe16toh(ehdr.e_shstrndx)) 279 shstrtabshdr = &shdrp[i]; 280 break; |
|
283 } 284 } | 281 } 282 } |
285 if (! weirdreason) 286 weirdreason = "unsupported"; | |
287 if (symtabshdr == NULL) 288 goto out; | 283 if (symtabshdr == NULL) 284 goto out; |
289 if (strtabshdr == NULL) | 285 if (strtabshdr == NULL) { |
290 weird = 1; | 286 weird = 1; |
291 if (!weird && stroff != maxoff) { | 287 weirdreason = "string table does not exist"; 288 } 289 if (shstrtabshdr == NULL) { |
292 weird = 1; | 290 weird = 1; |
293 weirdreason = "string table section not last in file"; 294 } | 291 weirdreason = "section header string table does not exist"; 292 } 293 if (weirdreason == NULL) 294 weirdreason = "unsupported"; |
295 if (weird) { 296 fprintf(stderr, "%s: weird executable (%s)\n", fn, weirdreason); 297 goto bad; 298 } 299 300 /* | 295 if (weird) { 296 fprintf(stderr, "%s: weird executable (%s)\n", fn, weirdreason); 297 goto bad; 298 } 299 300 /* |
301 * sort section layout table by offset 302 */ 303 layoutp = xmalloc(sizeof(struct shlayout) * (xe16toh(ehdr.e_shnum) + 1), 304 fn, "layout table"); 305 if (layoutp == NULL) 306 goto bad; 307 308 /* add a pseudo entry to represent the section header table */ 309 shdrshdr.sh_offset = ehdr.e_shoff; 310 shdrshdr.sh_size = htoxew(shdrsize); 311 shdrshdr.sh_addralign = htoxew(ELFSIZE / 8); 312 layoutp[xe16toh(ehdr.e_shnum)].shdr = &shdrshdr; 313 314 /* insert and sort normal section headers */ 315 for (i = xe16toh(ehdr.e_shnum) - 1; i >= 0; i--) { 316 l = i + 1; 317 r = xe16toh(ehdr.e_shnum); 318 while (l <= r) { 319 m = ( l + r) / 2; 320 if (xewtoh(shdrp[i].sh_offset) > 321 xewtoh(layoutp[m].shdr->sh_offset)) 322 l = m + 1; 323 else 324 r = m - 1; 325 } 326 327 if (r != i) { 328 memmove(&layoutp[i], &layoutp[i + 1], 329 sizeof(struct shlayout) * (r - i)); 330 } 331 332 layoutp[r].shdr = &shdrp[i]; 333 layoutp[r].bufp = NULL; 334 } 335 336 /* |
|
301 * load up everything we need 302 */ 303 | 337 * load up everything we need 338 */ 339 |
304 /* symbol table */ 305 if ((symtabp = xmalloc(xewtoh(symtabshdr->sh_size), fn, "symbol table")) 306 == NULL) | 340 /* load section string table for debug use */ 341 if ((shstrtabp = xmalloc(xewtoh(shstrtabshdr->sh_size), fn, 342 "section string table")) == NULL) |
307 goto bad; | 343 goto bad; |
308 if ((size_t)xreadatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset), 309 xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size)) | 344 if ((size_t)xreadatoff(fd, shstrtabp, xewtoh(shstrtabshdr->sh_offset), 345 xewtoh(shstrtabshdr->sh_size), fn) != xewtoh(shstrtabshdr->sh_size)) |
310 goto bad; 311 | 346 goto bad; 347 |
312 /* string table */ 313 if ((strtabp = xmalloc(xewtoh(strtabshdr->sh_size), fn, "string table")) 314 == NULL) 315 goto bad; 316 if ((size_t)xreadatoff(fd, strtabp, xewtoh(strtabshdr->sh_offset), 317 xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size)) 318 goto bad; | 348 /* we need symtab, strtab, and everything behind strtab */ 349 strtabidx = INT_MAX; 350 for (i = 0; i < xe16toh(ehdr.e_shnum) + 1; i++) { 351 if (layoutp[i].shdr == &shdrshdr) { 352 /* not load section header again */ 353 layoutp[i].bufp = shdrp; 354 continue; 355 } 356 if (layoutp[i].shdr == shstrtabshdr) { 357 /* not load section string table again */ 358 layoutp[i].bufp = shstrtabp; 359 continue; 360 } |
319 | 361 |
362 if (layoutp[i].shdr == strtabshdr) 363 strtabidx = i; 364 if (layoutp[i].shdr == symtabshdr || i >= strtabidx) { 365 off = xewtoh(layoutp[i].shdr->sh_offset); 366 size = xewtoh(layoutp[i].shdr->sh_size); 367 layoutp[i].bufp = xmalloc(size, fn, 368 shstrtabp + xewtoh(layoutp[i].shdr->sh_name)); 369 if (layoutp[i].bufp == NULL) 370 goto bad; 371 if ((size_t)xreadatoff(fd, layoutp[i].bufp, off, size, fn) != 372 size) 373 goto bad; 374 375 /* set symbol table and string table */ 376 if (layoutp[i].shdr == symtabshdr) 377 symtabp = layoutp[i].bufp; 378 else if (layoutp[i].shdr == strtabshdr) 379 strtabp = layoutp[i].bufp; 380 } 381 } 382 |
|
320 nstrtab_size = 256; 321 nstrtabp = xmalloc(nstrtab_size, fn, "new string table"); 322 if (nstrtabp == NULL) 323 goto bad; 324 nstrtab_nextoff = 0; 325 326 fn_size = strlen(fn); 327 --- 32 unchanged lines hidden (view full) --- 360 newent_len = sprintf(nstrtabp + nstrtab_nextoff, 361 "_$$hide$$ %s %s", fn, symname) + 1; 362 } 363 nstrtab_nextoff += newent_len; 364 } 365 strtabshdr->sh_size = htoxew(nstrtab_nextoff); 366 367 /* | 383 nstrtab_size = 256; 384 nstrtabp = xmalloc(nstrtab_size, fn, "new string table"); 385 if (nstrtabp == NULL) 386 goto bad; 387 nstrtab_nextoff = 0; 388 389 fn_size = strlen(fn); 390 --- 32 unchanged lines hidden (view full) --- 423 newent_len = sprintf(nstrtabp + nstrtab_nextoff, 424 "_$$hide$$ %s %s", fn, symname) + 1; 425 } 426 nstrtab_nextoff += newent_len; 427 } 428 strtabshdr->sh_size = htoxew(nstrtab_nextoff); 429 430 /* |
368 * write new tables to the file | 431 * update section header table in ascending order of offset |
369 */ | 432 */ |
370 if (xwriteatoff(fd, shdrp, xewtoh(ehdr.e_shoff), shdrsize, fn) != 371 shdrsize) 372 goto bad; 373 if ((size_t)xwriteatoff(fd, symtabp, xewtoh(symtabshdr->sh_offset), 374 xewtoh(symtabshdr->sh_size), fn) != xewtoh(symtabshdr->sh_size)) 375 goto bad; 376 /* write new symbol table strings */ 377 if ((size_t)xwriteatoff(fd, nstrtabp, xewtoh(strtabshdr->sh_offset), 378 xewtoh(strtabshdr->sh_size), fn) != xewtoh(strtabshdr->sh_size)) 379 goto bad; | 433 for (i = strtabidx + 1; i < xe16toh(ehdr.e_shnum) + 1; i++) { 434 Elf_Off off, align; 435 off = xewtoh(layoutp[i - 1].shdr->sh_offset) + 436 xewtoh(layoutp[i - 1].shdr->sh_size); 437 align = xewtoh(layoutp[i].shdr->sh_addralign); 438 off = (off + (align - 1)) & ~(align - 1); 439 layoutp[i].shdr->sh_offset = htoxew(off); 440 } |
380 | 441 |
442 /* 443 * write data to the file in descending order of offset 444 */ 445 for (i = xe16toh(ehdr.e_shnum); i >= 0; i--) { 446 if (layoutp[i].shdr == strtabshdr) { 447 /* new string table */ 448 buf = nstrtabp; 449 } else 450 buf = layoutp[i].bufp; 451 452 if (layoutp[i].shdr == &shdrshdr || 453 layoutp[i].shdr == symtabshdr || i >= strtabidx) { 454 if (buf == NULL) 455 goto bad; 456 457 /* 458 * update the offset of section header table in elf 459 * header if needed. 460 */ 461 if (layoutp[i].shdr == &shdrshdr && 462 ehdr.e_shoff != shdrshdr.sh_offset) { 463 ehdr.e_shoff = shdrshdr.sh_offset; 464 off = (ELFSIZE == 32) ? 32 : 44; 465 size = sizeof(Elf_Off); 466 if ((size_t)xwriteatoff(fd, &ehdr.e_shoff, off, size, 467 fn) != size) 468 goto bad; 469 } 470 471 off = xewtoh(layoutp[i].shdr->sh_offset); 472 size = xewtoh(layoutp[i].shdr->sh_size); 473 if ((size_t)xwriteatoff(fd, buf, off, size, fn) != size) 474 goto bad; 475 } 476 } 477 |
|
381out: | 478out: |
382 if (shdrp != NULL) 383 free(shdrp); 384 if (symtabp != NULL) 385 free(symtabp); 386 if (strtabp != NULL) 387 free(strtabp); 388 if (nstrtabp != NULL) 389 free(nstrtabp); | 479 if (layoutp != NULL) { 480 for (i = 0; i < xe16toh(ehdr.e_shnum) + 1; i++) { 481 if (layoutp[i].bufp != NULL) 482 free(layoutp[i].bufp); 483 } 484 free(layoutp); 485 } 486 free(nstrtabp); |
390 return (rv); 391 392bad: 393 rv = 1; 394 goto out; 395} 396 397#endif /* include this size of ELF */ | 487 return (rv); 488 489bad: 490 rv = 1; 491 goto out; 492} 493 494#endif /* include this size of ELF */ |