Ai
1 Star 0 Fork 0

博尔特烦恼/hello-elf

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
elf.c 22.30 KB
一键复制 编辑 原始数据 按行查看 历史
博尔特烦恼 提交于 2020-12-17 17:35 +08:00 . hello test gitlab aliyun
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739
#include<stdlib.h>
#include<stdio.h>
#include "elf.h"
int a = 3;
int main(int argc, char *argv[])
{
// 参数错误
if (argc < 2) {
printf("invalid arguments\n");
exit(0);
}
// 打开文件
FILE *fp;
fp = fopen(argv[1], "r");
if (NULL == fp) {
printf("fail to open the file");
exit(0);
}
// 解析head
struct Elf64_Ehdr elf_head;
int shnum, a;
// 读取 head 到elf_head
a = fread(&elf_head, sizeof(struct Elf64_Ehdr), 1, fp);
if (0 == a) {
printf("fail to read head\n");
exit(0);
}
// 判断elf文件类型
if (elf_head.e_ident[0] != 0x7F ||
elf_head.e_ident[1] != 'E' ||
elf_head.e_ident[2] != 'L' || elf_head.e_ident[3] != 'F') {
printf("Not a ELF file\n");
exit(0);
}
// 解析section 分配内存 section * 数量
struct Elf64_Shdr *shdr =
(struct Elf64_Shdr *)malloc(sizeof(struct Elf64_Shdr) *
elf_head.e_shnum);
if (NULL == shdr) {
printf("shdr malloc failed\n");
exit(0);
}
// 设置fp偏移量 offset
a = fseek(fp, elf_head.e_shoff, SEEK_SET);
if (0 != a) {
printf("\nfaile to fseek\n");
exit(0);
}
// 读取section 到 shdr, 大小为shdr * 数量
a = fread(shdr, sizeof(struct Elf64_Shdr) * elf_head.e_shnum, 1, fp);
if (0 == a) {
printf("\nfail to read section\n");
exit(0);
}
// 重置指针位置
rewind(fp);
#if 0
#endif
// 将fp指针移到 字符串表偏移位置处
fseek(fp, shdr[elf_head.e_shstrndx].sh_offset, SEEK_SET);
// 第e_shstrndx项是字符串表 定义 字节 长度 char类型 数组
char shstrtab[shdr[elf_head.e_shstrndx].sh_size];
char *temp = shstrtab;
// 读取内容
a = fread(shstrtab, shdr[elf_head.e_shstrndx].sh_size, 1, fp);
if (0 == a) {
printf("\nfaile to read\n");
}
// printf("\n\节的信息: \n");
// 遍历
// for (int i = 0; i < elf_head.e_shnum; i++)
// {
// temp = shstrtab;
// temp = temp + shdr[i].sh_name;
// printf("节的名称: %s\n", temp);
// printf("节首的偏移: %x\n", shdr[i].sh_offset);
// printf("节的大小: %x\n", shdr[i].sh_size);
// printf("节尾的地址: %x\n", shdr[i].sh_offset + shdr[i].sh_size);
// printf("\n");
// }
// 解析 segment
struct Elf64_Phdr *phdr =
(struct Elf64_Phdr *)malloc(sizeof(struct Elf64_Phdr) *
elf_head.e_phnum);
a = fseek(fp, elf_head.e_phoff, SEEK_SET);
a = fread(phdr, sizeof(struct Elf64_Phdr) * elf_head.e_phnum, 1, fp);
rewind(fp);
fseek(fp, phdr[elf_head.e_shentsize].p_offset, SEEK_SET);
char phstrtab[phdr[elf_head.e_shentsize].p_filesz];
a = fread(phstrtab, phdr[elf_head.e_shentsize].p_filesz, 1, fp);
printf("\n\n段的信息:\n");
for (int i = 0; i < elf_head.e_phnum; i++) {
printf("%d: \n", i);
printf(" 该段首相对偏移: %llx \n", phdr[i].p_offset);
printf(" 该段的大小: %llx \n", phdr[i].p_memsz);
printf(" 该段尾相对偏移: %llx \n",
phdr[i].p_memsz + phdr[i].p_offset);
printf(" *该段包含的节有:\n");
for (int j = 0; j < elf_head.e_shnum; j++) {
if ((shdr[j].sh_offset > phdr[i].p_offset) &&
((shdr[j].sh_offset + shdr[j].sh_size) <
(phdr[i].p_offset + phdr[i].p_memsz))
) {
temp = shstrtab;
temp = temp + shdr[j].sh_name;
printf(" 节的名称: %s\n", temp);
printf(" 节首的偏移: %llx\n",
shdr[j].sh_offset);
printf(" 节的大小: %llx\n",
shdr[j].sh_size);
printf(" 节尾的地址: %llx\n",
shdr[j].sh_offset + shdr[j].sh_size);
printf("\n");
}
}
printf("\n");
}
//test sh_info
int err;
for (int i = 0; i < elf_head.e_shnum; i++) {
unsigned int infosec = shdr[i].sh_info;
printf("infosec: %d\n", infosec);
/* Not a valid relocation section? */
if (infosec >= elf_head.e_shnum)
continue;
// /* Don't bother with non-allocated sections */
// if (!(shdr[infosec].sh_flags & SHF_ALLOC))
// continue;
// 是重定位段
// if (shdr[i].sh_type == SHT_REL)
// err = apply_relocate(info->sechdrs, info->strtab,
// info->index.sym, i, mod);
// else if (info->sechdrs[i].sh_type == SHT_RELA)
// err = apply_relocate_add(info->sechdrs, info->strtab,
// info->index.sym, i, mod);
// if (err < 0)
// break;
}
printf("\n");
return 0;
}
#if 0
static void get_rel_dyn_type(u2 machineType,u4 rInfo,u1* type);
void print_elf_section_of_reldyn(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
Elf32_Rel* pRel = NULL;
Elf32_Sym* pSymMem = NULL;
u1* shStringTableMem = NULL;
u4 i = 0;
u4 size = 0;
u1 buf[55];
LookupSection* pLookupSection = NULL;
LookupSection* pLookupStrSection = NULL;
Elf32_Shdr* pReldyn = NULL;
shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
if(NULL == shStringTableMem){
printf("Error,get elf section header string table failed !\n");
goto Exit;
}
for( ; i < pHeader->e_shnum ; i++){
if(pSheader[i].sh_type == SHT_REL && strcmp((const char*)(shStringTableMem + pSheader[i].sh_name),".rel.dyn") == 0){
size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
pRel = (Elf32_Rel*)(mem->base + pSheader[i].sh_offset);
pReldyn = (Elf32_Shdr*) &pSheader[i];
break;
}
continue;
}
if(NULL != pRel){
//@1 by default ,rel.dyn link dynsym ,so it sh_link is the index
pLookupSection = get_section_by_index(mem,pHeader,pSheader,pReldyn->sh_link);
if(NULL == pLookupSection){
printf("Error,get section by index failed\n");
goto Exit;
}
pSymMem = (Elf32_Sym*)pLookupSection->base;
pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
if(NULL == pLookupStrSection){
printf("Error,get sym tab link failed\n");
goto Exit;
}
i = 0;
printf("Relocation section '.rel.dyn' at offset 0x%.8x contains %d entries:\n",pReldyn->sh_addr,size);
printf("Offset Info Type Sym.Value Sym. Name\n");
for( ; i < size ; i++ ){
printf("0x%.8x ",pRel[i].r_offset);
printf("%.8x ",pRel[i].r_info);
memset(&buf,0,55);
get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRel[i].r_info),(u1*)buf);
printf("%-15s",buf);
if(pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_name != 0){
printf("%.8x ",pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_value);
printf("%s",(pLookupStrSection->base + pSymMem[ELF32_R_SYM(pRel[i].r_info)].st_name));
}
printf("\n");
}
}
Exit:
if(shStringTableMem)
free(shStringTableMem);
if(pLookupSection)
free(pLookupSection);
if(pLookupStrSection)
free(pLookupStrSection);
}
//this impl code almost sample as the top print_elf_section_of_reldyn,but its' sh_info point to which section will be relocated
void print_elf_section_of_relplt(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
Elf32_Rel* pRelplt = NULL;
Elf32_Sym* pSymMem = NULL;
u1* shStringTableMem = NULL;
u4 i = 0;
u4 size = 0;
u1 buf[55];
LookupSection* pLookupSection = NULL;
LookupSection* pLookupStrSection = NULL;
Elf32_Shdr* pThisSection = NULL;
shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
if(NULL == shStringTableMem){
printf("Error,get elf section header string table failed !\n");
goto Exit;
}
for( ; i < pHeader->e_shnum ; i++){
if(pSheader[i].sh_type == SHT_REL && strcmp((const char*)(shStringTableMem + pSheader[i].sh_name),".rel.plt") == 0){
size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
pRelplt = (Elf32_Rel*)(mem->base + pSheader[i].sh_offset);
pThisSection = (Elf32_Shdr*)&pSheader[i];
break;
}
continue;
}
if(NULL != pRelplt){
//@1 by default ,rel.dyn link dynsym ,so it sh_link is the index
pLookupSection = get_section_by_index(mem,pHeader,pSheader,pThisSection->sh_link);
if(NULL == pLookupSection){
printf("Error,get section by index failed\n");
goto Exit;
}
pSymMem = (Elf32_Sym*)pLookupSection->base;
pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
if(NULL == pLookupStrSection){
printf("Error,get sym tab link failed\n");
goto Exit;
}
i = 0;
printf("Relocation section '.rel.plt' at offset 0x%.8x contains %d entries:\n",pThisSection->sh_addr,size);
printf("Offset Info Type Sym.Value Sym. Name\n");
for( ; i < size ; i++ ){
printf("0x%.8x ",pRelplt[i].r_offset);
printf("%.8x ",pRelplt[i].r_info);
memset(&buf,0,55);
get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRelplt[i].r_info),(u1*)buf);
printf("%s ",buf);
if(pSymMem[ELF32_R_SYM(pRelplt[i].r_info)].st_name != 0){
printf("%.8x ",pSymMem[ELF32_R_SYM(pRelplt[i].r_info)].st_value);
printf("%s",(pLookupStrSection->base + pSymMem[ELF32_R_SYM(pRelplt[i].r_info)].st_name));
}
printf("\n");
}
}
Exit:
if(shStringTableMem)
free(shStringTableMem);
if(pLookupSection)
free(pLookupSection);
if(pLookupStrSection)
free(pLookupStrSection);
}
void print_elf_section_of_allrela(MemMapping* mem,Elf32_Ehdr* pHeader,Elf32_Shdr* pSheader){
Elf32_Rela* pRelplt = NULL;
Elf32_Sym* pRelaMem = NULL;
u4 i = 0;
u4 size = 0;
u1 buf[55];
LookupSection* pLookupSection = NULL;
LookupSection* pLookupStrSection = NULL;
Elf32_Shdr* pThisSection;
u1* shStringTableMem = NULL;
shStringTableMem = get_elf_section_of_shstr_table(mem,pHeader,pSheader);
if(NULL == shStringTableMem){
printf("Error,get elf section header string table failed !\n");
goto Exit;
}
for( ; i < pHeader->e_shnum ; i++){
if(pSheader[i].sh_type == SHT_RELA){
size = (pSheader[i].sh_size / pSheader[i].sh_entsize);
pRelplt = (Elf32_Rela*)(mem->base + pSheader[i].sh_offset);
pThisSection = (Elf32_Shdr*)(&pSheader[i]);
if(NULL != pRelplt){
//@1 by default ,RELA link dynsym ,so it sh_link is the index
pLookupSection = get_section_by_index(mem,pHeader,pSheader,pThisSection->sh_link);
if(NULL == pLookupSection){
printf("Error,get section by index failed\n");
goto Exit;
}
pRelaMem = (Elf32_Sym*)pLookupSection->base;
pLookupStrSection = get_section_by_index(mem,pHeader,pSheader,pLookupSection->link);
if(NULL == pLookupStrSection){
printf("Error,get sym tab link failed\n");
goto Exit;
}
u4 j = 0;
printf("Relocation section '%s' at offset 0x%.8x contains %d entries:\n",(shStringTableMem + pSheader[i].sh_name),pThisSection->sh_offset,size);
printf("Offset Info Type Sym.Value Sym. Name + Addend\n");
for( ; j < size ; j++ ){
printf("0x%.8x ",pRelplt[j].r_offset);
printf("%.8x ",pRelplt[j].r_info);
memset(&buf,0,55);
get_rel_dyn_type((u2)pHeader->e_machine,(u4)ELF32_R_TYPE(pRelplt[j].r_info),(u1*)buf);
printf("%-15s ",buf);
if(pRelaMem[ELF32_R_SYM(pRelplt[j].r_info)].st_name != 0){
printf("%.8x ",pRelaMem[ELF32_R_SYM(pRelplt[j].r_info)].st_value);
printf("%-10s ",(pLookupStrSection->base + pRelaMem[ELF32_R_SYM(pRelplt[j].r_info)].st_name));
}
else{
printf("%-22s","");
}
printf("%.8x",pRelplt[j].r_addend);
printf("\n");
}
memset(pLookupSection,0,GET_SIZE(LookupSection));
memset(pLookupSection,0,GET_SIZE(pLookupStrSection));
}
}
continue;
}
Exit:
if(shStringTableMem)
free(shStringTableMem);
if(pLookupSection){
free(pLookupSection);
pLookupSection = NULL;
}
if(pLookupStrSection){
free(pLookupStrSection);
pLookupStrSection = NULL;
}
return;
}
static void get_rel_dyn_type(u2 machineType,u4 rInfo,u1* type){
switch(machineType){
case EM_386:
switch(rInfo){
case R_386_NONE:
memcpy(type,"R_386_NONE",strlen("R_386_NONE"));
break;
case R_386_32:
memcpy(type,"R_386_32",strlen("R_386_32"));
break;
case R_386_PC32:
memcpy(type,"R_386_NONE",strlen("R_386_PC32"));
break;
case R_386_GOT32:
memcpy(type,"R_386_GOT32",strlen("R_386_GOT32"));
break;
case R_386_PLT32:
memcpy(type,"R_386_PLT32",strlen("R_386_PLT32"));
break;
case R_386_COPY:
memcpy(type,"R_386_COPY",strlen("R_386_COPY"));
break;
case R_386_GLOB_DAT:
memcpy(type,"R_386_GLOB_DAT",strlen("R_386_GLOB_DAT"));
break;
case R_386_JMP_SLOT:
memcpy(type,"R_386_JMP_SLOT",strlen("R_386_JMP_SLOT"));
break;
case R_386_RELATIVE:
memcpy(type,"R_386_RELATIVE",strlen("R_386_RELATIVE"));
break;
case R_386_GOTOFF:
memcpy(type,"R_386_GOTOFF",strlen("R_386_GOTOFF"));
break;
case R_386_GOTPC:
memcpy(type,"R_386_GLOB_DAT",strlen("R_386_GOTPC"));
break;
case R_386_TLS_TPOFF:
memcpy(type,"R_386_TLS_TPOFF",strlen("R_386_TLS_TPOFF"));
break;
case R_386_TLS_IE:
memcpy(type,"R_386_TLS_IE",strlen("R_386_TLS_IE"));
break;
case R_386_TLS_GOTIE:
memcpy(type,"R_386_TLS_GOTIE",strlen("R_386_TLS_GOTIE"));
break;
case R_386_TLS_LE:
memcpy(type,"R_386_TLS_LE",strlen("R_386_TLS_LE"));
break;
case R_386_TLS_GD:
memcpy(type,"R_386_TLS_GD",strlen("R_386_TLS_GD"));
break;
case R_386_TLS_LDM:
memcpy(type,"R_386_TLS_LDM",strlen("R_386_TLS_LDM"));
break;
case R_386_16:
memcpy(type,"R_386_16",strlen("R_386_16"));
break;
case R_386_PC16:
memcpy(type,"R_386_PC16",strlen("R_386_PC16"));
break;
case R_386_8:
memcpy(type,"R_386_8",strlen("R_386_8"));
break;
case R_386_PC8:
memcpy(type,"R_386_PC8",strlen("R_386_PC8"));
break;
case R_386_TLS_GD_32:
memcpy(type,"R_386_TLS_GD_32",strlen("R_386_TLS_GD_32"));
break;
case R_386_TLS_GD_PUSH:
memcpy(type,"R_386_TLS_GD_PUSH",strlen("R_386_TLS_GD_PUSH"));
break;
case R_386_TLS_GD_CALL:
memcpy(type,"R_386_TLS_GD_CALL",strlen("R_386_TLS_GD_CALL"));
break;
case R_386_TLS_GD_POP:
memcpy(type,"R_386_TLS_GD_POP",strlen("R_386_TLS_GD_POP"));
break;
case R_386_TLS_LDM_32:
memcpy(type,"R_386_TLS_LDM_32",strlen("R_386_TLS_LDM_32"));
break;
case R_386_TLS_LDM_PUSH:
memcpy(type,"R_386_TLS_LDM_PUSH",strlen("R_386_TLS_LDM_PUSH"));
break;
case R_386_TLS_LDM_CALL:
memcpy(type,"R_386_TLS_LDM_CALL",strlen("R_386_TLS_LDM_CALL"));
break;
case R_386_TLS_LDM_POP:
memcpy(type,"R_386_TLS_LDM_POP",strlen("R_386_TLS_LDM_POP"));
break;
case R_386_TLS_LDO_32:
memcpy(type,"R_386_TLS_LDO_32",strlen("R_386_TLS_LDO_32"));
break;
case R_386_TLS_IE_32:
memcpy(type,"R_386_TLS_IE_32",strlen("R_386_TLS_IE_32"));
break;
case R_386_TLS_LE_32:
memcpy(type,"R_386_TLS_LE_32",strlen("R_386_TLS_LE_32"));
break;
case R_386_TLS_DTPMOD32:
memcpy(type,"R_386_TLS_DTPMOD32",strlen("R_386_TLS_DTPMOD32"));
break;
case R_386_TLS_DTPOFF32:
memcpy(type,"R_386_TLS_DTPOFF32",strlen("R_386_TLS_DTPOFF32"));
break;
case R_386_TLS_TPOFF32:
memcpy(type,"R_386_TLS_TPOFF32",strlen("R_386_TLS_TPOFF32"));
break;
case R_386_IRELATIVE:
memcpy(type,"R_386_IRELATIVE",strlen("R_386_IRELATIVE"));
break;
default:
break;
}
break;
case EM_ARM:
switch(rInfo){
case R_ARM_NONE:
memcpy(type,"R_ARM_NONE",strlen("R_ARM_NONE"));
break;
case R_ARM_PC24:
memcpy(type,"R_ARM_PC24",strlen("R_ARM_PC24"));
break;
case R_ARM_ABS32:
memcpy(type,"R_ARM_ABS32",strlen("R_ARM_ABS32"));
break;
case R_ARM_REL32:
memcpy(type,"R_ARM_REL32",strlen("R_ARM_REL32"));
break;
case R_ARM_PC13:
memcpy(type,"R_ARM_PC13",strlen("R_ARM_PC13"));
break;
case R_ARM_ABS16:
memcpy(type,"R_ARM_ABS16",strlen("R_ARM_ABS16"));
break;
case R_ARM_ABS12:
memcpy(type,"R_ARM_ABS12",strlen("R_ARM_ABS12"));
break;
case R_ARM_THM_ABS5:
memcpy(type,"R_ARM_THM_ABS5",strlen("R_ARM_THM_ABS5"));
break;
case R_ARM_ABS8:
memcpy(type,"R_ARM_ABS8",strlen("R_ARM_ABS8"));
break;
case R_ARM_SBREL32:
memcpy(type,"R_ARM_SBREL32",strlen("R_ARM_SBREL32"));
break;
case R_ARM_THM_PC22:
memcpy(type,"R_ARM_THM_PC22",strlen("R_ARM_THM_PC22"));
break;
case R_ARM_THM_PC8:
memcpy(type,"R_ARM_THM_PC8",strlen("R_ARM_THM_PC8"));
break;
case R_ARM_AMP_VCALL9:
memcpy(type,"R_ARM_AMP_VCALL9",strlen("R_ARM_AMP_VCALL9"));
break;
case R_ARM_SWI24:
memcpy(type,"R_ARM_SWI24",strlen("R_ARM_SWI24"));
break;
case R_ARM_THM_SWI8:
memcpy(type,"R_ARM_THM_SWI8",strlen("R_ARM_THM_SWI8"));
break;
case R_ARM_XPC25:
memcpy(type,"R_ARM_XPC25",strlen("R_ARM_XPC25"));
break;
case R_ARM_THM_XPC22:
memcpy(type,"R_ARM_THM_XPC22",strlen("R_ARM_THM_XPC22"));
break;
case R_ARM_TLS_DTPMOD32:
memcpy(type,"R_ARM_TLS_DTPMOD32",strlen("R_ARM_TLS_DTPMOD32"));
break;
case R_ARM_TLS_DTPOFF32:
memcpy(type,"R_ARM_TLS_DTPOFF32",strlen("R_ARM_TLS_DTPOFF32"));
break;
case R_ARM_TLS_TPOFF32:
memcpy(type,"R_ARM_TLS_TPOFF32",strlen("R_ARM_TLS_TPOFF32"));
break;
case R_ARM_COPY:
memcpy(type,"R_ARM_COPY",strlen("R_ARM_COPY"));
break;
case R_ARM_GLOB_DAT:
memcpy(type,"R_ARM_GLOB_DAT",strlen("R_ARM_GLOB_DAT"));
break;
case R_ARM_JUMP_SLOT:
memcpy(type,"R_ARM_JUMP_SLOT",strlen("R_ARM_JUMP_SLOT"));
break;
case R_ARM_RELATIVE:
memcpy(type,"R_ARM_RELATIVE",strlen("R_ARM_RELATIVE"));
break;
case R_ARM_GOTOFF:
memcpy(type,"R_ARM_GOTOFF",strlen("R_ARM_GOTOFF"));
break;
case R_ARM_GOTPC:
memcpy(type,"R_ARM_GOTPC",strlen("R_ARM_GOTPC"));
break;
case R_ARM_GOT32:
memcpy(type,"R_ARM_GOT32",strlen("R_ARM_GOT32"));
break;
case R_ARM_PLT32:
memcpy(type,"R_ARM_PLT32",strlen("R_ARM_PLT32"));
break;
case R_ARM_GNU_VTENTRY:
memcpy(type,"R_ARM_GNU_VTENTRY",strlen("R_ARM_GNU_VTENTRY"));
break;
case R_ARM_GNU_VTINHERIT:
memcpy(type,"R_ARM_GNU_VTINHERIT",strlen("R_ARM_GNU_VTINHERIT"));
break;
case R_ARM_RSBREL32:
memcpy(type,"R_ARM_RSBREL32",strlen("R_ARM_RSBREL32"));
break;
case R_ARM_THM_RPC22:
memcpy(type,"R_ARM_THM_RPC22",strlen("R_ARM_THM_RPC22"));
break;
case R_ARM_RREL32:
memcpy(type,"R_ARM_RREL32",strlen("R_ARM_RREL32"));
break;
case R_ARM_RABS32:
memcpy(type,"R_ARM_RABS32",strlen("R_ARM_RABS32"));
break;
case R_ARM_RPC24:
memcpy(type,"R_ARM_RPC24",strlen("R_ARM_RPC24"));
break;
case R_ARM_RBASE:
memcpy(type,"R_ARM_RBASE",strlen("R_ARM_RBASE"));
break;
default:
break;
}
break;
default :
//TODO other ellipsis...
break;
}
}
练习:读取section names
从这一讲开始,都会有练习,方便我们把前面的理论知识综合运用。
下面这个练习的目标是:从一个ELF文件中读取存储section name的字符串表。前面讲过,该字符串表也是一个section,section header table中有其对应的section header,并且ELF文件头中给出了节名字符串表对应的section header的索引,e_shstrndx。
我们的思路是这样:
从ELF header中读取section header table的起始位置,每个section header的大小,以及节名字符串表对应section header的索引。
计算section_header_table_offset + section_header_size * e_shstrndx 就是节名字符串表对应section header的偏移。
读取section header,可以从中得到节名字符串表在文件中的偏移和大小。
把节名字符串表读取到内存中,打印其内容。
代码如下:
/* 64位ELF文件读取section name string table */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
int main(int argc, char *argv[])
{
/* 打开本地的ELF可执行文件hello */
FILE *fp = fopen("./hello", "rb");
if(!fp) {
perror("open ELF file");
exit(1);
}
/* 1. 通过读取ELF header得到section header table的偏移 */
/* for 64 bit ELF,
e_ident(16) + e_type(2) + e_machine(2) +
e_version(4) + e_entry(8) + e_phoff(8) = 40 */
fseek(fp, 40, SEEK_SET);
uint64_t sh_off;
int r = fread(&sh_off, 1, 8, fp);
if (r != 8) {
perror("read section header offset");
exit(2);
}
/* 得到的这个偏移值,可以用`reaelf -h hello`来验证是否正确 */
printf("section header offset in file: %ld (0x%lx)\n", sh_off, sh_off);
/* 2. 读取每个section header的大小e_shentsize,
section header的数量e_shnum,
以及对应section name字符串表的section header的索引e_shstrndx
得到这些值后,都可以用`readelf -h hello`来验证是否正确 */
/* e_flags(4) + e_ehsize(2) + e_phentsize(2) + e_phnum(2) = 10 */
fseek(fp, 10, SEEK_CUR);
uint16_t sh_ent_size; /* 每个section header的大小 */
r = fread(&sh_ent_size, 1, 2, fp);
if (r != 2) {
perror("read section header entry size");
exit(2);
}
printf("section header entry size: %d\n", sh_ent_size);
uint16_t sh_num; /* section header的数量 */
r = fread(&sh_num, 1, 2, fp);
if (r != 2) {
perror("read section header number");
exit(2);
}
printf("section header number: %d\n", sh_num);
uint16_t sh_strtab_index; /* 节名字符串表对应的节头的索引 */
r = fread(&sh_strtab_index, 1, 2, fp);
if (r != 2) {
perror("read section header string table index");
exit(2);
}
printf("section header string table index: %d\n", sh_strtab_index);
/* 3. read section name string table offset, size */
/* 先找到节头字符串表对应的section header的偏移位置 */
fseek(fp, sh_off + sh_strtab_index * sh_ent_size, SEEK_SET);
/* 再从section header中找到节头字符串表的偏移 */
/* sh_name(4) + sh_type(4) + sh_flags(8) + sh_addr(8) = 24 */
fseek(fp, 24, SEEK_CUR);
uint64_t str_table_off;
r = fread(&str_table_off, 1, 8, fp);
if (r != 8) {
perror("read section name string table offset");
exit(2);
}
printf("section name string table offset: %ld\n", str_table_off);
/* 从section header中找到节头字符串表的大小 */
uint64_t str_table_size;
r = fread(&str_table_size, 1, 8, fp);
if (r != 8) {
perror("read section name string table size");
exit(2);
}
printf("section name string table size: %ld\n", str_table_size);
/* 动态分配内存,把节头字符串表读到内存中 */
char *buf = (char *)malloc(str_table_size);
if(!buf) {
perror("allocate memory for section name string table");
exit(3);
}
fseek(fp, str_table_off, SEEK_SET);
r = fread(buf, 1, str_table_size, fp);
if(r != str_table_size) {
perror("read section name string table");
free(buf);
exit(2);
}
uint16_t i;
for(i = 0; i < str_table_size; ++i) {
/* 如果节头字符串表中的字节是0,就打印`\0` */
if (buf[i] == 0)
printf("\\0");
else
printf("%c", buf[i]);
}
printf("\n");
free(buf);
fclose(fp);
return 0;
}
#endif
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/home-coder/hello-elf.git
git@gitee.com:home-coder/hello-elf.git
home-coder
hello-elf
hello-elf
master

搜索帮助