From 04d1b66dd4598143a073d6414199c9a1bfce9930 Mon Sep 17 00:00:00 2001 From: "Koine Yuusuke(koinec)" Date: Sun, 10 Mar 2019 19:36:20 +0900 Subject: [PATCH] 2019/03/10(Sun) 19:36 (LibGoblin) * WorkBackup --- libgoblin/drd64_libgoblin_elf_dynsym.c | 19 ++++++-------- libgoblin/drd64_libgoblin_elf_gnuver.c | 47 ++++++++++++++++++++++++++++------ libgoblin/drd64_libgoblin_elf_gnuver.h | 3 ++- libgoblin/drd64_libgoblin_elf_hash.c | 30 ++++++++++++++++++---- libgoblin/drd64_libgoblin_elf_hash.h | 3 ++- 5 files changed, 76 insertions(+), 26 deletions(-) diff --git a/libgoblin/drd64_libgoblin_elf_dynsym.c b/libgoblin/drd64_libgoblin_elf_dynsym.c index 8b71775..b76e69d 100644 --- a/libgoblin/drd64_libgoblin_elf_dynsym.c +++ b/libgoblin/drd64_libgoblin_elf_dynsym.c @@ -46,7 +46,6 @@ int LibGoblin_BinaryInfo *p_binfo ) { char *pstr_symname; - char *pstr_vername; Byte *pb_dynstr; int i_bid; int i_result; @@ -67,7 +66,6 @@ int LibGoblin_ProgramInfo *p_pginfo; LibGoblin_BinaryInfo *p_binlib; - // Check exist .dynsym section --- psec_dynsym = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM ); @@ -103,11 +101,8 @@ int p_pginfo = ProgInfo_GetProgInfo( p_binfo->i_pginfo ); assert( NULL != p_pginfo ); - // Loop. --- - pstr_vername = NULL; p_sym = (Elf64_Sym *)psec_dynsym->pb_data; - //for( dw_sym = 0; dw_sym < dw_symbols; dw_sym++, p_sym++, pw_gnuver++ ) { for( dw_sym = 0; dw_sym < dw_symbols; dw_sym++, p_sym++ ) { if( NULL != pw_gnuver ) { w_gnuver = *pw_gnuver++; } @@ -127,20 +122,21 @@ int if( SHN_UNDEF != p_sym->st_shndx ) { continue; } // Search DynSym_Version --- - i_bid = p_binfo->i_id; + i_bid = p_binfo->i_id; if( 1 < w_gnuver ) { p_vernow = p_verneed; for( dw_cnt = 0; dw_cnt < dw_vermax; dw_cnt++, p_vernow++ ) { if( w_gnuver == p_vernow->dw_other ) { - i_bid = p_vernow->i_binfo_id; - pstr_vername = p_vernow->pstr_vername; + i_bid = p_vernow->i_binfo_id; break; } } } - if( i_bid == p_binfo->i_id ) - { i_bid = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid ); } + if( i_bid == p_binfo->i_id ) { + i_bid = BinInfo_SearchNextSlave( p_binfo->i_id, i_bid ); + p_vernow = NULL; + } pstr_symname = (char *)(pb_dynstr + p_sym->st_name); @@ -149,7 +145,7 @@ int p_binlib = BinaryInfo_GetBinInfo( i_bid ); assert( NULL != p_binlib ); - i_result = ELF64_GnuHash_SearchDynSym( p_binlib, pstr_symname, pstr_vername ); + i_result = ELF64_GnuHash_SearchDynSym( p_binlib, pstr_symname, p_vernow ); if( 0 <= i_result ) { break; } @@ -159,6 +155,7 @@ int printf(" debug: [%2u] %s (%s) = %d\n", dw_sym, pstr_symname, p_binlib->str_filename, i_result ); + // 2019/03/05 -- TODO // Set Info. for ObjectInfo diff --git a/libgoblin/drd64_libgoblin_elf_gnuver.c b/libgoblin/drd64_libgoblin_elf_gnuver.c index 730e52e..5e15a9c 100644 --- a/libgoblin/drd64_libgoblin_elf_gnuver.c +++ b/libgoblin/drd64_libgoblin_elf_gnuver.c @@ -45,24 +45,26 @@ LIBGOBLIN_ELF_GNUVER_EXTERN int ELF64_GnuVer_CheckVerName_inVerDef( LibGoblin_BinaryInfo *p_binfo, - char *pstr_vername, + GnuVer_VerNeed *p_verneed, Word w_version ) { int i_result = 0x00; - //Byte *pb_gnuver_d; + Byte *pb_gnuver_d; Byte *pb_dynstr; + DWord dw_next; Elf64_Verdef *pelf_verdef; + Elf64_Verdaux *pelf_vdaux; LibGoblin_SectionInfo *psec_dynstr; LibGoblin_SectionInfo *psec_gnuver_d; + //---------------------------- psec_gnuver_d = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_GNU_VERSION_D ); assert( NULL != psec_gnuver_d ); if( NULL == psec_gnuver_d->pb_data ) { goto goto_ELF64_GnuVer_CheckVerName_inVerDef_post; } - //pb_gnuver_d = psec_gnuver_d->pb_data; - pelf_verdef = (Elf64_Verdef *)psec_gnuver_d->pb_data; + pb_gnuver_d = psec_gnuver_d->pb_data; psec_dynstr = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR ); @@ -71,8 +73,37 @@ int { goto goto_ELF64_GnuVer_CheckVerName_inVerDef_post; } pb_dynstr = psec_dynstr->pb_data; + do { + pelf_verdef = (Elf64_Verdef *)pb_gnuver_d; + dw_next = pelf_verdef->vd_next; + pelf_vdaux = (Elf64_Verdaux *)(pb_gnuver_d + pelf_verdef->vd_aux); + + if( w_version == pelf_verdef->vd_ndx ) { +/* + printf(" [VerDef] lib= %s ndx=%d next= %xh VerName= %s hash= %08x\n", + p_binfo->str_filename, pelf_verdef->vd_ndx, pelf_verdef->vd_next, + (pb_dynstr + pelf_vdaux->vda_name), pelf_verdef->vd_hash ); +*/ + + if( pelf_verdef->vd_hash != p_verneed->dw_hash ) { + i_result = -0x01; + goto goto_ELF64_GnuVer_CheckVerName_inVerDef_post; + } + + if( strncmp( p_verneed->pstr_vername, + (char *)(pb_dynstr + pelf_vdaux->vda_name), 256 )) { + i_result = -0x02; + goto goto_ELF64_GnuVer_CheckVerName_inVerDef_post; + } -printf(" %s next = %xh\n", p_binfo->str_filename, pelf_verdef->vd_next ); + // Check VerName is OK. + i_result = 0x01; + break; + } + + pb_gnuver_d += pelf_verdef->vd_next; + pelf_verdef = (Elf64_Verdef *)pb_gnuver_d; + } while( 0 < dw_next ); goto_ELF64_GnuVer_CheckVerName_inVerDef_post: return i_result; @@ -151,6 +182,7 @@ GnuVer_VerNeed * p_vertemp->pv_verneed = (void *)p_verneed; p_vertemp->pv_vernaux = (void *)p_vernaux; p_vertemp->pstr_vername = (char *)(pb_dynstr + p_vernaux->vna_name); + p_vertemp->dw_hash = p_vernaux->vna_hash; p_vertemp->dw_other = p_vernaux->vna_other; p_vertemp->i_binfo_id = i_bid; p_vertemp++; @@ -166,8 +198,8 @@ GnuVer_VerNeed * printf(" [Verneed] vn_aux= %d, vn_next= %d\n", p_verneed->vn_aux, p_verneed->vn_next ); - printf(" [VernAux] vna_name= %s, vna_other= %d, \n\n", - (pb_dynstr + p_vernaux->vna_name), p_vernaux->vna_other); + printf(" [VernAux] vna_name= %s, vna_other= %d vna_hash= %08x \n\n", + (pb_dynstr + p_vernaux->vna_name), p_vernaux->vna_other, p_vernaux->vna_hash); */ dw_next = p_verneed->vn_next; @@ -197,4 +229,3 @@ void /* EOF of drd64_.c ----------------------------------- */ - diff --git a/libgoblin/drd64_libgoblin_elf_gnuver.h b/libgoblin/drd64_libgoblin_elf_gnuver.h index 446b215..01630de 100644 --- a/libgoblin/drd64_libgoblin_elf_gnuver.h +++ b/libgoblin/drd64_libgoblin_elf_gnuver.h @@ -53,6 +53,7 @@ typedef struct { void *pv_verneed; void *pv_vernaux; char *pstr_vername; + DWord dw_hash; DWord dw_other; int i_binfo_id; } GnuVer_VerNeed; @@ -60,7 +61,7 @@ typedef struct { LIBGOBLIN_ELF_GNUVER_EXTERN int ELF64_GnuVer_CheckVerName_inVerDef( - LibGoblin_BinaryInfo *p_binfo, char *pstr_vername, Word w_version ); + LibGoblin_BinaryInfo *p_binfo, GnuVer_VerNeed *p_verneed, Word w_version ); LIBGOBLIN_ELF_GNUVER_EXTERN GnuVer_VerNeed *ELF64_GnuVer_GenerateGnuVerNeed( DWord *dw_maxver, LibGoblin_BinaryInfo *p_binfo ); diff --git a/libgoblin/drd64_libgoblin_elf_hash.c b/libgoblin/drd64_libgoblin_elf_hash.c index 9ddd4c1..bca0cf0 100644 --- a/libgoblin/drd64_libgoblin_elf_hash.c +++ b/libgoblin/drd64_libgoblin_elf_hash.c @@ -55,13 +55,16 @@ int ELF64_GnuHash_SearchDynSym( LibGoblin_BinaryInfo *p_binfo, char *pstr_symname, - char *pstr_vername ) + GnuVer_VerNeed *p_verneed ) { int i_ret = -0x0f; + int i_result; char *pstr_dynname; Byte *pb_dynstr; Byte *pb_dynsym; Byte *pb_gnuhash; + Word *pw_gvernow; + Word *pw_gnuver; DWord dw_nbuckets; DWord dw_symoffset; DWord dw_bloom_sz; @@ -75,12 +78,14 @@ int DWord *pdw_buckets; DWord *pdw_chain; LibGoblin_SectionInfo *psec_gnuhash; + LibGoblin_SectionInfo *psec_gnuver; LibGoblin_SectionInfo *psec_dynsym; LibGoblin_SectionInfo *psec_dynstr; Elf64_Sym *p_dynsym; Elf64_Sym *p_symnow; //const Sym *sym; + // ---------------- psec_dynsym = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM ); assert( NULL != psec_dynsym ); @@ -90,6 +95,7 @@ int pb_dynsym = psec_dynsym->pb_data; p_dynsym = (Elf64_Sym *)pb_dynsym; + // ---------------- psec_dynstr = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_DYNSTR ); assert( NULL != psec_dynstr ); @@ -98,6 +104,7 @@ int } pb_dynstr = psec_dynstr->pb_data; + // ---------------- psec_gnuhash = Section_GetSectionInfo_fromBinaryInfo( p_binfo, LIBGOBLIN_SECTION_ID_GNU_HASH ); assert( NULL != psec_gnuhash ); @@ -106,6 +113,16 @@ int } pb_gnuhash = psec_gnuhash->pb_data; + // ---------------- + psec_gnuver = Section_GetSectionInfo_fromBinaryInfo( + p_binfo, LIBGOBLIN_SECTION_ID_GNU_VERSION ); + assert( NULL != psec_gnuver ); + if( NULL == psec_gnuver->pb_data ) { + return -0x01; + } + pw_gnuver = (Word *)psec_gnuver->pb_data; + + // ---------------- dw_nbuckets = *((DWord *)(pb_gnuhash)); dw_symoffset = *((DWord *)(pb_gnuhash + 4)); dw_bloom_sz = *((DWord *)(pb_gnuhash + 8)); @@ -127,16 +144,19 @@ int if( dw_symix < dw_symoffset ) { return -0x03; } while( 1 ) { - p_symnow = (p_dynsym + dw_symix); + p_symnow = (p_dynsym + dw_symix); + pw_gvernow = pw_gnuver + dw_symix; pstr_dynname = (char *)(pb_dynstr + p_symnow->st_name); dw_hash = *(pdw_chain + (dw_symix - dw_symoffset)); if(((dw_namehash | 1) == (dw_hash | 1)) && !strcmp(pstr_dynname, pstr_symname)) { - ELF64_GnuVer_CheckVerName_inVerDef( p_binfo, pstr_vername, 0); - i_ret = dw_symix & 0x7fffffff; - break; + i_result = ELF64_GnuVer_CheckVerName_inVerDef( p_binfo, p_verneed, *pw_gvernow); + if( 0x00 <= i_result ) { + i_ret = dw_symix & 0x7fffffff; + break; + } } if( dw_hash & 1 ) { break; } diff --git a/libgoblin/drd64_libgoblin_elf_hash.h b/libgoblin/drd64_libgoblin_elf_hash.h index 978e097..aaae2c3 100644 --- a/libgoblin/drd64_libgoblin_elf_hash.h +++ b/libgoblin/drd64_libgoblin_elf_hash.h @@ -50,7 +50,8 @@ Comment: #endif LIBGOBLIN_ELF_HASH_EXTERN - int ELF64_GnuHash_SearchDynSym( LibGoblin_BinaryInfo *p_binfo, char *pstr_symname, char *pstr_vername ); + int ELF64_GnuHash_SearchDynSym( + LibGoblin_BinaryInfo *p_binfo, char *pstr_symname, GnuVer_VerNeed *p_verneed ); -- 2.11.0