LibGoblin_BinaryInfo *p_binfo )
{
char *pstr_symname;
- char *pstr_vername;
Byte *pb_dynstr;
int i_bid;
int i_result;
LibGoblin_ProgramInfo *p_pginfo;
LibGoblin_BinaryInfo *p_binlib;
-
// Check exist .dynsym section ---
psec_dynsym = Section_GetSectionInfo_fromBinaryInfo(
p_binfo, LIBGOBLIN_SECTION_ID_DYNSYM );
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++; }
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);
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;
}
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
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 );
{ 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;
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++;
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;
/* EOF of drd64_.c ----------------------------------- */
-
void *pv_verneed;
void *pv_vernaux;
char *pstr_vername;
+ DWord dw_hash;
DWord dw_other;
int i_binfo_id;
} GnuVer_VerNeed;
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 );
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;
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 );
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 );
}
pb_dynstr = psec_dynstr->pb_data;
+ // ----------------
psec_gnuhash = Section_GetSectionInfo_fromBinaryInfo(
p_binfo, LIBGOBLIN_SECTION_ID_GNU_HASH );
assert( NULL != psec_gnuhash );
}
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));
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; }
#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 );