2011-02-28 10 views
8

En mi programa C++, ¿cómo puedo detectar mediante programación en el tiempo de ejecución si los símbolos se han eliminado a través de la herramienta de desarrollo 'strip' gnu en Linux?¿Cómo detectar en tiempo de ejecución si los símbolos se eliminan?

Me gustaría obtener una definición de función que devuelva verdadero si se elimina, de lo contrario será falso.

¿Usaría dlsym() en el trabajo "main()" para detectar esto de manera confiable?

+0

¿Por qué quiere detectar esto en tiempo de ejecución? –

+0

No tengo claro por qué necesita saber si el ejecutable se ha eliminado. Pero lo que sea que esté usando para procesar el ejecutable en tiempo de ejecución también debería poder decirle si las cosas se han eliminado. –

+0

@Martin York Para activar un mensaje de alerta cuando se ejecuta la aplicación para reducir la posibilidad de que una versión no eliminada se entregue inadvertidamente a un cliente. – WilliamKF

Respuesta

7

Sé que el comando file puede notar la diferencia, por lo que podría ver su origen para ver qué mecanismo utiliza.

+5

Un Strip [ELF] (http://en.wikipedia.org/wiki/Executable_and_Linkable_Format) carecerá de una entrada '.symtab'. El comando 'file' atraviesa todos los encabezados de sección de ELF hasta que se encuentre una sección de tabla de símbolos. Si no se puede encontrar uno, el binario se considera * despojado *. – jschmier

2

dlsym mira dinámicas símbolos, los cuales no son tocados por tira. La tabla de símbolos estáticos está contenida en secciones que no están cargadas en tiempo de ejecución y, por lo tanto, no aparecen en la tabla de segmentos.

Una heurística bastante buena sería observar la existencia de una tabla de sección en el encabezado ELF, que generalmente se asigna a la memoria de proceso, aunque las interfaces dinámicas del enlazador dificultan deliberadamente averiguar dónde. En un sistema típico que tiene la función dl_iterate_phdrs (que es una extensión del estándar), es posible que pueda recorrer el PHDRS y verificar en el vaddr para cada uno si hay un número mágico ELF allí, pero eso no es de ninguna manera, forma o forma portátil.

1

Usted podría utilizar popen() para ejecutarnm en la aplicación de destino y luego parse the output para averiguar si es despojado o no.

nm: /bin/ls: no symbols 
7

Desde un comentario dejado por another answer:

Un despojado ELF carecerá de una entrada .symtab. El comando file atraviesa todos los encabezados de sección de ELF hasta que se encuentra una sección de tabla de símbolos. Si no se puede encontrar uno, el binario se considera despojado.


El libelf biblioteca permite que un programa para manipular archivos ELF objeto, ficheros de datos, los miembros del archivo. Las páginas del manual elf(3E) proporcionan documentación relacionada con el uso de la biblioteca. El siguiente código proporciona un ejemplo para determinar si el ejecutable se elimina buscando la existencia de una sección de tabla de símbolos (.symtab).

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <fcntl.h> 

/* Include for ELF processing */ 
#include <libelf.h> 
#include <gelf.h> 

int main(int argc, char ** argv) 
{ 
    int fd; 
    const char *file = argv[0]; 

    Elf *elf;  /* ELF pointer for libelf */ 
    Elf_Scn *scn; /* section descriptor pointer */ 
    GElf_Shdr shdr; /* section header */ 

    /* Open ELF file to obtain file descriptor */ 
    if((fd = open(file, O_RDONLY)) < 0) 
    { 
     fprintf(stderr, "Error opening file %s\n", file); 
     exit(EXIT_FAILURE); 
    } 

    /* Protect program from using an older library */ 
    if(elf_version(EV_CURRENT) == EV_NONE) 
    { 
     fprintf(stderr, "WARNING - ELF Library is out of date!\n"); 
     exit(EXIT_FAILURE); 
    } 

    /* Initialize elf pointer for examining contents of file */ 
    elf = elf_begin(fd, ELF_C_READ, NULL); 

    /* Initialize section descriptor pointer so that elf_nextscn() 
    * returns a pointer to the section descriptor at index 1. */ 
    scn = NULL; 

    /* Iterate through ELF sections */ 
    while((scn = elf_nextscn(elf, scn)) != NULL) 
    { 
     /* Retrieve section header */ 
     gelf_getshdr(scn, &shdr); 

     /* If a section header holding a symbol table (.symtab) 
     * is found, this ELF file has not been stripped. */ 
     if(shdr.sh_type == SHT_SYMTAB) 
     { 
      printf("NOT STRIPPED\n"); 
      break; 
     } 
    } 

    elf_end(elf); 
    close(fd); 
    exit(EXIT_SUCCESS); 
} 
1

readelf --sections binary_path | grep debug_info

No es trivial decir en general si un archivo binario se eliminó o no, porque hay diferentes maneras de quitar un archivo. Esencialmente stripping elimina algunas secciones relacionadas con símbolos y depuración. Sin embargo, si reemplaza "debug_info" por "debug", puede ver que todavía quedan algunas secciones relacionadas con la depuración en los binarios estándar de la distribución de Ubuntu.

Cuestiones relacionadas