/*
ELF Reader V 0.0.5 Show ELF Information
by wzt <[email protected]>
*/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <elf.h>
#include <sys/stat.h>
#include <sys/mman.h>
#define BUFFER 1024
void usage(char *pro);
void info_elf(char *elf_file,char *function);
void usage(char *pro)
{
fprintf(stdout,"Relf V 0.0.5 by wzt\r\n");
fprintf(stdout,"\nusage:\r\n");
fprintf(stdout,"%s <elf-file> <symbol>\r\n",pro);
exit(0);
}
void info_elf(char *elf_file,char *function)
{
Elf32_Ehdr *ehdr = NULL;
Elf32_Phdr *phdr = NULL;
Elf32_Shdr *shdr = NULL;
Elf32_Shdr *shstrtab = NULL;
Elf32_Sym *dynsym_ptr = NULL;
Elf32_Sym *symtab_ptr = NULL;
Elf32_Sym *dynstr_ptr = NULL;
char *Real_strtab = NULL;
char *dynstr = NULL;
char *strtab_ptr = NULL;
char buffer[BUFFER];
char dynstr_buffer[2048];
char strtab_buffer[4096];
int fd,i;
int phdr_len;
int shdr_len;
int symtab_off,symtab_num;
int dynsym_off,dynsym_size,dynsym_num;
int dynstr_off,dynstr_size;
int shstrtab_off,shstrtab_len,shstrtab_num;
unsigned int strtab_off,strtab_size;
fd = open(elf_file,O_RDWR);
if( fd == -1 ){
perror("elf_file");
exit(1);
}
if( fstat(fd,&stat) == -1 ){
perror("fstat");
exit(1);
}
ehdr = mmap(0, stat.st_size, PROT_WRITE|PROT_READ, MAP_SHARED, fd, 0);
if(ehdr == MAP_FAILED) {
perror("mmap ehdr");
goto err;
}
if(ehdr->e_ident[EI_MAG0] != 0x7f
|| ehdr->e_ident[EI_MAG1] != 'E'
|| ehdr->e_ident[EI_MAG2] != 'L'
|| ehdr->e_ident[EI_MAG3] != 'F'
|| ehdr->e_ident[EI_CLASS] != ELFCLASS32
|| ehdr->e_ident[EI_DATA] != ELFDATA2LSB
|| ehdr->e_ident[EI_VERSION] != EV_CURRENT
|| ehdr->e_type != ET_EXEC
|| ehdr->e_machine != EM_386
|| ehdr->e_version != EV_CURRENT
) {
printf("File type not supported\n");
goto err;
}
phdr = (Elf32_Phdr *)( (unsigned long)ehdr + ehdr->e_phoff );
shdr = (Elf32_Shdr *)( (unsigned long)ehdr + ehdr->e_shoff );
// 节名表所在的节在文件中的地址
shstrtab = &shdr[ehdr->e_shstrndx];
// 节名表在文件中的偏移
shstrtab_off = (unsigned int)shstrtab->sh_offset;
// 节名表的长度
shstrtab_len = shstrtab->sh_size;
// 节名表在内存中的实际地址
Real_strtab = (char *)( (unsigned long)ehdr + shstrtab_off );
printf("[+] .Shstrtab Size :%x,%d\n",shstrtab->sh_size,shstrtab->sh_name);
printf("[+] .Shstrtab Off: %x\n",shstrtab_off);
// 将节名表拷贝到缓冲区中
memcpy(buffer,Real_strtab,shstrtab_len + 1);
for(i = 0 ; i < (int)ehdr->e_shnum ; i++){
if( strcmp(buffer + shdr[i].sh_name,".symtab") == 0 ){
symtab_off = (unsigned int)shdr[i].sh_offset;
symtab_num = (int )(shdr[i].sh_size / shdr[i].sh_entsize);
printf("[+] .Symtab Off : 0x%x num :%d\n",symtab_off,symtab_num);
}
if( strcmp(buffer + shdr[i].sh_name,".strtab") == 0){
strtab_off = (unsigned int)shdr[i].sh_offset;
strtab_size = (unsigned int)shdr[i].sh_size;
printf("[+] .Strtab Off : 0x%x num : %d\n",strtab_off,strtab_size);
}
}
// 将strtab节读到缓冲区中
strtab_ptr = (char *)( (unsigned long)ehdr + strtab_off );
memcpy(strtab_buffer,strtab_ptr,strtab_size + 1);
symtab_ptr = (Elf32_Sym *)( (unsigned long)ehdr + symtab_off );
for(i = 0; i< symtab_num; i++){
if( !strcmp(strtab_buffer + symtab_ptr[i].st_name,function) ){
printf("[+] Found %s!\n",function);
printf("[+] Size :%d!\n", symtab_ptr[i].st_size);
break;
}
}
err:
if (ehdr)
munmap(ehdr, stat.st_size);
if (fd != -1)
close(fd);
}
int main(int argc,char **argv)
{
if( argc == 1 ){
usage(argv[0]);
}
info_elf(argv[1],argv[2]);
return 0;
}
|