[C] Elf linked libraries [RISOLTO]
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.
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]
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 ?
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 ?
Ultima modifica di Dani il sab 5 apr 2008, 6:57, modificato 1 volta in totale.
- Toni
- Linux 3.x
- Messaggi: 999
- Iscritto il: lun 30 gen 2006, 22:08
- Slackware: slackware-14
- Kernel: 3.10.5
- Desktop: i3
- Località: milano
Re: [C] Distinzione files
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)
- umaga
- Packager
- Messaggi: 180
- Iscritto il: lun 30 gen 2006, 10:19
- Slackware: 13.37
- Kernel: 2.6.38.4-smp
- Desktop: KDE 4.7
- Località: Cagliari
Re: [C] Distinzione files
se non ricordo male il comando "file" da informazioni dettagliate su tipo di file... potresti prendere informazioni da li...
ciao
ciao
- 414N
- Iper Master
- Messaggi: 2922
- Iscritto il: mer 13 feb 2008, 16:19
- Slackware: 15.0
- Kernel: 5.15.19
- Desktop: KDE5
- Località: Bulagna
- Contatta:
Re: [C] Distinzione files
man libmagic
-
- Iper Master
- Messaggi: 3174
- Iscritto il: lun 3 set 2007, 21:20
- Nome Cognome: Mario Vanoni
- Slackware: 12.2
- Kernel: 3.0.4 statico
- Desktop: fluxbox/seamonkey
- Località: Cuasso al Monte (VA)
Re: [C] Distinzione files
1) usando popen(3)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
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
Re: [C] Distinzione files
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
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:
Sui files che hanno il primo byte diverso da 0x457F lancio ldd, ed infatti da shell:
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.
Per risolvere il terzo punto devo leggere questo magic number, che tra l'altro nemmeno conoscevo
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;
}
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
[...]
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.
- absinthe
- Iper Master
- Messaggi: 2354
- Iscritto il: dom 15 mag 2005, 0:00
- Nome Cognome: Matteo Nunziati
- Slackware: 12.1 - defunct
- Kernel: 2.6.32-5-amd64
- Desktop: gnome
- Distribuzione: debian squeeze
- Località: Prato
- Contatta:
Re: [C] Distinzione files
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
M
Re: [C] Distinzione files
Capisco, sfido chiunque a chiapparci qualcosa in quel file !absinthe ha scritto:io non ci chiappo nienete
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
Dunque possiamo passare all'ultimo punto, cioè alla lettura delle librerie collegate all'eseguibile. Any hints ?
- absinthe
- Iper Master
- Messaggi: 2354
- Iscritto il: dom 15 mag 2005, 0:00
- Nome Cognome: Matteo Nunziati
- Slackware: 12.1 - defunct
- Kernel: 2.6.32-5-amd64
- Desktop: gnome
- Distribuzione: debian squeeze
- Località: Prato
- Contatta:
Re: [C] Distinzione files
ma... di fatto te vuoi integrare un subset delle opzioni di readelf! scrutare il codicillo per controllare gli include potrebbe essere un'idea!
M
M
-
- Linux 0.x
- Messaggi: 64
- Iscritto il: lun 14 gen 2008, 14:14
Re: [C] Distinzione files
Se la distinzione fosse semplicemente sul tipo di file(regolare,directory, device file, sym link ..) basterebbe una semplice :
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.
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.
Re: [C] Distinzione files
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.
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.
Re: [C] Distinzione files
Risolto !
Sorgentino dimostrativo
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;
}