-
Notifications
You must be signed in to change notification settings - Fork 0
/
elf32.c
170 lines (150 loc) · 4.54 KB
/
elf32.c
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
/*
* Copyright (c) 1999-2004 University of New South Wales
*
* SPDX-License-Identifier: BSD-3-Clause
*/
#include "elf.h"
int elf32_checkFile(
struct Elf32_Header const *file)
{
if (file->e_ident[EI_MAG0] != ELFMAG0
|| file->e_ident[EI_MAG1] != ELFMAG1
|| file->e_ident[EI_MAG2] != ELFMAG2
|| file->e_ident[EI_MAG3] != ELFMAG3) {
return -1; /* not an elf file */
}
if (file->e_ident[EI_CLASS] != ELFCLASS32) {
return -2; /* not 32-bit file */
}
return 0; /* elf file looks OK */
}
/*
* Returns the number of program segments in this elf file.
*/
unsigned int elf32_getNumSections(
struct Elf32_Header const *elfFile)
{
return elfFile->e_shnum;
}
char const *elf32_getStringTable(
struct Elf32_Header const *elfFile)
{
struct Elf32_Shdr const *sections = elf32_getSectionTable(elfFile);
return (char const *)elfFile + sections[elfFile->e_shstrndx].sh_offset;
}
/* Returns a pointer to the program segment table, which is an array of
* ELF32_Phdr_t structs. The size of the array can be found by calling
* getNumProgramSegments. */
struct Elf32_Phdr const *elf32_getProgramSegmentTable(
struct Elf32_Header const *elfFile)
{
struct Elf32_Header const *fileHdr = elfFile;
return (struct Elf32_Phdr const *)(fileHdr->e_phoff + (long) elfFile);
}
/* Returns the number of program segments in this elf file. */
uint16_t elf32_getNumProgramHeaders(
struct Elf32_Header const *elfFile)
{
struct Elf32_Header const *fileHdr = elfFile;
return fileHdr->e_phnum;
}
char const *elf32_getSectionName(
struct Elf32_Header const *elfFile,
unsigned int i)
{
struct Elf32_Shdr const *sections = elf32_getSectionTable(elfFile);
char const *str_table = elf32_getSegmentStringTable(elfFile);
if (str_table == NULL) {
return "<corrupted>";
} else {
return str_table + sections[i].sh_name;
}
}
uint32_t elf32_getSectionSize(
struct Elf32_Header const *elfFile,
unsigned int i)
{
struct Elf32_Shdr const *sections = elf32_getSectionTable(elfFile);
return sections[i].sh_size;
}
uint32_t elf32_getSectionAddr(
struct Elf32_Header const *elfFile,
unsigned int i)
{
struct Elf32_Shdr const *sections = elf32_getSectionTable(elfFile);
return sections[i].sh_addr;
}
void const *elf32_getSection(
struct Elf32_Header const *elfFile,
unsigned int i)
{
struct Elf32_Shdr const *sections = elf32_getSectionTable(elfFile);
return (char *)elfFile + sections[i].sh_offset;
}
void const *elf32_getSectionNamed(
struct Elf32_Header const *elfFile,
char const *str)
{
unsigned int numSections = elf32_getNumSections(elfFile);
for (unsigned int i = 0; i < numSections; i++) {
if (strcmp(str, elf32_getSectionName(elfFile, i)) == 0) {
return elf32_getSection(elfFile, i);
}
}
return NULL;
}
char const *elf32_getSegmentStringTable(
struct Elf32_Header const *elfFile)
{
struct Elf32_Header const *fileHdr = (struct Elf32_Header *) elfFile;
if (fileHdr->e_shstrndx == 0) {
return NULL;
} else {
return elf32_getStringTable(elfFile);
}
}
#ifdef ELF_DEBUG
void elf32_printStringTable(
struct Elf32_Header const *elfFile)
{
struct Elf32_Shdr *sections = elf32_getSectionTable(elfFile);
char *stringTable;
if (!sections) {
printf("No sections.\n");
return;
}
stringTable = ((void *)elfFile) + sections[elfFile->e_shstrndx].sh_offset;
printf("File is %p; sections is %p; string table is %p\n", elfFile, sections, stringTable);
for (unsigned int counter = 0; counter < sections[elfFile->e_shstrndx].sh_size; counter++) {
printf("%02x %c ", stringTable[counter],
stringTable[counter] >= 0x20 ? stringTable[counter] : '.');
}
}
#endif
uint32_t elf32_getSegmentType(
struct Elf32_Header const *elfFile,
unsigned int segment)
{
return elf32_getProgramSegmentTable(elfFile)[segment].p_type;
}
void elf32_getSegmentInfo(
struct Elf32_Header const *elfFile,
unsigned int segment,
uint64_t *p_vaddr,
uint64_t *p_addr,
uint64_t *p_filesz,
uint64_t *p_offset,
uint64_t *p_memsz)
{
struct Elf32_Phdr const *segments = elf32_getProgramSegmentTable(elfFile);
*p_addr = segments[segment].p_paddr;
*p_vaddr = segments[segment].p_vaddr;
*p_filesz = segments[segment].p_filesz;
*p_offset = segments[segment].p_offset;
*p_memsz = segments[segment].p_memsz;
}
uint32_t elf32_getEntryPoint(
struct Elf32_Header const *elfFile)
{
return elfFile->e_entry;
}