Search Posts

libelf example can print out bytes in sections

libelf example

#include <err.h>
#include <fcntl.h>
#include <gelf.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <sysexits.h>
#include <unistd.h>
//#include <bsd/vis.h>

#define	PRINT_FMT 		"    %-20s 0x%jx\n"
#define	PRINT_FMT2 		"    %-20s 0x%jx"
#define PRINT_FIELD(N) 	printf(PRINT_FMT ,#N, (uintmax_t) ehdr.N);
#define PRINT_FIELD2(N)	printf(PRINT_FMT2, #N, (uintmax_t) phdr.N);
#define NL()			printf("\n");

void print_ptype(size_t pt) {
	printf(" ");
	switch (pt) {
		case 0:
			printf("PT_NULL");
			break;
		case 1:
			printf("PT_LOAD");
			break;
		case 2:
			printf("PT_DYNAMIC");
			break;
		case 3:
			printf("PT_INTERP");
			break;
		case 4:
			printf("PT_NOTE");
			break;
		case 5:
			printf("PT_SHLIB");
			break;
		case 6:
			printf("PT_PHDR");
			break;
		case 7:
			printf("PT_TLS");
			break;
		case 8:
			printf("PT_NUM");
			break;
		default:
			printf("unknown");
			break;
	}
}

int main(int argc, char **argv) {
	int i, fd;
	Elf *e;
	char *id, bytes[5];
	size_t n;
	GElf_Ehdr ehdr;
	GElf_Phdr phdr;

	Elf_Scn *scn;
	Elf_Data * data;
	GElf_Shdr shdr;
	size_t shstrndx, sz;
	char *name;
	scn = NULL;

	if (argc != 2)
		errx(EX_USAGE, "usage: %s file-name", argv[0]);
	if (elf_version(EV_CURRENT) == EV_NONE)
		errx(EX_SOFTWARE, "ELF library initialization "
			"failed: %s", elf_errmsg(-1));
	if ((fd = open(argv[1], O_RDONLY, 0)) < 0)
		err(EX_NOINPUT, "open \"%s\" failed", argv[1]);
	if ((e = elf_begin(fd, ELF_C_READ, NULL)) == NULL)
		errx(EX_SOFTWARE, "elf_begin() failed: %s.", elf_errmsg(-1));
	if (elf_kind(e) != ELF_K_ELF)
		errx(EX_DATAERR, "\"%s\" is not an ELF object.", argv[1]);
	if (gelf_getehdr(e, &ehdr) == NULL)
		errx(EX_SOFTWARE, "getehdr() failed: %s.", elf_errmsg(-1));
	if (elf_getshdrstrndx(e, &shstrndx) != 0)
		errx(EXIT_FAILURE, " elf_getshdrstrndx ()  failed : %s.", elf_errmsg(-1));

	if ((i = gelf_getclass(e)) == ELFCLASSNONE)
		errx(EX_SOFTWARE, "getclass() failed: %s.", elf_errmsg(-1));
	printf("%s: %d-bit ELF object\n", argv[1], i == ELFCLASS32 ? 32 : 64);
	if ((id = elf_getident(e, NULL)) == NULL)
		errx(EX_SOFTWARE, "getident() failed: %s.", elf_errmsg(-1));
	printf("%3s e_ident[0..%1d]%7s", " ", EI_ABIVERSION, " ");
	for (i = 0; i <= EI_ABIVERSION; i++) {
		printf(" 0x%x", id[i]);
	}
	printf("\n");

	PRINT_FIELD(e_type);
	PRINT_FIELD(e_machine);
	PRINT_FIELD(e_version);
	PRINT_FIELD(e_entry);
	PRINT_FIELD(e_phoff);
	PRINT_FIELD(e_shoff);
	PRINT_FIELD(e_flags);
	PRINT_FIELD(e_ehsize);
	PRINT_FIELD(e_phentsize);
	PRINT_FIELD(e_shentsize);

	if (elf_getshdrnum(e, &n) != 0)
		errx(EX_SOFTWARE, "getshdrnum() failed: %s.", elf_errmsg(-1));
	printf(PRINT_FMT, "(shnum)", (uintmax_t) n);
	if (elf_getshdrstrndx(e, &n) != 0)
		errx(EX_SOFTWARE, "getshdrstrndx() failed: %s.", elf_errmsg(-1));
	printf(PRINT_FMT, "(shstrndx)", (uintmax_t) n);
	if (elf_getphdrnum(e, &n) != 0)
		errx(EX_SOFTWARE, "getphdrnum() failed: %s.", elf_errmsg(-1));
	printf(PRINT_FMT, "(phnum)", (uintmax_t) n);

	if (elf_getphdrnum(e, &n) != 0)
		errx(EX_DATAERR, "elf_getphdrnum() failed: %s.", elf_errmsg(-1));

	FILE *file = fopen(argv[1], "r");
	fseek(file, 0, SEEK_END);
	long fileSize = ftell(file);
	rewind(file);
	char *buffer = (char *) malloc(fileSize);
	fread(buffer, 1, fileSize, file);
	fclose(file);

	for (i = 0; i < n; i++) {
		if (gelf_getphdr(e, i, &phdr) != &phdr)
			errx(EX_SOFTWARE, "getphdr() failed: %s.", elf_errmsg(-1));

		printf("PHDR %d:\n", i);
		PRINT_FIELD2(p_type);
		print_ptype(phdr.p_type);
		NL()
				;
		PRINT_FIELD2(p_offset);
		NL()
				;
		PRINT_FIELD2(p_vaddr);
		NL()
				;
		PRINT_FIELD2(p_paddr);
		NL()
				;
		PRINT_FIELD2(p_filesz);
		NL()
				;
		PRINT_FIELD2(p_memsz);
		NL()
				;
		PRINT_FIELD2(p_flags);
		printf(" [");
		if (phdr.p_flags & PF_X)
			printf(" execute");
		if (phdr.p_flags & PF_R)
			printf(" read");
		if (phdr.p_flags & PF_W)
			printf(" write");
		printf(" ]");
		NL()
				;
		PRINT_FIELD2(p_align);
		NL()
				;

		if (phdr.p_type == 1) {
			printf("%x\n%x\n", phdr.p_offset, ehdr.e_ehsize);
			for (int x = 0x74; x < 0x80; x++) {
				printf("%x ", buffer[x] & 0xff);
			}
			printf("\n");
		}
	}
	Elf_Data *edata = NULL;
	while ((scn = elf_nextscn(e, scn)) != NULL) {
		if (gelf_getshdr(scn, &shdr) != &shdr)
			errx(EXIT_FAILURE, "getshdr ()  failed : %s.", elf_errmsg(-1));

		switch (shdr.sh_type) {
			case SHT_NULL: printf("SHT_NULL");
				break;
			case SHT_PROGBITS: printf("SHT_PROGBITS");
				break;
			case SHT_SYMTAB: printf("SHT_SYMTAB");
				break;
			case SHT_STRTAB: printf("SHT_STRTAB");
				break;
			case SHT_RELA: printf("SHT_RELA");
				break;
			case SHT_HASH: printf("SHT_HASH");
				break;
			case SHT_DYNAMIC: printf("SHT_DYNAMIC");
				break;
			case SHT_NOTE: printf("SHT_NOTE");
				break;
			case SHT_NOBITS: printf("SHT_NOBITS");
				break;
			case SHT_REL: printf("SHT_REL\t");
				break;
			case SHT_SHLIB: printf("SHT_SHLIB");
				break;
			case SHT_DYNSYM: printf("SHT_DYNSYM");
				break;
			case SHT_INIT_ARRAY: printf("SHT_INIT_ARRAY");
				break;
			case SHT_FINI_ARRAY: printf("SHT_FINI_ARRAY");
				break;
			case SHT_PREINIT_ARRAY: printf("SHT_PREINIT_ARRAY");
				break;
			case SHT_GROUP: printf("SHT_GROUP");
				break;
			case SHT_SYMTAB_SHNDX: printf("SHT_SYMTAB_SHNDX");
				break;
			case SHT_NUM: printf("SHT_NUM ");
				break;
			case SHT_LOOS: printf("SHT_LOOS");
				break;
			case SHT_GNU_verdef: printf("SHT_GNU_verdef");
				break;
			case SHT_GNU_verneed: printf("SHT_VERNEED");
				break;
			case SHT_GNU_versym: printf("SHT_GNU_versym");
				break;
			default: printf("(none) ");
				break;
		}


		printf("\t\t\t%x, %x\n", shdr.sh_offset, shdr.sh_size);


		while (1) {
			edata = elf_getdata(scn, edata);
			if (edata == NULL) {
				break;
			}
			printf("         ");
			for (int x=0;x<10;x++){
				printf("%x ", ((char *)edata->d_buf)[x]);
			}
			printf("\n");
		}
	}

	(void) elf_end(e);
	(void) close(fd);

	return 0;
}
all: clean libelf_example2

libelf_example2: libelf_example2.c
	gcc $? -o $@ -g -lelf -I /opt/local/include/libelf -I /opt/local/include -L /opt/local/lib/
	#gcc $? -o $@ -g -lelf -std=c11 -lelf

clean:
	rm -fr libelf_example2

run:
	./libelf_example2 ~/workspace/PeterI/library/testingLibrary/test.exe

Leave a Reply

Your email address will not be published. Required fields are marked *