Repository 32bit  Forum
Repository 64bit  Wiki

[C] Elf linked libraries [RISOLTO]

Forum dedicato alla programmazione.

Moderatore: Staff

Regole del forum
1) Citare in modo preciso il linguaggio di programmazione usato.
2) Se possibile portare un esempio del risultato atteso.
3) Leggere attentamente le risposte ricevute.
4) Scrivere i messaggi con il colore di default, evitare altri colori.
5) Scrivere in Italiano o in Inglese, se possibile grammaticalmente corretto, evitate stili di scrittura poco chiari, quindi nessuna abbreviazione tipo telegramma o scrittura stile SMS o CHAT.
6) Appena registrati è consigliato presentarsi nel forum dedicato.

La non osservanza delle regole porta a provvedimenti di vari tipo da parte dello staff, in particolare la non osservanza della regola 5 porta alla cancellazione del post e alla segnalazione dell'utente. In caso di recidività l'utente rischia il ban temporaneo.

[C] Elf linked libraries [RISOLTO]

Messaggioda Dani » dom mar 23, 2008 2:09

Partendo dal path di un file è possibile riconoscere se il file stesso è un binario che usa librerie condivise o se è altro, senza ricorrere a programmi esterni ?
Devo costruirmi una funzione che abbia un comportamento simile:

- ottenimento del percorso dai parametri (es: f ("/bin/bash") )
- verifica dell'esistenza del file
- se il file esiste, verifica del tipo di file; se non è un binario che usa librerie condivise ritorna
- lettura librerie linkate

Il problema nasce dal terzo punto in poi, non so come riconoscere il tipo di file o come controllare eventuali librerie condivise.

Suggerimenti ? :roll:
Ultima modifica di Dani il sab apr 05, 2008 5:57, modificato 1 volta in totale.
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] Distinzione files

Messaggioda Toni » dom mar 23, 2008 2:24

ogni file in linux comincia con un magic number , con il quale si identifica il tipo di file ( a differenza dei sistemi microsoft che usa le estensioni dei nomi)
Avatar utente
Toni
Linux 2.6
Linux 2.6
 
Messaggi: 993
Iscritto il: lun gen 30, 2006 22:08
Località: milano
Slackware: slackware-14
Kernel: 3.10.5
Desktop: i3

Re: [C] Distinzione files

Messaggioda umaga » dom mar 23, 2008 6:29

se non ricordo male il comando "file" da informazioni dettagliate su tipo di file... potresti prendere informazioni da li...


ciao
Avatar utente
umaga
Packager
Packager
 
Messaggi: 179
Iscritto il: lun gen 30, 2006 10:19
Località: Cagliari
Slackware: 13.37
Kernel: 2.6.38.4-smp
Desktop: KDE 4.7

Re: [C] Distinzione files

Messaggioda 414N » dom mar 23, 2008 10:15

man libmagic
Avatar utente
414N
Iper Master
Iper Master
 
Messaggi: 2882
Iscritto il: mer feb 13, 2008 16:19
Località: Bulagna
Slackware: 14.0 (x64)
Kernel: 3.2.29
Desktop: LXDE

Re: [C] Distinzione files

Messaggioda Mario Vanoni » dom mar 23, 2008 15:14

Dani ha scritto:- ottenimento del percorso dai parametri (es: f ("/bin/bash") )
- verifica dell'esistenza del file
- se il file esiste, verifica del tipo di file; se non è un binario che usa librerie condivise ritorna
- lettura librerie linkate


1) usando popen(3)
2) usando access(2), ATTENTO: non funziona con files montati via NFS! man 2 access
3) impossibile, e.g. se compilato con make -O2 -s -static (mio standard)
4) illusione se 3) vero, se 3) falso ignoro, se shell script non importa
Mario Vanoni
Iper Master
Iper Master
 
Messaggi: 3174
Iscritto il: lun set 03, 2007 20:20
Località: Cuasso al Monte (VA)
Nome Cognome: Mario Vanoni
Slackware: 12.2
Kernel: 3.0.4 statico
Desktop: fluxbox/seamonkey

Re: [C] Distinzione files

Messaggioda Dani » mar mar 25, 2008 0:59

Non ho intenzione di usare comandi esterni, quindi non mi puo' tornare utile nè il comando file, nè la funzione popen().
Per risolvere il terzo punto devo leggere questo magic number, che tra l'altro nemmeno conoscevo :oops:
Ho fatto una prova al volo ed il tipo di file che cerco sembra avere sempre il primo byte uguale a 0x457F, non so se sia il magic number o meno, ma sta di fatto che tutti i binari che usano librerie condivise iniziano con quel valore.

Esempio:

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

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

FILE* fd;
#define size 255
int i;
unsigned short magic;
char buffer[size + 1] = { 0 };

if (argc < 2) return EXIT_FAILURE;

for (i = 1; i <= argc; i++)
{
   if (!(fd = fopen (argv[i], "rb"))) return EXIT_FAILURE;
   
   fread ((unsigned short*)&magic, sizeof (unsigned short), 1, fd);
   
//   printf ("Magic of %s: 0x%X\n", argv[i], magic);

   if (magic != 0x457F)
   {
      memset (buffer, 0, size);
      snprintf (buffer, size, "ldd %s", argv[i]);
      system (buffer);
   }

   fclose (fd);

}
return EXIT_SUCCESS;
}



Sui files che hanno il primo byte diverso da 0x457F lancio ldd, ed infatti da shell:

Codice: Seleziona tutto
bt ~ # for i in $(ls /usr/bin); do ./a.out /usr/bin/$i; done
       not a dynamic executable
        not a dynamic executable
        not a dynamic executable
        not a dynamic executable
        not a dynamic executable
        not a dynamic executable
        not a dynamic executable
[...]


Prima di passare all'ultimo punto, ovvero alla lettura delle librerie linkate dinamicamente, mi serve una conferma.
Quello che leggo è il magic number ? E' univoco ?

[edit] Piccola precisazione: il codice di sopra va a leggere piu' di un byte, se leggo un solo byte ottengo 0xBF7F.
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] Distinzione files

Messaggioda absinthe » mar mar 25, 2008 9:04

prova a leggere /etc/file/magic. è immenso greppa le informazioni su ELF. io non ci chiappo nienete ma lì dentro c'è la collezione di tutti i magic usati da file per capire di che tipo di file si tratta. forse anche un occhiata al codice di file potrebbe aiutare.

M
Avatar utente
absinthe
Iper Master
Iper Master
 
Messaggi: 2354
Iscritto il: sab mag 14, 2005 23:00
Località: Prato
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze

Re: [C] Distinzione files

Messaggioda Dani » mer mar 26, 2008 1:31

absinthe ha scritto:io non ci chiappo nienete


Capisco, sfido chiunque a chiapparci qualcosa in quel file ! :lol:
Fortunatamente ho trovato questa ottima spiegazione, ora so riconoscere il file ELF dal resto del mondo, e ho capito come distinguare l'ELF eseguibile dall'ELF resto del mondo :D

Dunque possiamo passare all'ultimo punto, cioè alla lettura delle librerie collegate all'eseguibile. Any hints ? #-o
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] Distinzione files

Messaggioda absinthe » mer mar 26, 2008 8:55

ma... di fatto te vuoi integrare un subset delle opzioni di readelf! scrutare il codicillo per controllare gli include potrebbe essere un'idea!

M
Avatar utente
absinthe
Iper Master
Iper Master
 
Messaggi: 2354
Iscritto il: sab mag 14, 2005 23:00
Località: Prato
Nome Cognome: Matteo Nunziati
Slackware: 12.1 - defunct
Kernel: 2.6.32-5-amd64
Desktop: gnome
Distribuzione: debian squeeze

Re: [C] Distinzione files

Messaggioda afterjames » mar apr 01, 2008 19:42

Se la distinzione fosse semplicemente sul tipo di file(regolare,directory, device file, sym link ..) basterebbe una semplice :


Codice: Seleziona tutto
int lstat(const char *restrict path, struct stat *restrict buf);



Tra l'altro il comando "File" la utilizza.Se è un file oggetto o un eseguibile in genere questi sono in formato elf, quindi usi una readelf.
afterjames
Linux 1.0
Linux 1.0
 
Messaggi: 64
Iscritto il: lun gen 14, 2008 14:14

Re: [C] Distinzione files

Messaggioda Dani » mer apr 02, 2008 3:46

Il problema della distinzione dei files l'ho risolto, a me interessava solo sapere se il file x era un elf.
Ora sono bloccato alla lettura delle librerie collegate ad esso. Ho provato a guardare il codice di readelf delle binutils, ma non si capisce niente.
Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch

Re: [C] Distinzione files

Messaggioda Dani » sab apr 05, 2008 5:56

Risolto !

Sorgentino dimostrativo :)

Codice: Seleziona tutto
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <elf.h>

#define ERR(s) {perror (s); exit (1);}

void print_hex (Elf32_Ehdr h, unsigned len, char* messaggio)
{
 int i;
 
 printf ("%s[", messaggio);
 
 for (i = 0; i < len; i++)
  printf ("%c", (unsigned char) h.e_ident[i]);
 
 printf ("] ");
 
 
 for (i = 0; i < len - 1; i++)
  printf ("%.2X ", (unsigned char) h.e_ident[i]);
 
 printf ("%.2X\n", h.e_ident[i]);
 
 return;
}

void print_ehdr (Elf32_Ehdr E)
{
   printf ("+----------\n| Elf32_Ehdr\n+----------\n");
   
   print_hex (E, sizeof E.e_ident,
            "E.e_ident:      ");
   printf ("E.e_type:       %.2X\n", E.e_type);
    printf ("E.e_machine:    %.2X\n", E.e_machine);
    printf ("E.e_version:    %.2X\n", E.e_version);
    printf ("E.e_entry:      0x%.8X\n", E.e_entry);
    printf ("E.e_phoff:      0x%.8X\n", E.e_phoff);
    printf ("E.e_shoff:      0x%.8X\n", E.e_shoff);
    printf ("E.e_flags:      %.2X\n", E.e_flags);
    printf ("E.e_ehsize:     %.2X\n", E.e_ehsize);
    printf ("E.e_phentsize:  %.2X\n", E.e_phentsize);
    printf ("E.e_phnum:      %.2X\n", E.e_phnum);
    printf ("E.e_shentsize:  %.2X\n", E.e_shentsize);
    printf ("E.e_shnum:      %.2X\n", E.e_shnum);
    printf ("E.e_shstrndx:   %.2X\n", E.e_shstrndx);
}

void print_phdr (Elf32_Phdr P, unsigned entry)
{
   printf ("\n+----------\n| Elf32_Phdr [%uth entry]\n+----------\n", entry);
   
   printf ("P.p_type :   %.2X %s\n", P.p_type, (P.p_type == PT_DYNAMIC) ? "[DYNAMIC SECTION]" : "");
   printf ("P.p_offset:  0x%.8X\n", P.p_offset);
   printf ("P.p_vaddr:   0x%.8X\n", P.p_vaddr);
   printf ("P.p_paddr:   0x%.8X\n", P.p_paddr);
   printf ("P.p_filesz:  %.2X\n", P.p_filesz);
   printf ("P.p_memsz:   %.2X\n", P.p_memsz);
   printf ("P.p_flags:   %.2X\n", P.p_flags);
   printf ("P.p_align:   %.2X\n", P.p_align);
}
   
   
void print_shdr (Elf32_Shdr S, unsigned entry)
{
   printf ("\n+----------\n| Elf32_Shdr [%uth entry]\n+----------\n", entry);
   
   printf ("S.sh_name:       %.2X\n", S.sh_name);
    printf ("S.sh_type:       %.2X %s\n", S.sh_type, (S.sh_type == SHT_DYNAMIC) ? "[DYNAMIC SECTION]" : "");
    printf ("S.sh_flags:      %.2X\n", S.sh_flags);
    printf ("S.sh_addr:       0x%.8X\n", S.sh_addr);
    printf ("S.sh_offset:     0x%.8X\n", S.sh_offset);
    printf ("S.sh_size:       0x%.8X\n", S.sh_size);
    printf ("S.sh_link:       0x%.2X\n", S.sh_link);
    printf ("S.sh_info:       %.2X\n", S.sh_info);
    printf ("S.sh_addralign:  %.2X\n", S.sh_addralign);
    printf ("S.sh_entsize:    %.2X\n", S.sh_entsize);
    
}

char* get_str (FILE* fd, unsigned long offset)
{
   char c, *s = NULL;
   int i;
   
   if (fseek (fd, offset, SEEK_SET))
    ERR ("Cannot seek file");
   
   while (1)
   {
      if (fread ((char*)&c, 1, 1, fd) != 1)
       ERR ("Cannot read from file");
      
      if (!c)
       break;
      
      i++;
      putchar (c);
   }
   
   
   return s;
}
      
   

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

FILE* fd;
unsigned char c;
int rval = 0, i, j, n, p_dynamic_index, s_dynamic_index;
unsigned long set;
char *data = NULL;
Elf32_Ehdr E;
Elf32_Phdr *P;
Elf32_Shdr *S;
Elf32_Dyn  *D;

char *str = NULL;

if (argc < 2 || !(fd = fopen (argv[1], "rb")))
 return EXIT_FAILURE;

 
 if (fread ((Elf32_Ehdr*)&E, sizeof (Elf32_Ehdr), 1, fd) != 1)
  ERR ("Unable to read elf header");
 print_ehdr (E);
 
 
 
 printf ("\nFound %d entries in program header:", E.e_phnum);
 if (fseek (fd, E.e_phoff, SEEK_SET))
  ERR ("Unable to seek file");
 P = (Elf32_Phdr*) malloc (E.e_phnum * sizeof (Elf32_Phdr));
 for (i = 0; i < E.e_phnum - 1; i++)
 {
    if (fread ((Elf32_Phdr*)&P[i], E.e_phentsize, 1, fd) != 1)
      ERR ("Cannot read program section header");
    
    
    if (P[i].p_type == PT_DYNAMIC)
    {
       print_phdr (P[i], i);
       p_dynamic_index = i;
   }
    
 }
 
 printf ("\nFound %d entries in section header:", E.e_shnum);
 if (fseek (fd, E.e_shoff, SEEK_SET))
  ERR ("Unable to seek file");
 S = (Elf32_Shdr*) malloc (E.e_shnum * sizeof (Elf32_Shdr));
 for (i = 0; i < E.e_shnum - 1; i++)
 {
    if (fread ((Elf32_Shdr*)&S[i], E.e_shentsize, 1, fd) != 1)
      ERR ("Cannot read program section header");
    
    if (S[i].sh_type == SHT_DYNAMIC)
    {
       print_shdr (S[i], i);
       s_dynamic_index = i;
       
       if (S[i].sh_link)
        print_shdr (*(S + S[i].sh_link), S[i].sh_link);
   }
    
 }
 

 n = S[s_dynamic_index].sh_size / S[s_dynamic_index].sh_entsize;

 puts ("\n------------\n");
 if (fseek (fd, P[p_dynamic_index].p_offset, SEEK_SET))
  ERR ("Unable to seek file");
 D = (Elf32_Dyn*) malloc (E.e_shnum * sizeof (Elf32_Dyn));
 for (i = 0; i < n; i++)
 {
    if (fread ((Elf32_Dyn*)&D[i], sizeof (Elf32_Dyn), 1, fd) != 1)
      ERR ("Unable to read dynamyc section");
    if (D[i].d_tag == DT_NEEDED)
    {
       printf ("[D.d_tag: DT_NEEDED] d_val: 0x%.8X\n", D[i].d_un.d_val);
    }
 }

 puts ("\n------------\n");
 
 for (i = 0; i < n; i++)
 {
    if (D[i].d_tag != DT_NEEDED)
     continue;
    
    set = S[S[s_dynamic_index].sh_link].sh_offset + D[i].d_un.d_val;
    str = get_str (fd, set);
   
    putchar ('\n');
 }
 
 
 fclose (fd);
 putchar ('\n');
 return EXIT_SUCCESS;
}

Dani
Linux 3.x
Linux 3.x
 
Messaggi: 1447
Iscritto il: mer apr 26, 2006 0:52
Desktop: gnome
Distribuzione: arch


Torna a Programmazione

Chi c’è in linea

Visitano il forum: Bing [Bot] e 1 ospite