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---------------
- process DT_NEEDED on ELF
- process on
- Some thinking on process
- Android power on process
- All About Process On Value and Process On Help
- All About Process On Value and Process On Help
- process memory segment on linux
- Get Process list & info & copy process memory on macosx
- ELF
- ELF
- Elf
- elf
- elf
- ELF
- ELF
- Enabling Process Accounting on Linux HOWTO
- getting detailed process information on Freebsd
- android boot process from power on
- 卷积神经网络理论知识
- Android自定义圆角Span背景
- [欧拉路径] POI 1996 Stage II Problem 3 Gambling
- 目标检测的图像特征提取之(二)LBP特征
- spring中用的设计模式
- process DT_NEEDED on ELF
- PHP工厂策略模式
- libFM的使用
- 最短路径——Floyd算法
- Python学习笔记:列表推导式List Comprehension
- 关于跨域访问json数据的一个笨方法的实践
- 开博第一发了
- caffe代码解读-mnist例子-前向计算
- 数据结构和算法系列之 二叉树