OSDN Git Service

2019/03/10(Sun) 19:36
authorKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 10 Mar 2019 10:36:20 +0000 (19:36 +0900)
committerKoine Yuusuke(koinec) <koinec@users.osdn.me>
Sun, 10 Mar 2019 10:36:20 +0000 (19:36 +0900)
 (LibGoblin)
  * WorkBackup

libgoblin/drd64_libgoblin_elf_dynsym.c
libgoblin/drd64_libgoblin_elf_gnuver.c
libgoblin/drd64_libgoblin_elf_gnuver.h
libgoblin/drd64_libgoblin_elf_hash.c
libgoblin/drd64_libgoblin_elf_hash.h

index 8b71775..b76e69d 100644 (file)
@@ -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
 
index 730e52e..5e15a9c 100644 (file)
@@ -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 ----------------------------------- */
 
-
index 446b215..01630de 100644 (file)
@@ -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 );
index 9ddd4c1..bca0cf0 100644 (file)
@@ -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; }
index 978e097..aaae2c3 100644 (file)
@@ -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 );