process DT_NEEDED on ELF

来源:互联网 发布:ug数控车编程 编辑:程序博客网 时间:2024/05/05 00:09

前言

找了一份开源代码来学习ELF文件格式.
当看到对DT_NEEDED处理时,明显不对了.
在android4.0代码中看readelf.c实现时,那个readelf.c 并不是\android-ndk-r10e\toolchains\arm-linux-androideabi-4.9\prebuilt\windows\bin\readelf.exe的实现.

在csdn上下载到一份gnu readelf的源码, [binutils-2.14.tar.gz完整版]
出处是 Binutils (2.14): ftp://ftp.gnu.org/gnu/binutils/

这份源码中的readelf.c, 看着就是控制台版的readelf.exe.
在这份代码中,找到了对ELF中的DT_NEEDED标志的正确处理方法.
如果有时间,可以将gnu版的控制台readelf工程翻译成windows窗口版的readelf.

ndk-r10e中自带的readelf版本,是gnu版2.24的readelf
D:>readelf -v
GNU readelf (GNU Binutils) 2.24.90
Copyright (C) 2014 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) any later version.
This program has absolutely no warranty.

记录

g_addr_dynamic_strings 是DT_NEEDED需要的串表基地址.
只有((shdr->sh_type == SHT_STRTAB && strcmp (tmp, “.dynstr”) == 0))成立时,shdr->sh_offset指向的扇区头偏移才是动态载入字符串表的基地址.

ABBR_TBL_INFO g_abbrInfo;DYNAMIC_INFO gDynamicInfo;int g_addr_dynamic_strings = -1;
BOOL proc_elf32_section(Elf32_Ehdr* ehdr, Elf32_Shdr* shdr, FILE* pFileOut, ABBR_TBL_INFO* pAbbrInfo){    BOOL bRc = FALSE;    char* tmp = NULL;    char szBuf[4096] = {'\0'};    do {        if ((NULL == ehdr) || (NULL == shdr) || (NULL == pFileOut) || (NULL == pAbbrInfo)) {            break;        }        if ((shdr->sh_name == SHN_UNDEF)                    || (shdr->sh_name == SHN_LORESERVE)            || (shdr->sh_name == SHN_LOPROC)            || (shdr->sh_name == SHN_HIPROC)            || (shdr->sh_name == SHN_LOOS)            || (shdr->sh_name == SHN_HIOS)            || (shdr->sh_name == SHN_ABS)            || (shdr->sh_name == SHN_COMMON)            || (shdr->sh_name == SHN_XINDEX)            || (shdr->sh_name == SHN_HIRESERVE))        {            sprintf(szBuf, "Special section, index: %d\r\n", shdr->sh_name);            fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);            break;        }        tmp = (char *)(GetNameStringBaseAddr(ehdr) + shdr->sh_name);        // at this pointer, tmp is section name        sprintf(szBuf, "Section name: %s\r\n", tmp);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        if( !strcmp(tmp, DEBUG_ABBREV_SECTION) )        {            pAbbrInfo->base = shdr->sh_offset;            pAbbrInfo->size = shdr->sh_size;        } else if (shdr->sh_type == SHT_STRTAB            && strcmp (tmp, ".dynstr") == 0) {            // 找动态串表基地址            g_addr_dynamic_strings = (int)ehdr + shdr->sh_offset;            /*            002D0218  00 5F 5F 6C 69 62 63 5F 69 6E 69 74 00 5F 5F 63  .__libc_init.__c            002D0228  78 61 5F 61 74 65 78 69 74 00 70 75 74 73 00 5F  xa_atexit.puts._            002D0238  5F 67 6E 75 5F 55 6E 77 69 6E 64 5F 46 69 6E 64  _gnu_Unwind_Find            002D0248  5F 65 78 69 64 78 00 61 62 6F 72 74 00 6D 65 6D  _exidx.abort.mem            002D0258  63 70 79 00 5F 5F 63 78 61 5F 62 65 67 69 6E 5F  cpy.__cxa_begin_            002D0268  63 6C 65 61 6E 75 70 00 5F 5F 63 78 61 5F 74 79  cleanup.__cxa_ty            002D0278  70 65 5F 6D 61 74 63 68 00 5F 5F 63 78 61 5F 63  pe_match.__cxa_c            002D0288  61 6C 6C 5F 75 6E 65 78 70 65 63 74 65 64 00 5F  all_unexpected._            002D0298  65 64 61 74 61 00 5F 5F 62 73 73 5F 73 74 61 72  edata.__bss_star            002D02A8  74 00 5F 65 6E 64 00 6C 69 62 73 74 64 63 2B 2B  t._end.libstdc++            002D02B8  2E 73 6F 00 6C 69 62 6D 2E 73 6F 00 6C 69 62 63  .so.libm.so.libc            002D02C8  2E 73 6F 00 6C 69 62 64 6C 2E 73 6F 00 00 00 00  .so.libdl.so....            */        }        switch(shdr->sh_type)           /* Section type */        {        case SHT_NULL:      tmp = "NULL section"; break;        case SHT_PROGBITS:  tmp = "SHT_PROGBITS"; break;        case SHT_SYMTAB:    tmp = "SHT_SYMTAB, this section hold a symbol table"; break;        case SHT_STRTAB:    tmp = "SHT_STRTAB, this section hold a string table"; break;        case SHT_RELA:      tmp = "SHT_RELA"; break;        case SHT_HASH:      tmp = "SHT_HASH, this section hold a symbol hash table"; break;        case SHT_DYNAMIC:   tmp = "SHT_DYNAMIC"; break;        case SHT_NOTE:      tmp = "SHT_NOTE"; break;        case SHT_NOBITS:    tmp = "SHT_NOBITS"; break;        case SHT_REL:       tmp = "SHT_REL"; break;        case SHT_SHLIB:     tmp = "SHT_SHLIB"; break;        case SHT_DYNSYM:    tmp = "SHT_DYNSYM"; break;        default:            tmp = "system reserved"; break;        }        sprintf(szBuf, "Type: %s \r\n", tmp);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        sprintf(szBuf, "Flags: ");        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        if(shdr->sh_flags & SHF_WRITE)        {            sprintf(szBuf, "SHF_WRITE ");            fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        }        if(shdr->sh_flags & SHF_ALLOC)        {            sprintf(szBuf, "SHF_ALLOC ");            fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        }        if(shdr->sh_flags & SHF_EXECINSTR)        {            sprintf(szBuf, "SHF_EXECINSTR ");            fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        }        if((shdr->sh_flags & SHF_MASKPROC) == SHF_MASKPROC)        {            sprintf(szBuf, "SHF_MASKPROC ");            fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        }        sprintf(szBuf, "\r\n");        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Section virtual addr at execution */        sprintf(szBuf, "Virtual addr at execution: 0x%x\r\n", shdr->sh_addr);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Section file offset */        sprintf(szBuf, "Offset in file: 0x%x\r\n", shdr->sh_offset);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Section size in bytes */        sprintf(szBuf, "Size: 0x%x\r\n", shdr->sh_size);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Link to another section */        sprintf(szBuf, "Section header link: %d\r\n", shdr->sh_link);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Additional section information */        sprintf(szBuf, "Additional information: %d\r\n", shdr->sh_info);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Section alignment */        sprintf(szBuf, "Alignment: %d\r\n", shdr->sh_addralign);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        /* Entry size if section holds table */        sprintf(szBuf, "Entry size if section holds table: %d\r\n", shdr->sh_entsize);        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        bRc = TRUE;    } while (0);    return bRc;}
void describe_dynamic_info(Elf32_Dyn* dyn, Elf32_Ehdr* ehdr, FILE* pFileOut){    BOOL bProcess = TRUE;    char szBuf[4096] = {'\0'};    char* tmp = NULL;    _ASSERT(NULL != dyn);    _ASSERT(NULL != pFileOut);    switch(dyn->d_tag)    {    case DT_NEEDED:             // 需要载入的库名称        if (g_addr_dynamic_strings >= 0) {            tmp = (char *)(g_addr_dynamic_strings + dyn->d_un.d_val);            sprintf(szBuf, "DT_NEEDED, needed library: %s\r\n", tmp);        }        break;    case DT_PLTRELSZ:        sprintf(szBuf, "DT_PLTRELSZ\r\n");        break;    case DT_PLTGOT:        sprintf(szBuf, "DT_PLTGOT\r\n");        break;    case DT_HASH:        sprintf(szBuf, "DT_HASH, Hash table section offset: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_STRTAB:             sprintf(szBuf, "DT_STRTAB, String table section offset: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_SYMTAB:             sprintf(szBuf, "DT_SYMTAB, Symbol table section offset: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_RELA:               sprintf(szBuf, "DT_RELA, SHT_RELA relocation section offset: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_RELASZ:             sprintf(szBuf, "DT_RELASZ, SHT_RELA relocation section size: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_RELAENT:            sprintf(szBuf, "DT_RELAENT, Entry size in SHT_RELA relocation section: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_STRSZ:              sprintf(szBuf, "DT_STRSZ, String table section size: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_SYMENT:             sprintf(szBuf, "DT_SYMENT, Entry size of ARM symbol table: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_INIT:               sprintf(szBuf, "DT_INIT\r\n");        break;    case DT_FINI:               sprintf(szBuf, "DT_FINI\r\n");        break;    case DT_SONAME:             tmp = (char *)(gDynamicInfo.str_tbl_addr + dyn->d_un.d_val);        sprintf(szBuf, "DT_SONAME, shared object name: %s\r\n", tmp);        break;    case DT_RPATH:              sprintf(szBuf, "DT_RPATH\r\n");        break;    case DT_SYMBOLIC:           sprintf(szBuf, "DT_SYMBOLIC\r\n");        break;    case DT_REL:                sprintf(szBuf, "DT_REL, SHT_REL relocation section offset: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_RELSZ:              sprintf(szBuf, "DT_RELSZ, SHT_REL relocation section size: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_RELENT:             sprintf(szBuf, "DT_RELENT, Entry size in SHT_REL relocation section: 0x%x\r\n", dyn->d_un.d_val);        break;    case DT_PLTREL:             sprintf(szBuf, "DT_PLTREL\r\n");        break;    case DT_DEBUG:              sprintf(szBuf, "DT_DEBUG\r\n");        break;    case DT_TEXTREL:            sprintf(szBuf, "DT_TEXTREL\r\n");        break;    case DT_JMPREL:             sprintf(szBuf, "DT_JMPREL\r\n");        break;    case DT_BIND_NOW:           sprintf(szBuf, "DT_BIND_NOW\r\n");        break;    case DT_LOPROC:         sprintf(szBuf, "DT_LOPROC\r\n");        break;    case DT_HIPROC:         sprintf(szBuf, "DT_HIPROC\r\n");        break;    default:        bProcess = FALSE;        break;    }    if (bProcess) {        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);        sprintf(szBuf, "------------------------------------------------------------\r\n");        fwrite(szBuf, sizeof(char), strlen(szBuf), pFileOut);    }}

运行结果

----------------dynamic begin---------------DT_PLTGOT------------------------------------------------------------DT_PLTRELSZ------------------------------------------------------------DT_JMPREL------------------------------------------------------------DT_PLTREL------------------------------------------------------------DT_REL, SHT_REL relocation section offset: 0x320------------------------------------------------------------DT_RELSZ, SHT_REL relocation section size: 0x60------------------------------------------------------------DT_RELENT, Entry size in SHT_REL relocation section: 0x8------------------------------------------------------------DT_DEBUG------------------------------------------------------------DT_SYMTAB, Symbol table section offset: 0x148------------------------------------------------------------DT_SYMENT, Entry size of ARM symbol table: 0x10------------------------------------------------------------DT_STRTAB, String table section offset: 0x218------------------------------------------------------------DT_STRSZ, String table section size: 0xbd------------------------------------------------------------DT_HASH, Hash table section offset: 0x2d8------------------------------------------------------------DT_NEEDED, needed library: libstdc++.so------------------------------------------------------------DT_NEEDED, needed library: libm.so------------------------------------------------------------DT_NEEDED, needed library: libc.so------------------------------------------------------------DT_NEEDED, needed library: libdl.so----------------------------------------------------------------------------dynamic end---------------
0 0
原创粉丝点击