aboutsummaryrefslogtreecommitdiff
blob: c18d277c1aa5092ce3dec84795a474409ff2be9d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
#include <stdio.h>	// printf
#include <stdlib.h>	// EXIT_FAILURE
#include <error.h>	// error

#include <gelf.h>	// elf_* and gelf_*

#include <sys/types.h>	// open
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>	// close


int main( int argc, char *argv[])
{
	int fd, cmd;
	size_t i, n;
	char *p; 

	Elf *arf, *elf;
	Elf_Arhdr *arhdr;
	GElf_Ehdr ehdr;
	GElf_Phdr phdr;
	Elf_Scn *scn;
	GElf_Shdr shdr;
	Elf_Data *data;

	if(elf_version(EV_CURRENT) == EV_NONE)
		error(EXIT_FAILURE, 0, "Library out of date.");

	if(argc != 2)
		error(EXIT_FAILURE, 0, "Usage: %s <filename>", argv[0]);

	if((fd = open(argv[1], O_RDONLY)) == -1)
		error(EXIT_FAILURE, 0, "Failed open file.");


	cmd = ELF_C_READ;

	if((arf = elf_begin(fd, cmd, (Elf *)0)) == NULL)
		error(EXIT_FAILURE, 0, "Failed open elf: %s", elf_errmsg ( -1));
		

	switch(elf_kind(arf))
	{
		case ELF_K_AR:
			printf("This is an archive.\n");
			arhdr = elf_getarhdr(arf);
			/*
			printf("\n ********** ARCHIVE HEADER ********** \n");
			printf( "Name:\t\t%s\nDate:\t\t%lu\nUID:\t\t%d\nGID:\t\t%d\n"
				"Mode:\t\t%d\n:Size:\t\t%lu\nRaw:\t\t%s\n\n ",
				arhdr->ar_name,
				arhdr->ar_date,
				arhdr->ar_uid,
				arhdr->ar_gid,
				arhdr->ar_mode,
				arhdr->ar_size,
				arhdr->ar_rawname
			);
			*/
			break;
		case ELF_K_COFF:
			printf("This is a COFF.\n"); break;
		case ELF_K_ELF:
			printf("This is an ELF.\n"); break;
		default:
		case ELF_K_NONE:
			printf("This is an unknown.\n"); break;
	}

	while((elf = elf_begin(fd, cmd, arf)) != NULL)
	{
		if(gelf_getehdr(elf,&ehdr) != NULL)
		{
			printf("\n ********** HEADER ********** \n");
			switch(ehdr.e_type)
			{
				case ET_NONE:	printf("This is a ET_NONE Type.\n"); break;
				case ET_REL:	printf("This is a ET_REL Type.\n"); break;
				case ET_EXEC:	printf("This is a ET_EXEC Type.\n"); break;
				case ET_DYN:	printf("This is a ET_DYN Type.\n"); break;
				case ET_CORE:	printf("This is a ET_CORE Type.\n"); break;
				case ET_NUM:	printf("This is a ET_NUM Type.\n"); break;
				case ET_LOOS:	printf("This is a ET_LOOS Type.\n"); break;
				case ET_HIOS:	printf("This is a ET_HIOS Type.\n"); break;
				case ET_LOPROC:	printf("This is a ET_LOPROC Type.\n"); break;
				case ET_HIPROC:	printf("This is a ET_HIPROC Type.\n"); break;
			}

			printf( "Ident:\t\t%d\nType:\t\t%d\nMachine:\t%d\nVersion:\t%d\n"
				"Entry:\t\t%lu\nPHoff:\t\t%lu\nSHoff:\t\t%lu\n"
				"Flags:\t\t%d\nEHSize:\t\t%d\nPHentsize:\t%d\n"
				"PHnum:\t\t%d\nSHentsize\t%d\nSHnum\t\t%d\nSHstrndx\t%d\n\n",
				ehdr.e_ident[EI_NIDENT],
				ehdr.e_type,
				ehdr.e_machine,
				ehdr.e_version,

				ehdr.e_entry,
				ehdr.e_phoff,
   				ehdr.e_shoff,

				ehdr.e_flags,
				ehdr.e_ehsize,
				ehdr.e_phentsize,

				ehdr.e_phnum,
				ehdr.e_shentsize,
				ehdr.e_shnum,
				ehdr.e_shstrndx
			);

			elf_getphdrnum(elf, &n);
			printf("NOTE: elf_getphdrnum=%lu ehdr.e_phnum=%d\n", n, ehdr.e_phnum );

			for (i = 0; i < ehdr.e_phnum; ++i)
			{
				if(gelf_getphdr(elf, i, &phdr) != &phdr)
					error(EXIT_FAILURE, 0, "Failed getphdr: %s", elf_errmsg ( -1));

				printf("\n ********** PROGRAM HEADER TABLE ENTRY ********** \n");
				switch(phdr.p_type)
				{
					case PT_NULL:		printf("This is a PT_NULL type\n"); break;
					case PT_LOAD:		printf("This is a PT_LOAD type\n"); break;
					case PT_DYNAMIC:	printf("This is a PT_DYNAMIC type\n"); break;
					case PT_INTERP:		printf("This is a PT_INTERP type\n"); break;
					case PT_NOTE:		printf("This is a PT_NOTE type\n"); break;
					case PT_SHLIB:		printf("This is a PT_SHLIB type\n"); break;
					case PT_PHDR:		printf("This is a PT_PHDR type\n"); break;
					case PT_TLS:		printf("This is a PT_TLS type\n"); break;
					case PT_NUM:		printf("This is a PT_NUM type\n"); break;
					case PT_LOOS:		printf("This is a PT_LOOS type\n"); break;
					case PT_GNU_EH_FRAME:	printf("This is a PT_GNU_EH_FRAME type\n"); break;
					case PT_GNU_STACK:	printf("This is a PT_GNU_STACK type\n"); break;
					case PT_GNU_RELRO:	printf("This is a PT_GNU_RELRO type\n"); break;
					case PT_PAX_FLAGS:	printf("This is a PT_PAX_FLAGS type\n"); break;
					case PT_LOSUNW:		printf("This is a PT_LOSUNW type\n"); break;
					//case PT_SUNWBSS:	printf("This is a PT_SUNWBSS type\n"); break;
					case PT_SUNWSTACK:	printf("This is a PT_SUNWSTACK type\n"); break;
					case PT_HISUNW:		printf("This is a PT_HISUNW type\n"); break;
					//case PT_HIOS:		printf("This is a PT_HIOS type\n"); break;
					case PT_LOPROC:		printf("This is a PT_LOPROC type\n"); break;
					case PT_HIPROC:		printf("This is a PT_HIPROC type\n"); break;
				}

				printf("Flags:\t\t");
				if( phdr.p_flags & PF_R ) printf("R");
				if( phdr.p_flags & PF_W ) printf("W");
				if( phdr.p_flags & PF_X ) printf("X");
				printf("\n");

				printf( "Type:\t\t%d\nFlags:\t\t%d\nOffset:\t\t%lu\nVaddr:\t\t%lu\nPaddr:\t\t%lu\n"
					"Filesz:\t\t%lu\nMemsz:\t\t%lu\nAlign:\t\t%lu\n",
					phdr.p_type,
					phdr.p_flags,
					phdr.p_offset,
					phdr.p_vaddr,
					phdr.p_paddr,
					phdr.p_filesz,
					phdr.p_memsz,
					phdr.p_align
				);

				printf("\n\n");
			}

			scn = NULL;
			while((scn = elf_nextscn(elf, scn)) != NULL)
			{
				gelf_getshdr(scn, &shdr);
				printf("\n ********** SECTION ********** \n");

				printf("Section name: %s\n", elf_strptr(elf, ehdr.e_shstrndx, shdr.sh_name));

				switch(shdr.sh_type)
				{
					case SHT_DYNAMIC:	printf("This is a SHT_DYNAMIC type\n"); break;
					case SHT_DYNSYM:	printf("This is a SHT_DYNSYM type\n"); break;
					case SHT_HASH:		printf("This is a SHT_HASH type\n"); break;
					case SHT_NOBITS:	printf("This is a SHT_NOBITS type\n"); break;
					case SHT_NOTE:		printf("This is a SHT_NOTE type\n"); break;
					case SHT_NULL:		printf("This is a SHT_NULL type\n"); break;
					case SHT_PROGBITS:	printf("This is a SHT_PROGBITS type\n"); break;
					case SHT_REL:		printf("This is a SHT_REL type\n"); break;
					case SHT_RELA:		printf("This is a SHT_RELA type\n"); break;
					case SHT_STRTAB:	printf("This is a SHT_STRTAB type\n"); break;
					case SHT_SYMTAB:	printf("This is a SHT_SYMTAB type\n"); break;
					default:		printf("This is an unknown section type\n"); break;
				}

				printf(
					"Name:\t\t%d\nType:\t\t%d\nFlags:\t\t%lu\n"
					"Addr:\t\t%lu\nOffset:\t\t%lu\nSize:\t\t%lu\n"
					"Link:\t\t%d\nInfo:\t\t%d\nAddrAlign:\t%lu\nEntsize:\t%lu\n",
					shdr.sh_name,
   					shdr.sh_type,
					shdr.sh_flags,
   					shdr.sh_addr,
					shdr.sh_offset,
   					shdr.sh_size,
					shdr.sh_link,
   					shdr.sh_info,
					shdr.sh_addralign,
   					shdr.sh_entsize
				);

				if((data = elf_getdata(scn, data)) != NULL)
				{
					printf("\n ***** DATA ***** \n");
					printf( "Data:\t\t%s\nType:\t\t%d\nSize:\t\t%lu\n"
						"Off:\t\t%lu\nAlign:\t\t%lu\nVersion:\t%u\n",
						(char *)data->d_buf,
						data->d_type,
						data->d_size,
						data->d_off,
						data->d_align,
   						data->d_version
					);
				}
				printf("\n\n");

			}


			//Print out data in .shstrtab section
			if((scn = elf_getscn(elf, ehdr.e_shstrndx)) == NULL)
				error(EXIT_FAILURE, 0, "getscn() failed: %s.", elf_errmsg(-1));

			if(gelf_getshdr( scn, &shdr ) != &shdr)
				error(EXIT_FAILURE, 0, "getshdr(ehdr.e_shstrndx) failed: %s.", elf_errmsg(-1));

			printf(" .shstrab: size=%jd\n", (uintmax_t)shdr.sh_size);

			data = NULL;
			n = 0;
			while( n < shdr.sh_size && (data = elf_getdata(scn, data)) != NULL )
			{
				p = (char *)data->d_buf ;
				while(p < (char *)data->d_buf + data->d_size)
				{
					printf("%c", *p);
					n++;
					p++;
					if(!(n%16)) printf("\n");
				}
			}
			printf("\n");

		}
		cmd = elf_next(elf);
		elf_end(elf);
	}

	elf_end(arf);

	close(fd);
}