@ -20,17 +20,17 @@
template < typename ElfHeaderType /*Elf{32,64}_Ehdr*/ ,
template < typename ElfHeaderType /*Elf{32,64}_Ehdr*/ ,
typename ElfSectionHeaderType /*Elf{32,64}_Shdr*/ ,
typename ElfSectionHeaderType /*Elf{32,64}_Shdr*/ ,
typename ElfDynamicSectionEntryType /* Elf{32,64}_Dyn */ >
typename ElfDynamicSectionEntryType /* Elf{32,64}_Dyn */ >
bool process_elf ( uint8_t * bytes , size_t elf_file_size )
bool process_elf ( uint8_t * bytes , size_t elf_file_size , char const * file_name )
{
{
if ( sizeof ( ElfSectionHeaderType ) > elf_file_size ) {
if ( sizeof ( ElfSectionHeaderType ) > elf_file_size ) {
fprintf ( stderr , " ERROR: Elf header would end at %zu but file size only %zu\n " , sizeof ( ElfSectionHeaderType ) , elf_file_size ) ;
fprintf ( stderr , " termux-elf-cleaner: Elf header for '%s' would end at %zu but file size only %zu\n " , file_name , sizeof ( ElfSectionHeaderType ) , elf_file_size ) ;
return false ;
return false ;
}
}
ElfHeaderType * elf_hdr = reinterpret_cast < ElfHeaderType * > ( bytes ) ;
ElfHeaderType * elf_hdr = reinterpret_cast < ElfHeaderType * > ( bytes ) ;
size_t last_section_header_byte = elf_hdr - > e_shoff + sizeof ( ElfSectionHeaderType ) * elf_hdr - > e_shnum ;
size_t last_section_header_byte = elf_hdr - > e_shoff + sizeof ( ElfSectionHeaderType ) * elf_hdr - > e_shnum ;
if ( last_section_header_byte > elf_file_size ) {
if ( last_section_header_byte > elf_file_size ) {
fprintf ( stderr , " ERROR: Section header would end at %zu but file size only %zu\n " , last_section_header_byte , elf_file_size ) ;
fprintf ( stderr , " termux-elf-cleaner: Section header for '%s' would end at %zu but file size only %zu\n " , file_name , last_section_header_byte , elf_file_size ) ;
return false ;
return false ;
}
}
ElfSectionHeaderType * section_header_table = reinterpret_cast < ElfSectionHeaderType * > ( bytes + elf_hdr - > e_shoff ) ;
ElfSectionHeaderType * section_header_table = reinterpret_cast < ElfSectionHeaderType * > ( bytes + elf_hdr - > e_shoff ) ;
@ -40,7 +40,7 @@ bool process_elf(uint8_t* bytes, size_t elf_file_size)
if ( section_header_entry - > sh_type = = SHT_DYNAMIC ) {
if ( section_header_entry - > sh_type = = SHT_DYNAMIC ) {
size_t const last_dynamic_section_byte = section_header_entry - > sh_offset + section_header_entry - > sh_size ;
size_t const last_dynamic_section_byte = section_header_entry - > sh_offset + section_header_entry - > sh_size ;
if ( last_dynamic_section_byte > elf_file_size ) {
if ( last_dynamic_section_byte > elf_file_size ) {
fprintf ( stderr , " ERROR: Dynamic section would end at %zu but file size only %zu\n " , last_dynamic_section_byte , elf_file_size ) ;
fprintf ( stderr , " termux-elf-cleaner: Dynamic section for '%s' would end at %zu but file size only %zu\n " , file_name , last_dynamic_section_byte , elf_file_size ) ;
return false ;
return false ;
}
}
@ -67,7 +67,7 @@ bool process_elf(uint8_t* bytes, size_t elf_file_size)
case DT_RUNPATH : removed_name = " DT_RUNPATH " ; break ;
case DT_RUNPATH : removed_name = " DT_RUNPATH " ; break ;
}
}
if ( removed_name ! = nullptr ) {
if ( removed_name ! = nullptr ) {
printf ( " Removing the %s dynamic section entry \n " , removed_name ) ;
printf ( " termux-elf-cleaner: Removing the %s dynamic section entry from '%s' \n " , removed_name , file _name ) ;
// Tag the entry with DT_NULL and put it last:
// Tag the entry with DT_NULL and put it last:
dynamic_section_entry - > d_tag = DT_NULL ;
dynamic_section_entry - > d_tag = DT_NULL ;
// Decrease j to process new entry index:
// Decrease j to process new entry index:
@ -80,7 +80,7 @@ bool process_elf(uint8_t* bytes, size_t elf_file_size)
}
}
int main ( int argc , char * * argv )
int main ( int argc , char const * * argv )
{
{
if ( argc < 2 | | ( argc = = 2 & & strcmp ( argv [ 1 ] , " -h " ) = = 0 ) ) {
if ( argc < 2 | | ( argc = = 2 & & strcmp ( argv [ 1 ] , " -h " ) = = 0 ) ) {
fprintf ( stderr , " usage: %s <filename> \n " , argv [ 0 ] ) ;
fprintf ( stderr , " usage: %s <filename> \n " , argv [ 0 ] ) ;
@ -90,7 +90,8 @@ int main(int argc, char **argv)
}
}
for ( int i = 1 ; i < argc ; i + + ) {
for ( int i = 1 ; i < argc ; i + + ) {
int fd = open ( argv [ i ] , O_RDWR ) ;
char const * file_name = argv [ i ] ;
int fd = open ( file_name , O_RDWR ) ;
if ( fd < 0 ) { perror ( " open() " ) ; return 1 ; }
if ( fd < 0 ) { perror ( " open() " ) ; return 1 ; }
struct stat st ;
struct stat st ;
@ -103,19 +104,25 @@ int main(int argc, char **argv)
uint8_t * bytes = reinterpret_cast < uint8_t * > ( mem ) ;
uint8_t * bytes = reinterpret_cast < uint8_t * > ( mem ) ;
if ( ! ( bytes [ 0 ] = = 0x7F & & bytes [ 1 ] = = ' E ' & & bytes [ 2 ] = = ' L ' & & bytes [ 3 ] = = ' F ' ) ) {
if ( ! ( bytes [ 0 ] = = 0x7F & & bytes [ 1 ] = = ' E ' & & bytes [ 2 ] = = ' L ' & & bytes [ 3 ] = = ' F ' ) ) {
// Not the ELF magic number.
munmap ( mem , st . st_size ) ;
munmap ( mem , st . st_size ) ;
close ( fd ) ;
close ( fd ) ;
continue ;
continue ;
}
}
uint8_t bit_value = bytes [ 4 ] ;
if ( bytes [ /*EI_DATA*/ 5 ] ! = 1 ) {
if ( ! ( bit_value = = 1 | | bit_value = = 2 ) ) {
fprintf ( stderr , " termux-elf-cleaner: Not little endianness in '%s' \n " , file_name ) ;
printf ( " ERROR: Incorrect bit value: %d \n " , bit_value ) ;
continue ;
return 1 ;
}
} else if ( bit_value = = 1 ) {
if ( ! process_elf < Elf32_Ehdr , Elf32_Shdr , Elf32_Dyn > ( bytes , st . st_size ) ) return 1 ;
uint8_t const bit_value = bytes [ /*EI_CLASS*/ 4 ] ;
if ( bit_value = = 1 ) {
if ( ! process_elf < Elf32_Ehdr , Elf32_Shdr , Elf32_Dyn > ( bytes , st . st_size , file_name ) ) return 1 ;
} else if ( bit_value = = 2 ) {
if ( ! process_elf < Elf64_Ehdr , Elf64_Shdr , Elf64_Dyn > ( bytes , st . st_size , file_name ) ) return 1 ;
} else {
} else {
if ( ! process_elf < Elf64_Ehdr , Elf64_Shdr , Elf64_Dyn > ( bytes , st . st_size ) ) return 1 ;
printf ( " termux-elf-cleaner: Incorrect bit value %d in '%s' \n " , bit_value , file_name ) ;
return 1 ;
}
}
if ( msync ( mem , st . st_size , MS_SYNC ) < 0 ) { perror ( " msync() " ) ; return 1 ; }
if ( msync ( mem , st . st_size , MS_SYNC ) < 0 ) { perror ( " msync() " ) ; return 1 ; }