summaryrefslogtreecommitdiffstats
path: root/elfreader.h
blob: 06a5747959c9be80e0c79ab5c46389f8c14507a0 (plain) (blame)
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
#ifndef __ELFREADER_H
#define __ELFREADER_H

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <elf.h>

#include "debug.h"
#include "assert.h"

#define SWP16(X) (((X)&0x00FF)<<8)|(((X)&0xFF00)>>8)
#define SWP32(X) ((((X)&0x00FF)<<24)|(((X)&0xFF00)<<8)|(((X)&0xFF0000)>>8)|(((X)&0xFF000000)>>24))


#define ELF_TYPE_UNKNOWN 0
#define ELF_TYPE_32      1
#define ELF_TYPE_64      2

/* if you add header on Intel(LE) on MIPS(be) arch
   then you going to have troubles. Lets prepare for this troubles
 */
#define ELF_ENONE 0
#define ELF_LLSB  1
#define ELF_LMSB  2
#define ELF_MLSB  3
#define ELF_MMSB  4

typedef struct Elf_Ident {
	unsigned char ident[EI_NIDENT];
} Elf_Ident;


/*
++++++++++++++++++++++++++++++++++++
+  Type  +   ELF32   +    ELF64    +
++++++++++++++++++++++++++++++++++++
+Half	 +  uint16_t  +  uint16_t  +
+Word    +  uint32_t  +  uint32_t  +
+Sword   +  int32_t   +  int32_t   +
+Xword   +  uint64_t  +  uint64_t  +
+Sxword  +  int64_t   +  int64_t   +
+Addr    +  uint32_t  +  uint64_t  +
+Off     +  uint32_t  +  uint64_t  +
+Section +  uint16_t  +  uint16_t  +
+Versym  +  uint16_t  +  uint16_t  +
++++++++++++++++++++++++++++++++++++
*/


typedef struct Elf_Ehdr {
	int		type;	/* to distinguish 32 or its 64 bits */
	int		byteorder;

	/* generic elf header information */
	uint16_t	e_type;			
	uint16_t	e_machine;		
	uint32_t	e_version;		
	uint64_t	e_entry;		
	uint64_t	e_phoff;		
	uint64_t	e_shoff;		
	uint32_t	e_flags;		
	uint16_t	e_ehsize;		
	uint16_t	e_phentsize;		
	uint16_t	e_phnum;		
	uint16_t	e_shentsize;		
	uint16_t	e_shnum;		
	uint16_t	e_shstrndx;		
} Elf_Ehdr;


typedef struct Elf_Phdr {
	int		type;
	uint32_t 	offset;			/* Offset in file */
	int		byteorder;
	
	/* generic progeam heaer information */
	uint32_t	p_type;			/* Segment type */
	uint64_t	p_offset;		/* Segment file offset */
	uint64_t	p_vaddr;		/* Segment virtual address */
	uint64_t	p_paddr;		/* Segment physical address */
	uint32_t	p_filesz;		/* Segment size in file */
	uint32_t	p_memsz;		/* Segment size in memory */
	uint32_t	p_flags;		/* Segment flags */
	uint32_t	p_align;		/* Segment alignment */
} Elf_Phdr;


typedef struct Elf_Shdr {
	int		type;
	uint32_t	offset;			/* Offset inside file */
	int		byteorder;
	
	/* generic section header information  */
	uint32_t	sh_name;		/* Section name (string tbl index) */
	uint32_t	sh_type;		/* Section type */
	uint64_t	sh_flags;		/* Section flags */
	uint64_t	sh_addr;		/* Section virtual addr at execution */
	uint64_t	sh_offset;		/* Section file offset */
	uint64_t	sh_size;		/* Section size in bytes */
	uint32_t	sh_link;		/* Link to another section */
	uint32_t	sh_info;		/* Additional section information */
	uint64_t	sh_addralign;		/* Section alignment */
	uint64_t	sh_entsize;
} Elf_Shdr;

typedef struct Elf_Shdr_strtab {
	long     offset;
	int      sz_tab;
	uint8_t *strtab;
} Elf_Shdr_strtab;

Elf_Ident* elf_ident(  FILE *f );
int ident_check( Elf_Ident *ident );
void ident_info( Elf_Ident *ident );

/* 
All headers can have different types or different offsets inside structure 
should we write each function 2 times for 32/64? or just one generic function
and type convos in between?
*/
/* ehdr := mapping ehdr32 */
int elf_ehdr_32( Elf_Ehdr *ehdr,     Elf32_Ehdr *ehdr32, int byteorder );
/* ehdr := mapping ehdr64 */
int elf_ehdr_64( Elf_Ehdr *ehdr,     Elf64_Ehdr *ehdr64, int byteorder );
/* ehdr32 := mapping ehdr */
int elf_32_ehdr( Elf32_Ehdr *ehdr32, Elf_Ehdr *ehdr );
/* ehdr64 := mapping ehdr */
int elf_64_ehdr( Elf64_Ehdr *ehdr64, Elf_Ehdr *ehdr );
int elf_ehdr32_bele( Elf32_Ehdr *ehdr32 );
int elf_ehdr32_lebe( Elf32_Ehdr *ehdr32 );
int elf_ehdr2mem( Elf_Ident *ident, Elf_Ehdr *ehdr, uint8_t *buf, int size );
Elf_Ehdr*    elf_header( FILE *f, Elf_Ident *ident, int sysorder );
void header_info( Elf_Ehdr *ehdr );


int elf_phdr_32( Elf_Phdr *phdr,     Elf32_Phdr *phdr32 );
int elf_phdr_64( Elf_Phdr *phdr,     Elf64_Phdr *phdr64 );
int elf_32_phdr( Elf32_Phdr *phdr32, Elf_Phdr   *phdr );
int elf_64_phdr( Elf64_Phdr *phdr64, Elf_Phdr   *phdr );
Elf_Phdr*   elf_phdr(    FILE *f, Elf_Ehdr  *ehdr  );


int elf_shdr_32( Elf_Shdr *shdr, Elf32_Shdr *shdr32 );
int elf_shdr_64( Elf_Shdr *shdr, Elf64_Shdr *shdr64 );
int elf_32_shdr( Elf32_Shdr *shdr32, Elf_Shdr *shdr );
int elf_64_shdr( Elf64_Shdr *shdr64, Elf_Shdr *shdr );
int elf_shdr64_lebe( Elf64_Shdr *shdr64 );
int elf_shdr32_lebe( Elf32_Shdr *shdr32 );
int elf_shdr2mem( Elf_Shdr *shdr, uint8_t *buf, int size, int offset );
Elf_Shdr**  elf_shdr( FILE *f, Elf_Ehdr  *ehdr  );
void section_info( Elf_Shdr* shdr, Elf_Shdr_strtab *strtab );

/* Search for strtab section */
Elf_Shdr_strtab* strtab_search( FILE *f, Elf_Ehdr *ehdr, Elf_Shdr **shdr );
unsigned char* strtab_name( Elf_Shdr_strtab *strtab, long offset );

#endif