#include <stdio.h>
#include <elf.h>
#include <unistd.h>
#include <sys/stat.h>
#include <stdlib.h>
#include <string.h>
// size : 64 byte
// typedef uint32_t Elf64_Word;
// typedef uint64_t Elf64_Xword;
// typedef uint64_t Elf64_Addr;
// typedef uint64_t Elf64_Off;
// typedef struct
// {
// Elf64_Word sh_name; /* Section name (string tbl index) */
// Elf64_Word sh_type; /* Section type */
// Elf64_Xword sh_flags; /* Section flags */
// Elf64_Addr sh_addr; /* Section virtual addr at execution */
// Elf64_Off sh_offset; /* Section file offset */
// Elf64_Xword sh_size; /* Section size in bytes */
// Elf64_Word sh_link; /* Link to another section */
// Elf64_Word sh_info; /* Additional section information */
// Elf64_Xword sh_addralign; /* Section alignment */
// Elf64_Xword sh_entsize; /* Entry size if section holds table */
// } Elf64_Shdr;
int main(int argc, char* argv[]) {
printf("hello ELF \n");
char* fileName = argv[1];
struct stat st;
if (-1 == stat(fileName, &st)) {
printf("%s not exist \n", fileName);
return -1;
} else {
printf("parse ELF file %s, size %ld \n", fileName, st.st_size);
}
char* buf = (char*)malloc(st.st_size);
FILE* fp = fopen(fileName, "rb");
if (fp) {
size_t count = fread(buf, 1, st.st_size, fp);
fclose(fp);
printf("load %ld bytes from %s \n", count, fileName);
}
fseek (fp, 0, SEEK_SET);
// 64 bytes
Elf64_Ehdr elf64_header;
// 64 bytes
Elf64_Shdr elf64_secHeader;
// printf("sizeof elf64_header %ld, section header: %ld \n", sizeof(elf64_header), sizeof(elf64_secHeader));
// parse header
memcpy(&elf64_header, buf, sizeof(Elf64_Ehdr));
printf("\nELF Header:");
printf("程序入口地址: 0x%lx \n", elf64_header.e_entry);
printf("段信息: \n");
printf("\tsection table entry: 0x%lx, \n\teach section size: 0x%x, \n\tsection count: %d, \n\tsymtab index: %d \n",
elf64_header.e_shoff, elf64_header.e_shentsize, elf64_header.e_shnum, elf64_header.e_shstrndx);
printf("\n");
fseek (fp, 0, SEEK_SET);
int secNum = elf64_header.e_shnum;
size_t secTabSize = elf64_header.e_shentsize * secNum;
Elf64_Shdr* secTabPtr = (Elf64_Shdr*)malloc(secTabSize);
memset(secTabPtr, 0, secTabSize);
memcpy((void*)secTabPtr, buf + elf64_header.e_shoff, secTabSize);
// 1. section string section
Elf64_Shdr* ptr = (Elf64_Shdr*)((char*)secTabPtr + elf64_header.e_shstrndx * elf64_header.e_shentsize);
Elf64_Off sh_offset = ptr->sh_offset;
Elf64_Xword sh_size = ptr->sh_size;
printf("sh_offset : 0x%lx, sh_size 0x%lx \n", sh_offset, sh_size);
char* shstrPtr = (char*)malloc(sh_size);
memcpy(shstrPtr, buf + ptr->sh_offset, sh_size);
printf("shstr 段: \n");
for (int i = 0; i < sh_size; i++) printf("%c", shstrPtr[i]);
printf("\n");
// 打印各段的header信息
int strtabIndex, texttabIndex, datatabIndex, bsstabIndex, symtabIndex;
for (int i = 0; i < secNum; i++) {
Elf64_Shdr* ptr = (Elf64_Shdr*)((char*)secTabPtr + i * elf64_header.e_shentsize);
printf("Section[%d]: name %s, sh_addr 0x%lx, sh_offset 0x%lx, sh_size 0x%lx \n",
i, shstrPtr + ptr->sh_name, ptr->sh_addr, ptr->sh_offset, ptr->sh_size);
if (strcmp(shstrPtr + ptr->sh_name, ".text") == 0) texttabIndex = i;
if (strcmp(shstrPtr + ptr->sh_name, ".data") == 0) datatabIndex = i;
if (strcmp(shstrPtr + ptr->sh_name, ".bss") == 0) bsstabIndex = i;
if (strcmp(shstrPtr + ptr->sh_name, ".symtab") == 0) symtabIndex = i;
if (strcmp(shstrPtr + ptr->sh_name, ".strtab") == 0) strtabIndex = i;
}
// 获取段信息
// 2. .strtab 字符串表
printf("\n.strtab 段: \n");
Elf64_Shdr* strtabPtr = (Elf64_Shdr*)((char*)secTabPtr + strtabIndex * elf64_header.e_shentsize);
Elf64_Off strtab_offset = strtabPtr->sh_offset;
Elf64_Xword strtab_size = strtabPtr->sh_size;
char* strtab_buf = (char*)malloc(strtab_size);
memcpy((void*)strtab_buf, buf + strtab_offset, strtab_size);
for (int i = 0; i < sh_size; i++) printf("%c", strtab_buf[i]);
printf("\n");
// 3. 解析 .symtab 符号表
Elf64_Shdr* symtabPtr = (Elf64_Shdr*)((char*)secTabPtr + symtabIndex * elf64_header.e_shentsize);
Elf64_Off symtab_offset = symtabPtr->sh_offset;
Elf64_Xword symtab_size = symtabPtr->sh_size;
int sym_count = symtab_size / sizeof(Elf64_Sym);
char* symtab_buf = (char*)malloc(symtab_size);
memcpy((void*)symtab_buf, buf + symtab_offset, symtab_size);
printf("symtab offset 0x%lx, size 0x%lx, sizeof Elf64_Sym %ld \n", symtab_offset, symtab_size, sizeof(Elf64_Sym));
for (int i = 0; i < sym_count; i++) {
Elf64_Sym* ptr = (Elf64_Sym*)((char*)symtab_buf + i * sizeof(Elf64_Sym));
// st_value 是在 st_shndx 段内的偏移量
printf("symtab [%d] name %s, st_value 0x%lx, st_size 0x%lx, sec index %d \n",
i, strtab_buf + ptr->st_name, ptr->st_value, ptr->st_size, ptr->st_shndx);
}
printf("\n");
// free
free(shstrPtr);
free(secTabPtr);
free(buf);
printf("END \n");
return 0;
}
解析 ELF 文件
最新推荐文章于 2024-09-12 15:39:41 发布