[Aporte] Obtener los simbolos de un archivo ELF

Iniciado por 0xDani, 15 Diciembre 2012, 17:16 PM

0 Miembros y 1 Visitante están viendo este tema.

0xDani

Bueno aqui os dejo esta pequeña herramienta que he hecho para ver algunos datos sobre los simbolos de una libreria dinamica o un ejecutable ELF: http://es.wikipedia.org/wiki/Executable_and_Linkable_Format

Cualquier pregunta, comentario o critica constructiva posteen  ;)

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

int main(int argc, char **argv)
{

char *shstrtabdata, *strtabdata, *dynstrdata;
int i, off;
bool strtabf=true, symtabf=true, dynsymf=true;

size_t ret;

Elf32_Ehdr *hdr = malloc(sizeof(Elf32_Ehdr));
Elf32_Shdr shdr, shstrtab, strtab, dynsym, dynstr;
Elf32_Sym sym;

FILE *dyn = fopen(argv[1], "rb");
if(!dyn)
{
  perror("fopen");
  exit(1);
}

fread(hdr, sizeof(Elf32_Ehdr), 1, dyn);
fseek(dyn, hdr->e_shoff+hdr->e_shentsize*hdr->e_shstrndx, SEEK_SET);
fread(&shstrtab, sizeof(shstrtab), 1, dyn);
shstrtabdata = malloc(shstrtab.sh_size);
if(!shstrtabdata)
{
  perror("malloc");
  exit(2);
}
fseek(dyn, shstrtab.sh_offset, SEEK_SET);
fread(shstrtabdata, 1, shstrtab.sh_size, dyn);
fseek(dyn, hdr->e_shoff, SEEK_SET);

fwrite(shstrtabdata, 1, shstrtab.sh_size, stdin);

for(i=0; i<hdr->e_shnum; i++)
{
  fread(&shdr, sizeof(shdr), 1, dyn);
  if(!strcmp(shstrtabdata+shdr.sh_name, ".symtab"))
  {
   printf(".symtab encontrada: offset: 0x%x\n", shdr.sh_offset);
   printf("Tamaño de .symtab: %d\n", shdr.sh_size);
   printf("Numero de sym headers: %f\n", (float) shdr.sh_size/(float) sizeof(Elf32_Sym));
   symtabf = false;
   break;
  }
}

if(symtabf)
{
  printf("sección .symtab no encontrada.\n");
}

fseek(dyn, hdr->e_shoff, SEEK_SET);

for(i=0; i<hdr->e_shnum; i++)
{
  fread(&dynsym, sizeof(dynsym), 1, dyn);
  if(!strcmp(shstrtabdata+dynsym.sh_name, ".dynsym"))
  {
   printf(".dynsym encontrada: offset: 0x%x\n", dynsym.sh_offset);
   dynsymf=false;
   break;
  }
}

fseek(dyn, hdr->e_shoff, SEEK_SET);

for(i=0; i<hdr->e_shnum; i++)
{
  fread(&dynstr, sizeof(dynstr), 1, dyn);
  if(!strcmp(shstrtabdata+dynstr.sh_name, ".dynstr"))
  {
   printf(".dynstr encontrada: offset: 0x%x\n", dynstr.sh_offset);
   printf("Tamaño de .dynstr: 0x%x\n", dynstr.sh_size);
   break;
  }
}

dynstrdata = malloc(dynstr.sh_size);
if(!dynstrdata)
{
  perror("malloc");
  exit(5);
}

fseek(dyn, dynstr.sh_offset, SEEK_SET);
ret = fread(dynstrdata, 1, dynstr.sh_size, dyn);

fseek(dyn, hdr->e_shoff, SEEK_SET);

for(i=0; i<hdr->e_shnum; i++)
{
  fread(&strtab, sizeof(strtab), 1, dyn);
  if(!strcmp(shstrtabdata+strtab.sh_name, ".strtab"))
  {
   printf(".strtab encontrada: offset: 0x%x\n", strtab.sh_offset);
   strtabf = false;
   break;
  }
}

if(strtabf)
{
  printf("sección .strtab no encontrada.\n");
}


if(!strtabf)
{
  strtabdata = malloc(strtab.sh_size);
  if(!strtabdata)
  {
   perror("malloc");
   exit(3);
  }
  fseek(dyn, strtab.sh_offset, SEEK_SET);
  ret=fread(strtabdata, 1, strtab.sh_size, dyn);
  if(ret!=strtab.sh_size)
  {
    perror("fread");
    exit(4);
  }
}


  fseek(dyn, shdr.sh_offset, SEEK_SET);


if(!symtabf)
{
  printf("***Symtab***\n\n");
  i=0;
  while(shdr.sh_size>i)
  {
   ret=fread(&sym, sizeof(sym), 1, dyn);
   i+=sizeof(sym);
   printf("%s\n", strtabdata+sym.st_name);
   printf("Direccion: 0x%x\t", sym.st_value);
   printf("Tamaño: 0x%x\t", sym.st_size);
   if(sym.st_info & STT_NOTYPE) printf("Tipo no definido\t");
   if(sym.st_info & STT_OBJECT) printf("Data object\t");
   if(sym.st_info & STT_FUNC) printf("Funcion\t");
   if(sym.st_info & STT_FILE) printf("Fichero fuente\t");
   printf("\n");
  }
  printf("Numero de simbolos: %d\n", i/16);
}

fseek(dyn, dynsym.sh_offset, SEEK_SET);

if(!dynsymf)
{
  printf("***Dynsym***\n\n");
  i=0;
  while(dynsym.sh_size>i)
  {
   ret=fread(&sym, sizeof(sym), 1, dyn);
   i+=sizeof(sym);
   printf("%s\n", dynstrdata+sym.st_name);
   printf("Direccion: 0x%x\t", sym.st_value);
   printf("Tamaño: 0x%x\t", sym.st_size);
   if(sym.st_info & STT_NOTYPE) printf("Tipo no definido\t");
   if(sym.st_info & STT_OBJECT) printf("Data object\t");
   if(sym.st_info & STT_FUNC) printf("Funcion\t");
   if(sym.st_info & STT_FILE) printf("Fichero fuente\t");
   printf("\n");
  }
  printf("Numero de simbolos: %d\n", i/16);
}

if(!strtabf) free(strtabdata);
free(shstrtabdata);
if(!dynsymf) free(dynstrdata);

return 0;

}


El modo de uso es tan simple como pasarle como argumento la ruta del archivo a analizar.

Saludos!
I keep searching for something that I never seem to find, but maybe I won't, because I left it all behind!

I code for $$$
Hago trabajos en C/C++
Contactar por PM