aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDark Ness <darkness@yellowness.dis>2011-04-12 13:29:52 -0400
committerDark Ness <darkness@yellowness.dis>2011-04-12 13:29:52 -0400
commit3c8478886c9300ca1b685e6140988868a77ff745 (patch)
tree2f1f6ce381bca0cf584fd5b0a024869e2bf3a0a7
downloadelfix-3c8478886c9300ca1b685e6140988868a77ff745.tar.gz
elfix-3c8478886c9300ca1b685e6140988868a77ff745.tar.bz2
elfix-3c8478886c9300ca1b685e6140988868a77ff745.zip
Initial commit
-rw-r--r--Makefile12
-rw-r--r--README7
-rw-r--r--misc/eheader.c251
-rw-r--r--parse_elf.c259
-rw-r--r--test.c5
5 files changed, 534 insertions, 0 deletions
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..826632d
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,12 @@
+
+SRCS = parse_elf test
+
+.PHONY: all
+all: $(SRCS)
+
+.PHONY: clean
+clean:
+ rm -f $(SRCS)
+
+%: %.c
+ gcc -o $@ $^ -lelf
diff --git a/README b/README
new file mode 100644
index 0000000..19b97eb
--- /dev/null
+++ b/README
@@ -0,0 +1,7 @@
+
+Miscellaneous Elf/GElf functions to parse an Elf object
+
+Author
+
+ Anthony G. Basile <blueness@gentoo.org>
+
diff --git a/misc/eheader.c b/misc/eheader.c
new file mode 100644
index 0000000..697f81e
--- /dev/null
+++ b/misc/eheader.c
@@ -0,0 +1,251 @@
+
+#include <stdio.h> // printf
+#include <stdlib.h> // EXIT_FAILURE
+#include <error.h> // error
+
+#include <gelf.h> // elf_*
+
+#include <sys/types.h> // open
+#include <sys/stat.h>
+#include <fcntl.h>
+
+
+int main( int argc, char *argv[])
+{
+ int fd, cmd;
+ Elf *arf, *elf;
+ Elf64_Ehdr *ehdr;
+ Elf_Arhdr *arhdr;
+ Elf64_Phdr *phdr;
+ Elf_Scn *scn;
+ Elf64_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, "Incorrect usage.");
+
+ if((fd = open(argv[1], O_RDONLY)) == -1)
+ error(EXIT_FAILURE, 0, "Failed open file.");
+
+
+ cmd = ELF_C_READ;
+ arf = elf_begin(fd, cmd, (Elf *)0);
+
+ 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)) != 0)
+ {
+ if((ehdr = elf64_getehdr(elf)) != 0)
+ {
+ 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;
+ default:
+ 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
+ );
+
+ if((phdr = elf64_getphdr(elf)) != 0)
+ {
+ printf("\n ********** PROGRAM HEADER ********** \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
+ );
+ }
+
+ for (i = 0; i < ehdr.e_phnum; ++i)
+ {
+ gelf_getphdr (elf, i, phdr+i);
+ i++ ;
+
+ printf("\n ********** PROGRAM HEADER TABLE ENTRY ********** \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+i)->p_type,
+ (phdr+i)->p_flags,
+ (phdr+i)->p_offset,
+ (phdr+i)->p_vaddr,
+ (phdr+i)->p_paddr,
+ (phdr+i)->p_filesz,
+ (phdr+i)->p_memsz,
+ (phdr+i)->p_align
+ );
+ }
+
+
+ scn = 0;
+ while ((scn = elf_nextscn(elf, scn)) != 0)
+ {
+ shdr = elf64_getshdr(scn);
+ printf("\n ********** SECTION ********** \n");
+ 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)) != 0)
+ {
+ 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");
+
+ }
+ }
+ cmd = elf_next(elf);
+ elf_end(elf);
+ }
+
+ elf_end(arf);
+
+ close(fd);
+}
diff --git a/parse_elf.c b/parse_elf.c
new file mode 100644
index 0000000..c18d277
--- /dev/null
+++ b/parse_elf.c
@@ -0,0 +1,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);
+}
diff --git a/test.c b/test.c
new file mode 100644
index 0000000..196d2fc
--- /dev/null
+++ b/test.c
@@ -0,0 +1,5 @@
+int main()
+{
+ ;
+ return 0 ;
+}