这个程序用C语言分析实现了elf的header以及section header, 最后找出自定义section里面的内容。
源代码如下:
/*****************************************************************************
* include header file
*****************************************************************************/
#include
#include
#include /* elf header file */
#include
/*****************************************************************************
* define value block
*****************************************************************************/
#define APP_FILE_NAME "selfsection"
#define APP_SELFDEF_SECTION "selfsection"
#define START_TAG "SELFDEF_SECTION"
/*****************************************************************************
* function block
*****************************************************************************/
static int Read_Ushort(FILE *fp, unsigned short *value)
{
unsigned char lsb = 0;
unsigned char msb = 0;
if(fp == NULL)
{
return -1;
}
msb = (unsigned char)fgetc(fp);
lsb = (unsigned char)fgetc(fp);
*value = lsb;
*value = ((*value) << 8) | msb;
return 0;
}
static int Read_Ulong(FILE *fp, unsigned long *value)
{
unsigned char lsb0,lsb1 = 0;
unsigned char msb0,msb1 = 0;
if(fp == NULL)
{
return -1;
}
msb0 = (unsigned char)fgetc(fp);
msb1 = (unsigned char)fgetc(fp);
lsb0 = (unsigned char)fgetc(fp);
lsb1 = (unsigned char)fgetc(fp);
*value = lsb1;
*value = ((*value) << 8) | lsb0;
*value = ((*value) << 8) | msb1;
*value = ((*value) << 8) | msb0;
return 0;
}
static int Read_Elf_Ehdr(FILE* fp, Elf32_Ehdr *ehdr)
{
fread(&ehdr->e_ident,16,1,fp);
Read_Ushort(fp,&ehdr->e_type);
Read_Ushort(fp,&ehdr->e_machine);
Read_Ulong(fp,&ehdr->e_version);
Read_Ulong(fp,&ehdr->e_entry);
Read_Ulong(fp, &ehdr->e_phoff);
Read_Ulong(fp,&ehdr->e_shoff);
Read_Ulong(fp,&ehdr->e_flags);
Read_Ushort(fp,&ehdr->e_ehsize);
Read_Ushort(fp,&ehdr->e_phentsize);
Read_Ushort(fp,&ehdr->e_phnum);
Read_Ushort(fp,&ehdr->e_shentsize);
Read_Ushort(fp,&ehdr->e_shnum);
Read_Ushort(fp,&ehdr->e_shstrndx);
return 0;
}
static int get_section_info(FILE* fp, Elf32_Shdr *sHdr)
{
Read_Ulong(fp, &sHdr->sh_name);
Read_Ulong(fp, &sHdr->sh_type);
Read_Ulong(fp, &sHdr->sh_flags);
Read_Ulong(fp, &sHdr->sh_addr);
Read_Ulong(fp, &sHdr->sh_offset);
Read_Ulong(fp, &sHdr->sh_size);
Read_Ulong(fp, &sHdr->sh_link);
Read_Ulong(fp, &sHdr->sh_info);
Read_Ulong(fp, &sHdr->sh_addralign);
Read_Ulong(fp, &sHdr->sh_entsize);
return 0;
}
int chk_self_def_section(FILE *fp, Elf32_Off sh_offset)
{
unsigned char szBuf[strlen(START_TAG)];
memset(szBuf, 0, sizeof(szBuf));
fseek(fp, sh_offset, SEEK_SET);
fread(szBuf, strlen(START_TAG), 1, fp);
printf("#######################offset =%x\n", sh_offset);
if(sh_offset == 0x6e8)
printf("len=%d, szBuf=%s\n", strlen(START_TAG), szBuf);
if(strncmp(szBuf, START_TAG, strlen(START_TAG)) == 0)
{
return 0;
}
return -1;
}
static void process_app_info(FILE *fp, Elf32_Shdr *section)
{
unsigned char szBuf[1024];
rewind(fp);
fseek(fp, section->sh_offset, SEEK_SET);
memset(szBuf, 0, sizeof(szBuf));
fread(szBuf, section->sh_size, 1, fp);
printf("%s\n", szBuf);
}
int main(void)
{
int i = 0;
int nRet = 0;
int strtab_cnt = 0;
int strtab_idx = 0;
int selfdef_section_idx = 0;
Elf32_Ehdr elfFHeader;
Elf32_Shdr section; /* define one section structure */
FILE *fp;
fp = fopen(APP_FILE_NAME, "rb");
if(fp == NULL)
{
printf("error open file\n");
return -1;
}
memset(&elfFHeader, 0, sizeof(Elf32_Ehdr));
Read_Elf_Ehdr(fp, &elfFHeader);
printf("section header offset=%x\n", elfFHeader.e_shoff);
printf("each section size=%x\n", elfFHeader.e_shentsize);
printf("section num=%x\n", elfFHeader.e_shnum);
for(i = 0; i < elfFHeader.e_shnum; i++)
{
/* reset fp */
fseek(fp,
elfFHeader.e_shoff + i * elfFHeader.e_shentsize,
SEEK_SET);
get_section_info(fp, §ion);
printf("ind=%d: name=%x; type=%x; flags=%x; addr=%x; offset=%x; size=%x; link=%x; \n\tinfo=%x; addraliggn=%x; entsiz=%x;\n", i,
section.sh_name, section.sh_type,
section.sh_flags, section.sh_addr,
section.sh_offset, section.sh_size,
section.sh_link, section.sh_info,
section.sh_addralign, section.sh_entsize);
nRet = chk_self_def_section(fp, section.sh_offset);
if(nRet == 0)
{
process_app_info(fp, §ion);
break;
}
}
if(i == elfFHeader.e_shnum)
{
printf("Appinfo not found!\n");
fclose(fp);
return -1;
}
fclose(fp);
return 0;
}
PS:
1. 我曾尝试找到STRTAB这个类型的section来,判断section header里面section名字字串的位置,再查找self_def_section在section header中的index。但是这样有风险,我用的编译器编译出来的elf文件,始终不能在shstrtab中读取到.plt这个section的名字。
2. 这里,我用了一个较苯的算法,读一个section就根据这个section的offset找到对应文件的地方判断是否是自定义section内容,如果不是就继续读取下一个section,知道读取到自定section为止。
这种方法虽然笨了点,但是一定可以找到自定义section,而且效率是稳定的。
3. 当然,自定义section一般在section header里面比较靠后,可以从最后一个section往前读取,效率更高。
4. Read_Ulong 和Read_Ushort要根据情况,这里是linux elf文件因此有little endian的问题.