Foro de elhacker.net

Seguridad Informática => Análisis y Diseño de Malware => Mensaje iniciado por: 0xDani en 15 Diciembre 2012, 17:16 pm



Título: [Aporte] Obtener los simbolos de un archivo ELF
Publicado por: 0xDani en 15 Diciembre 2012, 17:16 pm
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  ;)

Código
  1. #include <stdio.h>
  2. #include <string.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include <elf.h>
  6.  
  7. int main(int argc, char **argv)
  8. {
  9.  
  10. char *shstrtabdata, *strtabdata, *dynstrdata;
  11. int i, off;
  12. bool strtabf=true, symtabf=true, dynsymf=true;
  13.  
  14. size_t ret;
  15.  
  16. Elf32_Ehdr *hdr = malloc(sizeof(Elf32_Ehdr));
  17. Elf32_Shdr shdr, shstrtab, strtab, dynsym, dynstr;
  18. Elf32_Sym sym;
  19.  
  20. FILE *dyn = fopen(argv[1], "rb");
  21. if(!dyn)
  22. {
  23.  perror("fopen");
  24.  exit(1);
  25. }
  26.  
  27. fread(hdr, sizeof(Elf32_Ehdr), 1, dyn);
  28. fseek(dyn, hdr->e_shoff+hdr->e_shentsize*hdr->e_shstrndx, SEEK_SET);
  29. fread(&shstrtab, sizeof(shstrtab), 1, dyn);
  30. shstrtabdata = malloc(shstrtab.sh_size);
  31. if(!shstrtabdata)
  32. {
  33.  perror("malloc");
  34.  exit(2);
  35. }
  36. fseek(dyn, shstrtab.sh_offset, SEEK_SET);
  37. fread(shstrtabdata, 1, shstrtab.sh_size, dyn);
  38. fseek(dyn, hdr->e_shoff, SEEK_SET);
  39.  
  40. fwrite(shstrtabdata, 1, shstrtab.sh_size, stdin);
  41.  
  42. for(i=0; i<hdr->e_shnum; i++)
  43. {
  44.  fread(&shdr, sizeof(shdr), 1, dyn);
  45.  if(!strcmp(shstrtabdata+shdr.sh_name, ".symtab"))
  46.  {
  47.   printf(".symtab encontrada: offset: 0x%x\n", shdr.sh_offset);
  48.   printf("Tamaño de .symtab: %d\n", shdr.sh_size);
  49.   printf("Numero de sym headers: %f\n", (float) shdr.sh_size/(float) sizeof(Elf32_Sym));
  50.   symtabf = false;
  51.   break;
  52.  }
  53. }
  54.  
  55. if(symtabf)
  56. {
  57.  printf("sección .symtab no encontrada.\n");
  58. }
  59.  
  60. fseek(dyn, hdr->e_shoff, SEEK_SET);
  61.  
  62. for(i=0; i<hdr->e_shnum; i++)
  63. {
  64.  fread(&dynsym, sizeof(dynsym), 1, dyn);
  65.  if(!strcmp(shstrtabdata+dynsym.sh_name, ".dynsym"))
  66.  {
  67.   printf(".dynsym encontrada: offset: 0x%x\n", dynsym.sh_offset);
  68.   dynsymf=false;
  69.   break;
  70.  }
  71. }
  72.  
  73. fseek(dyn, hdr->e_shoff, SEEK_SET);
  74.  
  75. for(i=0; i<hdr->e_shnum; i++)
  76. {
  77.  fread(&dynstr, sizeof(dynstr), 1, dyn);
  78.  if(!strcmp(shstrtabdata+dynstr.sh_name, ".dynstr"))
  79.  {
  80.   printf(".dynstr encontrada: offset: 0x%x\n", dynstr.sh_offset);
  81.   printf("Tamaño de .dynstr: 0x%x\n", dynstr.sh_size);
  82.   break;
  83.  }
  84. }
  85.  
  86. dynstrdata = malloc(dynstr.sh_size);
  87. if(!dynstrdata)
  88. {
  89.  perror("malloc");
  90.  exit(5);
  91. }
  92.  
  93. fseek(dyn, dynstr.sh_offset, SEEK_SET);
  94. ret = fread(dynstrdata, 1, dynstr.sh_size, dyn);
  95.  
  96. fseek(dyn, hdr->e_shoff, SEEK_SET);
  97.  
  98. for(i=0; i<hdr->e_shnum; i++)
  99. {
  100.  fread(&strtab, sizeof(strtab), 1, dyn);
  101.  if(!strcmp(shstrtabdata+strtab.sh_name, ".strtab"))
  102.  {
  103.   printf(".strtab encontrada: offset: 0x%x\n", strtab.sh_offset);
  104.   strtabf = false;
  105.   break;
  106.  }
  107. }
  108.  
  109. if(strtabf)
  110. {
  111.  printf("sección .strtab no encontrada.\n");
  112. }
  113.  
  114.  
  115. if(!strtabf)
  116. {
  117.  strtabdata = malloc(strtab.sh_size);
  118.  if(!strtabdata)
  119.  {
  120.   perror("malloc");
  121.   exit(3);
  122.  }
  123.  fseek(dyn, strtab.sh_offset, SEEK_SET);
  124.  ret=fread(strtabdata, 1, strtab.sh_size, dyn);
  125.  if(ret!=strtab.sh_size)
  126.  {
  127.    perror("fread");
  128.    exit(4);
  129.  }
  130. }
  131.  
  132.  
  133.  fseek(dyn, shdr.sh_offset, SEEK_SET);
  134.  
  135.  
  136. if(!symtabf)
  137. {
  138.  printf("***Symtab***\n\n");
  139.  i=0;
  140.  while(shdr.sh_size>i)
  141.  {
  142.   ret=fread(&sym, sizeof(sym), 1, dyn);
  143.   i+=sizeof(sym);
  144.   printf("%s\n", strtabdata+sym.st_name);
  145.   printf("Direccion: 0x%x\t", sym.st_value);
  146.   printf("Tamaño: 0x%x\t", sym.st_size);
  147.   if(sym.st_info & STT_NOTYPE) printf("Tipo no definido\t");
  148.   if(sym.st_info & STT_OBJECT) printf("Data object\t");
  149.   if(sym.st_info & STT_FUNC) printf("Funcion\t");
  150.   if(sym.st_info & STT_FILE) printf("Fichero fuente\t");
  151.   printf("\n");
  152.  }
  153.  printf("Numero de simbolos: %d\n", i/16);
  154. }
  155.  
  156. fseek(dyn, dynsym.sh_offset, SEEK_SET);
  157.  
  158. if(!dynsymf)
  159. {
  160.  printf("***Dynsym***\n\n");
  161.  i=0;
  162.  while(dynsym.sh_size>i)
  163.  {
  164.   ret=fread(&sym, sizeof(sym), 1, dyn);
  165.   i+=sizeof(sym);
  166.   printf("%s\n", dynstrdata+sym.st_name);
  167.   printf("Direccion: 0x%x\t", sym.st_value);
  168.   printf("Tamaño: 0x%x\t", sym.st_size);
  169.   if(sym.st_info & STT_NOTYPE) printf("Tipo no definido\t");
  170.   if(sym.st_info & STT_OBJECT) printf("Data object\t");
  171.   if(sym.st_info & STT_FUNC) printf("Funcion\t");
  172.   if(sym.st_info & STT_FILE) printf("Fichero fuente\t");
  173.   printf("\n");
  174.  }
  175.  printf("Numero de simbolos: %d\n", i/16);
  176. }
  177.  
  178. if(!strtabf) free(strtabdata);
  179. free(shstrtabdata);
  180. if(!dynsymf) free(dynstrdata);
  181.  
  182. return 0;
  183.  
  184. }

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

Saludos!