ELF文件解析之 ELF头 程序头表 节头表-补充之前文章代码 只支持32位 出版
2014-07-20 22:17
399 查看
提供对ELF文件的一些解析,仅支持32位,出版,进行了部分测试(并不保证完全正确,只是一个帮助作用吧,相互学习借鉴)
最外层的头文件
#ifndef UTIL_H
#define UTIL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/elf.h>
#include<sys/stat.h>
#include "Types.h"
#include "Helper.h"
#define GET_SIZE(n) (sizeof(n))
#define PRINT_PRE_FIVE_BYTE(p) printf("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x \n", \
*(u1*)p,*(u1*)(p+4),*(u1*)(p+8),*(u1*)(p+12),*(u1*)(p+16)) \
#ifndef PT_ARM_EXIDX
#define PT_ARM_EXIDX 0X70000001
#endif
#ifndef SHT_MIPS_MSYM
#define SHT_MIPS_MSYM 0X70000001
#endif
#ifndef SHT_MIPS_GPTAB
#define SHT_MIPS_GPTAB 0x70000003
#endif
#ifndef DT_GNU_PRELINKED
#define DT_GNU_PRELINKED 0x6ffffdf5
#endif
#ifndef DT_GNU_LIBLIST
#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
#endif
#ifndef DT_GNU_LIBLISTSZ
#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
#endif
#ifndef DT_GNU_CONFLICT
#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
#endif
#ifndef DT_GNU_CONFLICTSZ
#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
#endif
/* Flags for the feature selection in DT_FEATURE_1. */
#ifndef DTF_1_PARINIT
#define DTF_1_PARINIT 0x00000001
#endif
#ifndef DTF_1_CONFEXP
#define DTF_1_CONFEXP 0x00000002
#endif
/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
#ifndef DF_P1_LAZYLOAD
#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
#endif
#ifndef DF_P1_GROUPPERM
#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
#endif
#ifdef FIND_ELF_MARCO
//State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry in the dynamic section. */
#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
#define DF_1_TRANS 0x00000200
#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ generally available. */
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
u4 nSize;
u1* base;
}MemMapping;
typedef struct{
u4 type;
u4 link;
u4 info;
u4 nSize;
u4 nEntSize;
u1 name[256];
u1* base;
}LookupSection;
int init_mem_mapping(const char* elf_path,MemMapping* mem);
Elf32_Ehdr* get_elf_header(MemMapping* mem);
void print_elf_header(MemMapping* mem,Elf32_Ehdr* pHeader);
Elf32_Phdr* get_elf_program_header_table(MemMapping* mem,Elf32_Ehdr* pHeader);
void print_elf_program_header_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Phdr* pPheader);
Elf32_Shdr* get_elf_section_header_table(MemMapping* mem,Elf32_Ehdr* pHeader);
u1* get_elf_section_of_shstr_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_header_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_string_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_interpreter(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_dynamic_string_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_dynamic(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
LookupSection* get_section_by_index(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader,u1 index);
Elf32_Sym* get_elf_section_of_sym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_sym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
Elf32_Sym* get_elf_section_of_dynsym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_dyn_sym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_reldyn(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_relplt(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_allrela(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
#ifdef __cplusplus
}
#endif
#endif /* UTIL_H */
最外层实现
/*
* ElfParser.c
*
* Created on: 2014年7月19日
* Author: angel-toms
*/
#include "ElfParser.h"
int init_mem_mapping(const char* elf_path,MemMapping* mem){
int nRet = -1;
int fd = -1;
printf("elf path : %s\n",elf_path);
fd = open(elf_path,O_RDONLY);
if(fd < 0){
perror("Error,open elf file\n");
goto bail;
}
mem->nSize = get_file_size(elf_path);
if(mem->nSize == 0)
goto bail;
mem->base = malloc(mem->nSize);
if(NULL == mem->base){
perror("Error,malloc mem mapping faild\n");
goto bail;
}
memset(mem->base,0,mem->nSize);
if(read(fd,mem->base,mem->nSize) <= 0){
perror("Error,read mem mapping faild\n");
free(mem->base);
mem->base = NULL;
goto bail;
}
nRet = 0;
bail:
if(fd)
close(fd);
return nRet;
}
LookupSection* get_section_by_index(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader,u1 index){
LookupSection* pLookupSection = NULL;
u1* pStringTable = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
if(NULL == pStringTable){
printf("Error,get string table failed !\n");
return NULL;
}
if(index > pHeader->e_shnum){
printf("Error,out of the sections bound !\n");
return NULL;
}
pLookupSection = calloc(1,GET_SIZE(LookupSection));
if(NULL == pLookupSection){
perror("Error,calloc LookupSection failed");
return NULL;
}
pLookupSection->type = pSheader[index].sh_type;
pLookupSection->link = pSheader[index].sh_link;
pLookupSection->info = pSheader[index].sh_info;
pLookupSection->nSize = pSheader[index].sh_size;
pLookupSection->nEntSize = pSheader[index].sh_entsize;
const char* inxName = (char*)(pStringTable + pSheader[index].sh_name);
memcpy(pLookupSection->name,inxName,strlen(inxName));
pLookupSection->base = (u1*)(mem->base + pSheader[index].sh_offset);
return pLookupSection;
}
最外层的头文件
#ifndef UTIL_H
#define UTIL_H
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <time.h>
#include <fcntl.h>
#include <sys/elf.h>
#include<sys/stat.h>
#include "Types.h"
#include "Helper.h"
#define GET_SIZE(n) (sizeof(n))
#define PRINT_PRE_FIVE_BYTE(p) printf("0x%.8x 0x%.8x 0x%.8x 0x%.8x 0x%.8x \n", \
*(u1*)p,*(u1*)(p+4),*(u1*)(p+8),*(u1*)(p+12),*(u1*)(p+16)) \
#ifndef PT_ARM_EXIDX
#define PT_ARM_EXIDX 0X70000001
#endif
#ifndef SHT_MIPS_MSYM
#define SHT_MIPS_MSYM 0X70000001
#endif
#ifndef SHT_MIPS_GPTAB
#define SHT_MIPS_GPTAB 0x70000003
#endif
#ifndef DT_GNU_PRELINKED
#define DT_GNU_PRELINKED 0x6ffffdf5
#endif
#ifndef DT_GNU_LIBLIST
#define DT_GNU_LIBLIST 0x6ffffef9 /* Library list */
#endif
#ifndef DT_GNU_LIBLISTSZ
#define DT_GNU_LIBLISTSZ 0x6ffffdf7 /* Size of library list */
#endif
#ifndef DT_GNU_CONFLICT
#define DT_GNU_CONFLICT 0x6ffffef8 /* Start of conflict section */
#endif
#ifndef DT_GNU_CONFLICTSZ
#define DT_GNU_CONFLICTSZ 0x6ffffdf6 /* Size of conflict section */
#endif
/* Flags for the feature selection in DT_FEATURE_1. */
#ifndef DTF_1_PARINIT
#define DTF_1_PARINIT 0x00000001
#endif
#ifndef DTF_1_CONFEXP
#define DTF_1_CONFEXP 0x00000002
#endif
/* Flags in the DT_POSFLAG_1 entry effecting only the next DT_* entry. */
#ifndef DF_P1_LAZYLOAD
#define DF_P1_LAZYLOAD 0x00000001 /* Lazyload following object. */
#endif
#ifndef DF_P1_GROUPPERM
#define DF_P1_GROUPPERM 0x00000002 /* Symbols from next object are not
#endif
#ifdef FIND_ELF_MARCO
//State flags selectable in the `d_un.d_val' element of the DT_FLAGS_1 entry in the dynamic section. */
#define DF_1_GROUP 0x00000004 /* Set RTLD_GROUP for this object. */
#define DF_1_INITFIRST 0x00000020 /* Set RTLD_INITFIRST for this object*/
#define DF_1_DIRECT 0x00000100 /* Direct binding enabled. */
#define DF_1_TRANS 0x00000200
#define DF_1_INTERPOSE 0x00000400 /* Object is used to interpose. */
#define DF_1_NODUMP 0x00001000 /* Object can't be dldump'ed. */
#define DF_1_CONFALT 0x00002000 /* Configuration alternative created.*/
#define DF_1_ENDFILTEE 0x00004000 /* Filtee terminates filters search. */
#define DF_1_DISPRELDNE 0x00008000 /* Disp reloc applied at build time. */
#define DF_1_DISPRELPND 0x00010000 /* Disp reloc applied at run-time. */ generally available. */
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct {
u4 nSize;
u1* base;
}MemMapping;
typedef struct{
u4 type;
u4 link;
u4 info;
u4 nSize;
u4 nEntSize;
u1 name[256];
u1* base;
}LookupSection;
int init_mem_mapping(const char* elf_path,MemMapping* mem);
Elf32_Ehdr* get_elf_header(MemMapping* mem);
void print_elf_header(MemMapping* mem,Elf32_Ehdr* pHeader);
Elf32_Phdr* get_elf_program_header_table(MemMapping* mem,Elf32_Ehdr* pHeader);
void print_elf_program_header_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Phdr* pPheader);
Elf32_Shdr* get_elf_section_header_table(MemMapping* mem,Elf32_Ehdr* pHeader);
u1* get_elf_section_of_shstr_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_header_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_string_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_interpreter(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_dynamic_string_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_dynamic(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
LookupSection* get_section_by_index(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader,u1 index);
Elf32_Sym* get_elf_section_of_sym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_sym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
Elf32_Sym* get_elf_section_of_dynsym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_dyn_sym_table(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_reldyn(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_relplt(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
void print_elf_section_of_allrela(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader);
#ifdef __cplusplus
}
#endif
#endif /* UTIL_H */
最外层实现
/*
* ElfParser.c
*
* Created on: 2014年7月19日
* Author: angel-toms
*/
#include "ElfParser.h"
int init_mem_mapping(const char* elf_path,MemMapping* mem){
int nRet = -1;
int fd = -1;
printf("elf path : %s\n",elf_path);
fd = open(elf_path,O_RDONLY);
if(fd < 0){
perror("Error,open elf file\n");
goto bail;
}
mem->nSize = get_file_size(elf_path);
if(mem->nSize == 0)
goto bail;
mem->base = malloc(mem->nSize);
if(NULL == mem->base){
perror("Error,malloc mem mapping faild\n");
goto bail;
}
memset(mem->base,0,mem->nSize);
if(read(fd,mem->base,mem->nSize) <= 0){
perror("Error,read mem mapping faild\n");
free(mem->base);
mem->base = NULL;
goto bail;
}
nRet = 0;
bail:
if(fd)
close(fd);
return nRet;
}
LookupSection* get_section_by_index(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader,u1 index){
LookupSection* pLookupSection = NULL;
u1* pStringTable = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
if(NULL == pStringTable){
printf("Error,get string table failed !\n");
return NULL;
}
if(index > pHeader->e_shnum){
printf("Error,out of the sections bound !\n");
return NULL;
}
pLookupSection = calloc(1,GET_SIZE(LookupSection));
if(NULL == pLookupSection){
perror("Error,calloc LookupSection failed");
return NULL;
}
pLookupSection->type = pSheader[index].sh_type;
pLookupSection->link = pSheader[index].sh_link;
pLookupSection->info = pSheader[index].sh_info;
pLookupSection->nSize = pSheader[index].sh_size;
pLookupSection->nEntSize = pSheader[index].sh_entsize;
const char* inxName = (char*)(pStringTable + pSheader[index].sh_name);
memcpy(pLookupSection->name,inxName,strlen(inxName));
pLookupSection->base = (u1*)(mem->base + pSheader[index].sh_offset);
return pLookupSection;
}
相关文章推荐
- ELF文件解析和加载(附代码)
- 分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要)
- 部分GNU代码片 8、程序的配置文件解析部分辨别代码
- 分享非常有用的Java程序 (关键代码)(六)---解析/读取XML 文件(重要)
- Java解析ELF文件:使用Java读取文件头部、节区头部表、程序头部表
- 程序如何在32位机子上支持大文件读写
- perl文件上传程序,支持多文件!
- 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)
- 使用MAP文件快速定位程序崩溃代码行
- 在程序中加载解析3DS文件,显示三维模型(c# MDX),
- bmp文件MFC中翻转、保存和解析代码
- 使用 SqlBulkCopy 大量复制文字文件之 C# 程序代码
- [原创]VB程序 - 处理字符和文件名称的代码模块
- 让UpdatePanel支持文件上传(4):数据传输与解析机制
- 让UpdatePanel支持文件上传(4):数据传输与解析机制
- JAVA 实现多文件同时操作 程序代码
- Intel平台下Linux中 ELF文件动态链接的加载、解析及实例分析(一): 加载
- Beginning C# Objects从概念到代码——1.4 解析一个简单的C#程序
- 一个使用JAVA编写的类似按键精灵的程序,支持脚本文件编写(含源代码)
- 一个WinForm记事本程序(包含主/下拉/弹出菜单/打开文件/保存文件/打印/页面设置/字体/颜色对话框/剪切版操作等等控件用法以及记事本菜单事件/按键事件的具体代码)