GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/crunchgen/elf_hide.c Lines: 0 105 0.0 %
Date: 2017-11-07 Branches: 0 60 0.0 %

Line Branch Exec Source
1
/* $OpenBSD: elf_hide.c,v 1.10 2015/08/20 22:39:29 deraadt Exp $ */
2
3
/*
4
 * Copyright (c) 1997 Dale Rahn.
5
 * All rights reserved.
6
 *
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that the following conditions
10
 * are met:
11
 * 1. Redistributions of source code must retain the above copyright
12
 *    notice, this list of conditions and the following disclaimer.
13
 * 2. Redistributions in binary form must reproduce the above copyright
14
 *    notice, this list of conditions and the following disclaimer in the
15
 *    documentation and/or other materials provided with the distribution.
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
29
#include <sys/types.h>
30
#include <sys/mman.h>
31
#include <sys/stat.h>
32
#include <sys/exec_elf.h>
33
34
#include <err.h>
35
#include <errno.h>
36
#include <fcntl.h>
37
#include <unistd.h>
38
#include <stdio.h>
39
#include <stdlib.h>
40
#include <string.h>
41
#include "mangle.h"
42
43
extern	int elf_mangle;
44
45
void	load_strtab(Elf_Ehdr * pehdr, char *pexe);
46
void	dump_strtab(void);
47
char	*get_str(int indx);
48
49
void	load_symtab(Elf_Ehdr * pehdr, char *pexe);
50
void	dump_symtab(Elf_Shdr * symsect, Elf_Sym * symtab, int symtabsize);
51
void	fprint_str(FILE * channel, int indx);
52
53
void	load_shstr_tab(Elf_Ehdr * pehdr, char *pexe);
54
char	*get_shstr(int indx);
55
void	fprint_shstr(FILE * channel, int indx);
56
57
void	hide_sym(Elf_Ehdr * ehdr, Elf_Shdr * symsect,
58
	    Elf_Sym * symtab, int symtabsize, int symtabsecnum);
59
void	reorder_syms(Elf_Ehdr * ehdr, Elf_Shdr * symsect,
60
	    Elf_Sym * symtab, int symtabsize, int symtabsecnum);
61
typedef long    Symmap;
62
void	renum_reloc_syms(Elf_Ehdr * ehdr, Symmap * symmap,
63
	    int symtabsecnum);
64
void	elf_hide(int pfile, char *p);
65
66
67
char           *pexe;
68
69
void
70
elf_hide(int pfile, char *p)
71
{
72
	Elf_Ehdr       *pehdr;
73
#ifdef DEBUG
74
	Elf_Shdr       *pshdr;
75
	Elf_Phdr       *pphdr;
76
	int             i;
77
#endif
78
79
	pexe = p;
80
	pehdr = (Elf_Ehdr *) pexe;
81
82
#ifdef DEBUG
83
	printf("elf header\n");
84
	printf("e_type %x\n", pehdr->e_type);
85
	printf("e_machine %x\n", pehdr->e_machine);
86
	printf("e_version %x\n", pehdr->e_version);
87
	printf("e_entry %x\n", pehdr->e_entry);
88
	printf("e_phoff %x\n", pehdr->e_phoff);
89
	printf("e_shoff %x\n", pehdr->e_shoff);
90
	printf("e_flags %x\n", pehdr->e_flags);
91
	printf("e_ehsize %x\n", pehdr->e_ehsize);
92
	printf("e_phentsize %x\n", pehdr->e_phentsize);
93
	printf("e_phnum %x\n", pehdr->e_phnum);
94
	printf("e_shentsize %x\n", pehdr->e_shentsize);
95
	printf("e_shnum %x\n", pehdr->e_shnum);
96
	printf("e_shstrndx %x\n", pehdr->e_shstrndx);
97
#endif
98
99
	load_shstr_tab(pehdr, pexe);
100
#ifdef DEBUG
101
	for (i = 0; i < pehdr->e_shnum; i++) {
102
		pshdr = (Elf_Phdr *) (pexe + pehdr->e_shoff +
103
		    (i * pehdr->e_shentsize));
104
105
		printf("section header %d\n", i);
106
		printf("sh_name %x ", pshdr->sh_name);
107
		fprint_shstr(stdout, pshdr->sh_name);
108
		printf("\n");
109
		printf("sh_type %x\n", pshdr->sh_type);
110
		printf("sh_flags %x\n", pshdr->sh_flags);
111
		printf("sh_addr %x\n", pshdr->sh_addr);
112
		printf("sh_offset %x\n", pshdr->sh_offset);
113
		printf("sh_size %x\n", pshdr->sh_size);
114
		printf("sh_link %x\n", pshdr->sh_link);
115
		printf("sh_info %x\n", pshdr->sh_info);
116
		printf("sh_addralign %x\n", pshdr->sh_addralign);
117
		printf("sh_entsize %x\n", pshdr->sh_entsize);
118
	}
119
#endif				/* DEBUG */
120
121
#ifdef DEBUG
122
	for (i = 0; i < pehdr->e_phnum; i++) {
123
		pshdr = (Elf_Phdr *) (pexe + pehdr->e_phoff +
124
		    (i * pehdr->e_phentsize));
125
126
		printf("program header %d\n", i);
127
		printf("p_type %x\n", pphdr->p_type);
128
		printf("p_offset %x\n", pphdr->p_offset);
129
		printf("p_vaddr %x\n", pphdr->p_vaddr);
130
		printf("p_paddr %x\n", pphdr->p_paddr);
131
		printf("p_filesz %x\n", pphdr->p_filesz);
132
		printf("p_memsz %x\n", pphdr->p_memsz);
133
		printf("p_flags %x\n", pphdr->p_flags);
134
		printf("p_align %x\n", pphdr->p_align);
135
	}
136
#endif				/* DEBUG */
137
#if 0
138
	for (i = 0; i < pehdr->e_shnum; i++) {
139
		pshdr = (Elf_Phdr *) (pexe + pehdr->e_shoff +
140
		    (i * pehdr->e_shentsize));
141
		if (strcmp(".strtab", get_shstr(pshdr->sh_name)) == 0)
142
			break;
143
	}
144
	fprint_shstr(stdout, pshdr->sh_name);
145
	printf("\n");
146
#endif
147
148
	load_strtab(pehdr, pexe);
149
	load_symtab(pehdr, pexe);
150
	close(pfile);
151
}
152
char           *shstrtab;
153
154
void
155
load_shstr_tab(Elf_Ehdr * pehdr, char *pexe)
156
{
157
	Elf_Shdr       *pshdr;
158
	shstrtab = NULL;
159
	if (pehdr->e_shstrndx == 0)
160
		return;
161
	pshdr = (Elf_Shdr *) (pexe + pehdr->e_shoff +
162
	    (pehdr->e_shstrndx * pehdr->e_shentsize));
163
164
	shstrtab = (char *) (pexe + pshdr->sh_offset);
165
}
166
167
void
168
fprint_shstr(FILE * channel, int indx)
169
{
170
	if (shstrtab != NULL)
171
		fprintf(channel, "\"%s\"", &(shstrtab[indx]));
172
}
173
174
char           *
175
get_shstr(int indx)
176
{
177
	return &(shstrtab[indx]);
178
}
179
180
void
181
load_symtab(Elf_Ehdr * pehdr, char *pexe)
182
{
183
	Elf_Sym        *symtab;
184
	Elf_Shdr       *symsect;
185
	int             symtabsize;
186
	Elf_Shdr       *psymshdr;
187
	Elf_Shdr       *pshdr;
188
#ifdef DEBUG
189
	char           *shname;
190
#endif
191
	int             i;
192
193
	symtab = NULL;
194
	for (i = 0; i < pehdr->e_shnum; i++) {
195
		pshdr = (Elf_Shdr *) (pexe + pehdr->e_shoff +
196
		    (i * pehdr->e_shentsize));
197
		if (SHT_REL != pshdr->sh_type && SHT_RELA != pshdr->sh_type)
198
			continue;
199
		psymshdr = (Elf_Shdr *) (pexe + pehdr->e_shoff +
200
		    (pshdr->sh_link * pehdr->e_shentsize));
201
#ifdef DEBUG
202
		fprint_shstr(stdout, pshdr->sh_name);
203
		printf("\n");
204
#endif
205
		symtab = (Elf_Sym *) (pexe + psymshdr->sh_offset);
206
		symsect = psymshdr;
207
		symtabsize = psymshdr->sh_size;
208
209
#ifdef DEBUG
210
		dump_symtab(symsect, symtab, symtabsize);
211
#endif
212
		hide_sym(pehdr, symsect, symtab, symtabsize, pshdr->sh_link);
213
	}
214
215
}
216
217
void
218
dump_symtab(Elf_Shdr * symsect, Elf_Sym * symtab, int symtabsize)
219
{
220
	int             i;
221
	Elf_Sym        *psymtab;
222
223
	for (i = 0; i < (symtabsize / sizeof(Elf_Sym)); i++) {
224
		psymtab = &(symtab[i]);
225
		if ((psymtab->st_info & 0xf0) == 0x10 &&
226
		    (psymtab->st_shndx != SHN_UNDEF)) {
227
			printf("symbol %d:\n", i);
228
			printf("st_name %x \"%s\"\n", psymtab->st_name,
229
			    get_str(psymtab->st_name));
230
			printf("st_value %llx\n", (unsigned long long)psymtab->st_value);
231
			printf("st_size %llx\n", (unsigned long long)psymtab->st_size);
232
			printf("st_info %x\n", psymtab->st_info);
233
			printf("st_other %x\n", psymtab->st_other);
234
			printf("st_shndx %x\n", psymtab->st_shndx);
235
		}
236
	}
237
}
238
239
char           *strtab;
240
int             strtabsize;
241
void
242
load_strtab(Elf_Ehdr * pehdr, char *pexe)
243
{
244
	Elf_Shdr       *pshdr = NULL;
245
	char           *shname;
246
	int             i;
247
	strtab = NULL;
248
	for (i = 0; i < pehdr->e_shnum; i++) {
249
		pshdr = (Elf_Shdr *) (pexe + pehdr->e_shoff +
250
		    (i * pehdr->e_shentsize));
251
252
		shname = get_shstr(pshdr->sh_name);
253
		if (strcmp(".strtab", shname) == 0)
254
			break;
255
	}
256
#ifdef DEBUG
257
	fprint_shstr(stdout, pshdr->sh_name);
258
	printf("\n");
259
#endif
260
261
	strtab = (char *) (pexe + pshdr->sh_offset);
262
263
	strtabsize = pshdr->sh_size;
264
265
#ifdef DEBUG
266
	dump_strtab();
267
#endif
268
}
269
270
void
271
dump_strtab()
272
{
273
	int             index;
274
	char           *pstr;
275
	char           *pnstr;
276
	int             i = 0;
277
	index = 0;
278
	pstr = strtab;
279
	while (index < strtabsize) {
280
		printf("string %x: \"%s\"\n", i, pstr);
281
		pnstr = pstr + strlen(pstr) + 1;
282
		index = pnstr - strtab;
283
		pstr = pnstr;
284
		i++;
285
	}
286
287
}
288
289
void
290
fprint_str(FILE * channel, int indx)
291
{
292
	if (strtab != NULL)
293
		fprintf(channel, "\"%s\"", &(strtab[indx]));
294
}
295
296
char *
297
get_str(int indx)
298
{
299
	return &(strtab[indx]);
300
}
301
302
int             in_keep_list(char *symbol);
303
304
void
305
hide_sym(Elf_Ehdr * ehdr, Elf_Shdr * symsect,
306
    Elf_Sym * symtab, int symtabsize, int symtabsecnum)
307
{
308
	int             i;
309
	unsigned char   info;
310
	Elf_Sym        *psymtab;
311
312
	for (i = 0; i < (symtabsize / sizeof(Elf_Sym)); i++) {
313
		psymtab = &(symtab[i]);
314
		if ((psymtab->st_info & 0xf0) == 0x10 &&
315
		    (psymtab->st_shndx != SHN_UNDEF)) {
316
			if (in_keep_list(get_str(psymtab->st_name)))
317
				continue;
318
#ifdef DEBUG
319
			printf("symbol %d:\n", i);
320
			printf("st_name %x \"%s\"\n", psymtab->st_name,
321
			    get_str(psymtab->st_name));
322
			printf("st_info %x\n", psymtab->st_info);
323
#endif
324
			if (!elf_mangle) {
325
				info = psymtab->st_info;
326
				info = info & 0xf;
327
				psymtab->st_info = info;
328
			} else {
329
				mangle_str(get_str(psymtab->st_name));
330
			}
331
#ifdef DEBUG
332
			printf("st_info %x\n", psymtab->st_info);
333
#endif
334
		}
335
	}
336
	reorder_syms(ehdr, symsect, symtab, symtabsize, symtabsecnum);
337
}
338
339
void
340
reorder_syms(Elf_Ehdr * ehdr, Elf_Shdr * symsect,
341
    Elf_Sym * symtab, int symtabsize, int symtabsecnum)
342
{
343
	int             i;
344
	int             nsyms;
345
	int             cursym;
346
	Elf_Sym        *tmpsymtab;
347
	Symmap         *symmap;
348
349
350
	nsyms = symtabsize / sizeof(Elf_Sym);
351
352
	tmpsymtab = calloc(1, symtabsize);
353
	symmap = calloc(nsyms, sizeof(Symmap));
354
	if (!tmpsymtab || !symmap)
355
		errc(5, ENOMEM, "calloc");
356
357
	bcopy(symtab, tmpsymtab, symtabsize);
358
359
	cursym = 1;
360
	for (i = 1; i < nsyms; i++) {
361
		if ((tmpsymtab[i].st_info & 0xf0) == 0x00) {
362
#ifdef DEBUG
363
			printf("copying  l o%d n%d <%s>\n", i, cursym,
364
			    get_str(tmpsymtab[i].st_name));
365
#endif
366
			bcopy(&(tmpsymtab[i]), &(symtab[cursym]),
367
			    sizeof(Elf_Sym));
368
			symmap[i] = cursym;
369
			cursym++;
370
		}
371
	}
372
	symsect->sh_info = cursym;
373
	for (i = 1; i < nsyms; i++) {
374
		if ((tmpsymtab[i].st_info & 0xf0) != 0x00) {
375
#ifdef DEBUG
376
			printf("copying nl o%d n%d <%s>\n", i, cursym,
377
			    get_str(tmpsymtab[i].st_name));
378
#endif
379
			bcopy(&(tmpsymtab[i]), &(symtab[cursym]),
380
			    sizeof(Elf_Sym));
381
			symmap[i] = cursym;
382
			cursym++;
383
		}
384
	}
385
	if (cursym != nsyms) {
386
		printf("miscounted symbols somewhere c %d n %d \n",
387
		    cursym, nsyms);
388
		exit(5);
389
	}
390
	renum_reloc_syms(ehdr, symmap, symtabsecnum);
391
	free(tmpsymtab);
392
	free(symmap);
393
}
394
395
void
396
renum_reloc_syms(Elf_Ehdr * ehdr, Symmap * symmap, int symtabsecnum)
397
{
398
	Elf_Shdr       *pshdr;
399
	int             i, j;
400
	int             num_reloc;
401
	Elf_Rel        *prel;
402
	Elf_RelA       *prela;
403
	int             symnum;
404
405
	for (i = 0; i < ehdr->e_shnum; i++) {
406
		pshdr = (Elf_Shdr *) (pexe + ehdr->e_shoff +
407
		    (i * ehdr->e_shentsize));
408
		if ((pshdr->sh_type == SHT_RELA) &&
409
		    pshdr->sh_link == symtabsecnum) {
410
411
#ifdef DEBUG
412
			printf("section %d has rela relocations in symtab\n", i);
413
#endif
414
			prela = (Elf_RelA *) (pexe + pshdr->sh_offset);
415
			num_reloc = pshdr->sh_size / sizeof(Elf_RelA);
416
			for (j = 0; j < num_reloc; j++) {
417
				symnum = ELF_R_SYM(prela[j].r_info);
418
#ifdef DEBUG
419
				printf("sym num o %d n %d\n", symnum,
420
				    symmap[symnum]);
421
#endif
422
				prela[j].r_info = ELF_R_INFO(symmap[symnum],
423
				    ELF_R_TYPE(prela[j].r_info));
424
			}
425
		}
426
		if ((pshdr->sh_type == SHT_REL) &&
427
		    pshdr->sh_link == symtabsecnum) {
428
#ifdef DEBUG
429
			printf("section %d has rel relocations in symtab\n", i);
430
#endif
431
			prel = (Elf_Rel *) (pexe + pshdr->sh_offset);
432
			num_reloc = pshdr->sh_size / sizeof(Elf_Rel);
433
			for (j = 0; j < num_reloc; j++) {
434
				symnum = ELF_R_SYM(prel[j].r_info);
435
#ifdef DEBUG
436
				printf("sym num o %d n %d\n", symnum,
437
				    symmap[symnum]);
438
#endif
439
				prel[j].r_info = ELF_R_INFO(symmap[symnum],
440
				    ELF_R_TYPE(prel[j].r_info));
441
			}
442
		}
443
	}
444
445
}