From 5b3181093cd9ff49bbc5de1fc232551b9e10f9fd Mon Sep 17 00:00:00 2001 From: "Koine Yuusuke(koinec)" Date: Sun, 31 Mar 2019 20:16:56 +0900 Subject: [PATCH] 2019/03/31(Sun) 20:17 (LibGoblin) * WorkBackup --- libgoblin/drd64_libgoblin_elf_dynsym.c | 15 ++++- libgoblin/drd64_libgoblin_elf_rela.c | 99 +++++++++++++++++++++++++++++++++ libgoblin/drd64_libgoblin_elf_rela.h | 2 + libgoblin/drd64_libgoblin_elf_section.c | 2 + libgoblin/drd64_libgoblin_elf_symtab.c | 14 ++++- libgoblin/drd64_libgoblin_elf_symtab.h | 2 +- libgoblin/drd64_libgoblin_section.c | 2 + libgoblin/drd64_libgoblin_type.h | 1 + 8 files changed, 130 insertions(+), 7 deletions(-) diff --git a/libgoblin/drd64_libgoblin_elf_dynsym.c b/libgoblin/drd64_libgoblin_elf_dynsym.c index 0738996..d06ae9f 100644 --- a/libgoblin/drd64_libgoblin_elf_dynsym.c +++ b/libgoblin/drd64_libgoblin_elf_dynsym.c @@ -60,6 +60,7 @@ int Word *pw_gnuver = NULL; Elf64_Shdr *p_shdr; Elf64_Sym *p_sym; + PtrValue ptr_addr; GnuVer_VerNeed *p_verneed; GnuVer_VerNeed *p_vernow; LibGoblin_SectionInfo *psec_gnuver = NULL; @@ -162,11 +163,19 @@ int if( 0 > i_symindex ) { continue; } - p_obj = ObjectInfo_SearchDynamicSymbol( - p_pginfo, ((PtrValue)p_sym->st_value + p_binfo->ptr_loadbase), pstr_symname ); + // If dynsym addr = 0x00000000, Search PLT addr. from .got addr. --- +//XXX + ptr_addr = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname ); + if( 0x00000000 == p_sym->st_value ) + { ptr_addr = ELF64_Rela_GetPLTaddr_fromGOT( p_binfo, pstr_symname ); } + else + { ptr_addr = (PtrValue)p_sym->st_value + p_binfo->ptr_loadbase; } + + p_obj = ObjectInfo_SearchDynamicSymbol( p_pginfo, ptr_addr, pstr_symname ); // If the target program is stripped, p_obj = NULL because don't exist .symtab section. if( NULL == p_obj ) { - p_obj = ELF64_Symtab_RegistSymbol_toObjectInfo( p_pginfo, p_binfo, p_sym, pb_dynstr ); + p_obj = ELF64_Symtab_RegistSymbol_toObjectInfo( + p_pginfo, p_binfo, ptr_addr, p_sym, pb_dynstr ); } if( NULL != p_obj ) { diff --git a/libgoblin/drd64_libgoblin_elf_rela.c b/libgoblin/drd64_libgoblin_elf_rela.c index 9b162f4..a4c20e3 100644 --- a/libgoblin/drd64_libgoblin_elf_rela.c +++ b/libgoblin/drd64_libgoblin_elf_rela.c @@ -40,6 +40,105 @@ Comment: /*---------------------------------------------------------------------- ----------------------------------------------------------------------*/ +LIBGOBLIN_ELF_RELA_EXTERN +PtrValue + ELF64_Rela_GetPLTaddr_fromGOT( + LibGoblin_BinaryInfo *p_binfo, + char *pstr_symname ) +{ + Byte *pb_dynstr; + Byte *pb_gotplt; + char *pstr_temp; + DWord dw_cnt; + DWord dw_maxrels; + DWord dw_symbol; + QWord qw_temp; + QWord qw_entsize; + PtrValue ptr_ret = 0x00000000; + PtrValue *pptr_pltaddr; + Elf64_Sym *pelf_sym; + Elf64_Rela *pelf_rela; + LibGoblin_SectionInfo *psec_rela; + LibGoblin_SectionInfo *psec_plt; + LibGoblin_SectionInfo *psec_gotplt; + LibGoblin_SectionInfo *psec_dynstr; + LibGoblin_SectionInfo *psec_dynsym; + LibGoblin_BinaryFile *p_bfile; + + // -------------- + p_bfile = BinaryFile_GetBinaryFile( p_binfo->i_binfile ); + assert( NULL != p_bfile ); + + // -------------- + psec_rela = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_RELA_PLT ); + if( NULL == psec_rela ) { + return ptr_ret; + } + if( NULL == psec_rela->pb_data ) { + return ptr_ret; + } + pelf_rela = (Elf64_Rela *)psec_rela->pb_data; + dw_maxrels = (DWord)psec_rela->qw_size / sizeof( Elf64_Rela ); + + // -------------- + psec_dynsym = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM ); + if( NULL == psec_dynsym ) { return 0x00; } + if( NULL == psec_dynsym->pb_data ) { return 0x00; } + + // -------------- + psec_dynstr = Section_GetSectionInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR ); + if( NULL == psec_dynstr ) { return 0x00; } + if( NULL == psec_dynstr->pb_data ) { + return -0x01; + } + pb_dynstr = psec_dynstr->pb_data; + + // -------------- + psec_gotplt = Section_GetSectionInfo_fromBinaryFile( p_bfile, LIBGOBLIN_SECTION_ID_GOT_PLT ); + if( NULL == psec_gotplt ) { return 0x00; } + if( NULL == psec_gotplt->pb_data ) { + return -0x01; + } + pb_gotplt = psec_gotplt->pb_data; + + // -------------- + psec_plt = Section_GetSectionInfo_fromBinaryFile( p_bfile, LIBGOBLIN_SECTION_ID_PLT ); + if( NULL == psec_plt ) { return 0x00; } +printf(" debug: %s\n", pstr_symname ); + + if( 0 == psec_plt->qw_entsize ) + { return 0x00; } + +printf(" debug plt entsize = %lx %lx %lx %d\n", qw_entsize, psec_plt->qw_entsize, psec_plt->qw_size, dw_maxrels ); + + for( dw_cnt = 0; dw_cnt < dw_maxrels; dw_cnt++, pelf_rela++ ) { + // r_info - Relocation type and symbol index. + dw_symbol = ELF64_R_SYM( pelf_rela->r_info ); + if( 2 > dw_symbol ) { continue; } + + pelf_sym = ((Elf64_Sym *)psec_dynsym->pb_data + dw_symbol); + + pstr_temp = (char *)pb_dynstr + pelf_sym->st_name; + if( !strncmp( pstr_symname, pstr_temp, 60 ) ) { + if(( 0x00000000 == pelf_rela->r_offset ) + || (pelf_rela->r_offset < psec_gotplt->ptr_addr.value )) + { goto goto_ELF64_Rela_GetPLTaddr_fromGOT; } + + qw_temp = (QWord)pelf_rela->r_offset - (QWord)psec_gotplt->ptr_addr.value; + pptr_pltaddr = (PtrValue *)(psec_gotplt->pb_data + qw_temp); + ptr_ret = (PtrValue)(*pptr_pltaddr - (*pptr_pltaddr % psec_plt->qw_entsize)); +printf(" debug plt addr = %lx %lx\n", *pptr_pltaddr, ptr_ret ); + break; + } + } + +goto_ELF64_Rela_GetPLTaddr_fromGOT: + return ptr_ret; +} + + +/*---------------------------------------------------------------------- +----------------------------------------------------------------------*/ int ELF64_Rela_ReadIndicateSection_Rela( LibGoblin_BinaryInfo *p_binfo, diff --git a/libgoblin/drd64_libgoblin_elf_rela.h b/libgoblin/drd64_libgoblin_elf_rela.h index 0f2f028..6b19e9c 100644 --- a/libgoblin/drd64_libgoblin_elf_rela.h +++ b/libgoblin/drd64_libgoblin_elf_rela.h @@ -46,6 +46,8 @@ Comment: #endif LIBGOBLIN_ELF_RELA_EXTERN + PtrValue ELF64_Rela_GetPLTaddr_fromGOT( LibGoblin_BinaryInfo *p_binfo, char *pstr_symname ); +LIBGOBLIN_ELF_RELA_EXTERN int ELF64_Rela_ReadSection( LibGoblin_BinaryInfo *p_binfo ); #ifdef DRD64_SRC_LIBGOBLIN_ELF_RELA diff --git a/libgoblin/drd64_libgoblin_elf_section.c b/libgoblin/drd64_libgoblin_elf_section.c index 80a8f68..ae36cad 100644 --- a/libgoblin/drd64_libgoblin_elf_section.c +++ b/libgoblin/drd64_libgoblin_elf_section.c @@ -101,6 +101,7 @@ int p_sectbl->i_binfile = p_binfo->i_binfile; p_sectbl->w_index = (Word)i_cnt; p_sectbl->qw_flag = p_sechdr->sh_flags; + p_sectbl->qw_entsize = p_sechdr->sh_entsize; p_bfile->i_secindex[ i_cnt ] = i_index; break; @@ -122,6 +123,7 @@ int p_sectbl->i_binfile = p_binfo->i_binfile; p_sectbl->w_index = (Word)i_cnt; p_sectbl->qw_flag = p_sechdr->sh_flags; + p_sectbl->qw_entsize = p_sechdr->sh_entsize; p_bfile->i_secindex[ i_cnt ] = i_user_section; diff --git a/libgoblin/drd64_libgoblin_elf_symtab.c b/libgoblin/drd64_libgoblin_elf_symtab.c index 9c32be6..a3ed12e 100644 --- a/libgoblin/drd64_libgoblin_elf_symtab.c +++ b/libgoblin/drd64_libgoblin_elf_symtab.c @@ -45,6 +45,7 @@ LibGoblin_ObjectInfo * ELF64_Symtab_RegistSymbol_toObjectInfo( LibGoblin_ProgramInfo *p_pginfo, LibGoblin_BinaryInfo *p_binfo, + PtrValue ptr_loadaddr, Elf64_Sym *p_sym, Byte *pb_strtab ) { @@ -70,8 +71,7 @@ LibGoblin_ObjectInfo * // st_value - Symbol value. // st_size - Size of associated object. p_obj = ObjectInfo_InsetObject( p_pginfo, - ((PtrValue)p_sym->st_value + p_binfo->ptr_loadbase), - (QWord)p_sym->st_size, NULL, 0x01 ); + ptr_loadaddr, (QWord)p_sym->st_size, NULL, 0x01 ); // st_name - String table index of name. p_obj->pstr_name = (char *)(pb_strtab + p_sym->st_name); @@ -167,7 +167,15 @@ int p_sym = (Elf64_Sym *)pb_symtab; for( dw_cnt = 0; ((dw_cnt < dw_symbols) && (0x00 == i_result)); dw_cnt++, p_sym++ ) { - ELF64_Symtab_RegistSymbol_toObjectInfo( p_pginfo, p_binfo, p_sym, pb_strtab ); + + // Dynamic Symbol without addr. don't regist ObjectInfo. --- + if(( SHN_UNDEF == p_sym->st_shndx ) && ( 0x00000000 == p_sym->st_value )) + { continue; } + + // Regist Symbol to ObjectInfo. --- + ELF64_Symtab_RegistSymbol_toObjectInfo( + p_pginfo, p_binfo, ((PtrValue)p_sym->st_value + p_binfo->ptr_loadbase), + p_sym, pb_strtab ); } if( 0x00 != i_result ) { diff --git a/libgoblin/drd64_libgoblin_elf_symtab.h b/libgoblin/drd64_libgoblin_elf_symtab.h index ce4aabf..950c68a 100644 --- a/libgoblin/drd64_libgoblin_elf_symtab.h +++ b/libgoblin/drd64_libgoblin_elf_symtab.h @@ -52,7 +52,7 @@ Comment: LIBGOBLIN_ELF_SYMTAB_EXTERN LibGoblin_ObjectInfo *ELF64_Symtab_RegistSymbol_toObjectInfo( LibGoblin_ProgramInfo *p_pginfo, LibGoblin_BinaryInfo *p_binfo, - Elf64_Sym *p_sym, Byte *pb_strtab ); + PtrValue ptr_loadaddr, Elf64_Sym *p_sym, Byte *pb_strtab ); LIBGOBLIN_ELF_SYMTAB_EXTERN int ELF64_Symtab_ReadSection( LibGoblin_BinaryInfo *p_binfo ); diff --git a/libgoblin/drd64_libgoblin_section.c b/libgoblin/drd64_libgoblin_section.c index 4a507d7..b644c3e 100644 --- a/libgoblin/drd64_libgoblin_section.c +++ b/libgoblin/drd64_libgoblin_section.c @@ -104,6 +104,7 @@ int p_globsec->pstr_secname = p_sectbl->pstr_secname; p_globsec->qw_size = p_sectbl->qw_size; p_globsec->qw_flag = p_sectbl->qw_flag; + p_globsec->qw_entsize = p_sectbl->qw_entsize; p_globsec->i_binfile = p_sectbl->i_binfile; if( SHF_ALLOC & p_sectbl->qw_flag ) { p_globsec->ptr_addr.value = p_sectbl->ptr_addr.value + p_binfo->ptr_loadbase; } @@ -136,6 +137,7 @@ int p_globsec->pstr_secname = p_sectbl->pstr_secname; p_globsec->qw_size = p_sectbl->qw_size; p_globsec->qw_flag = p_sectbl->qw_flag; + p_globsec->qw_entsize = p_sectbl->qw_entsize; p_globsec->i_binfile = p_sectbl->i_binfile; if( SHF_ALLOC & p_sectbl->qw_flag ) { p_globsec->ptr_addr.value = p_sectbl->ptr_addr.value + p_binfo->ptr_loadbase; } diff --git a/libgoblin/drd64_libgoblin_type.h b/libgoblin/drd64_libgoblin_type.h index b94f7dc..54906e0 100644 --- a/libgoblin/drd64_libgoblin_type.h +++ b/libgoblin/drd64_libgoblin_type.h @@ -46,6 +46,7 @@ typedef struct { Ptr ptr_addr; QWord qw_size; QWord qw_flag; + QWord qw_entsize; char *pstr_secname; int i_binfile; -- 2.11.0