Deleted Added
full compact
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 */