/** * gcc -Wall -g -o dt_needed dt_needed.c */ #include #include #include #include #include #include #include #include #include int main( int argc, char **argv ) { Elf32_Ehdr hdr; char *strdata = 0; int fd; int i; if( argc < 2 ) { fprintf( stderr, "Usage %s \n", argv[ 0 ] ); return 1; } fd = open( argv[ 1 ], O_RDONLY ); if( fd < 0 ) { fprintf( stderr, "%s: Cannot open %s: %s\n", argv[ 0 ], argv[ 1 ], strerror( errno ) ); return 1; } fprintf( stdout, "Libraries required by %s:\n", argv[ 1 ] ); if( read( fd, &hdr, sizeof( Elf32_Ehdr ) ) < 0 ) { fprintf( stderr, "%s: Cannot read elf header: %s\n", argv[ 0 ], strerror( errno ) ); return 1; } /* Jump to the section header table. */ lseek( fd, hdr.e_shoff, SEEK_SET ); /* Find and load the dynamic symbol strings. */ for( i = 0; i < hdr.e_shnum; i++ ) { Elf32_Shdr shdr; lseek( fd, hdr.e_shoff + (i * hdr.e_shentsize), SEEK_SET ); read( fd, &shdr, sizeof( Elf32_Shdr ) ); if( shdr.sh_type == SHT_DYNSYM ) { Elf32_Shdr symstr; lseek( fd, hdr.e_shoff + (shdr.sh_link * hdr.e_shentsize), SEEK_SET ); read( fd, &symstr, sizeof( Elf32_Shdr ) ); lseek( fd, symstr.sh_offset, SEEK_SET ); strdata = malloc( symstr.sh_size ); read( fd, strdata, symstr.sh_size ); break; } } /* Quit if we couldn't find any. */ if( strdata == 0 ) { fprintf( stderr, "%s: No symbol strings found.\n", argv[ 0 ] ); return 1; } /* Now find the .dynamic section. */ for( i = 0; i < hdr.e_shnum; i++ ) { Elf32_Shdr shdr; lseek( fd, hdr.e_shoff + (i * hdr.e_shentsize), SEEK_SET ); read( fd, &shdr, sizeof( Elf32_Shdr ) ); if( shdr.sh_type == SHT_DYNAMIC ) { int j; /* Load its data and print all DT_NEEDED strings. */ lseek( fd, shdr.sh_offset, SEEK_SET ); for( j = 0; j < shdr.sh_size / sizeof( Elf32_Dyn ); j++ ) { Elf32_Dyn cur; read( fd, &cur, sizeof( Elf32_Dyn ) ); if( cur.d_tag == DT_NEEDED ) { fprintf( stdout, "\t%s\n", strdata + cur.d_un.d_val ); } } } } return 0; }