This commit is contained in:
John Doe
2023-12-08 02:52:18 +00:00
parent 8fdaeaeadc
commit 8c87c67b30
2 changed files with 71 additions and 59 deletions

View File

@@ -5,7 +5,9 @@ OBJECTS=$(SOURCES:.cc=.o)
CFLAGS=-g -O0
INCLUDES=-I/usr/include/elf
LIBS=-lunwind-x86_64 -lunwind -lelf -ldwarf -ldw
LIBS=-lunwind-x86_64 -lunwind -lelf
#-ldwarf -ldw
%.o: %.cc
$(CXX) $(CFLAGS) $(INCLUDES) -c $< -o $@

View File

@@ -8,8 +8,8 @@
#include <sys/utsname.h>
#include <unistd.h>
#include <dwarf.h>
#include <elfutils/libdw.h>
// #include <dwarf.h>
// #include <elfutils/libdw.h>
#define NS_NAME_LEN 128
@@ -81,14 +81,14 @@ static int get_symbols_in_section(sym_section_ctx *sym, Elf *elf, Elf_Scn *sec,
return -1;
}
sym->symstrs = elf_getdata(symstrs_sec, NULL);
sym->symstrs = elf_getdata(symstrs_sec, NULL); // 获取section data
if (!sym->symstrs) {
return -1;
}
sym->sym_count = shdr->sh_size / shdr->sh_entsize;
sym->sym_count = shdr->sh_size / shdr->sh_entsize; // 获取section中的symbol数量
sym->is_plt = 0;
sym->is_reloc = is_reloc;
sym->is_reloc = is_reloc; // 是否是可重定位文件
return 0;
}
@@ -118,7 +118,7 @@ static int get_plt_symbols_in_section(sym_section_ctx *sym, Elf *elf,
sym->is_plt = 1;
sym->plt_entsize = plt->plt.hdr->sh_type;
sym->plt_offset = plt->plt.hdr->sh_offset;
sym->sym_count = plt->plt_rel.hdr->sh_size / plt->plt_rel.hdr->sh_entsize;
sym->sym_count = plt->plt_rel.hdr->sh_size / plt->plt_rel.hdr->sh_entsize; // 获取section中的symbol数量
sym->plt_rel_type = plt->plt_rel.hdr->sh_type;
return 0;
@@ -161,6 +161,7 @@ static void __get_symbol_without_plt(std::set<symbol> &ss, sym_section_ctx *tab,
s.end = s.start + sym.st_size;
s.ip = s.start;
s.name = sym_name;
printf("name: %s, start: %lx, end: %lx\n", s.name.c_str(), s.start, s.end);
ss.insert(s);
}
}
@@ -217,6 +218,7 @@ static void __get_plt_symbol(std::set<symbol> &ss, symbol_sections_ctx *si,
s.end = s.start + si->dynsymtab.plt_entsize;
s.ip = s.start;
s.name = sym_name;
printf("name: %s, start: %lx, end: %lx\n", s.name.c_str(), s.start, s.end);
ss.insert(s);
}
}
@@ -227,44 +229,51 @@ static void get_all_symbols(std::set<symbol> &ss, symbol_sections_ctx *si,
__get_plt_symbol(ss, si, elf);
}
static void get_debug_symbols(std::set<symbol>& ss, Dwarf* dw) {
Dwarf_Off die_offset = 0, next_offset;
size_t header_size;
while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL, NULL) == 0) {
Dwarf_Die cudie;
if (dwarf_offdie(dw, die_offset + header_size, &cudie) == NULL) {
continue;
}
// static void get_debug_symbols(std::set<symbol>& ss, Dwarf* dw) {
// Dwarf_Off die_offset = 0, next_offset;
// size_t header_size;
// printf("1\n");
// while (dwarf_nextcu(dw, die_offset, &next_offset, &header_size, NULL, NULL, NULL) == 0) {
// printf("2\n");
// Dwarf_Die cudie;
// printf("3\n");
// if (dwarf_offdie(dw, die_offset + header_size, &cudie) == NULL) {
// printf("4\n");
// continue;
// }
// printf("4\n");
// Dwarf_Die die;
// if (dwarf_child(&cudie, &die) != 0) {
// printf("5\n");
// continue;
// }
Dwarf_Die die;
if (dwarf_child(&cudie, &die) != 0) {
continue;
}
// do {
// const char* die_name = dwarf_diename(&die);
// printf("6\n");
// if (!die_name) {
// continue;
// }
do {
const char* die_name = dwarf_diename(&die);
if (!die_name) {
continue;
}
// Dwarf_Attribute attr_mem;
// Dwarf_Attribute* attr = dwarf_attr(&die, DW_AT_low_pc, &attr_mem);
// if (attr) {
// Dwarf_Addr low_pc;
// if (dwarf_formaddr(attr, &low_pc) == 0) {
// printf("name: %s, low_pc: %lx\n", die_name, low_pc);
// // symbol s;
// // s.name = die_name;
// // s.start = low_pc;
// // s.end = s.start; // You need to find the high_pc to set the end.
Dwarf_Attribute attr_mem;
Dwarf_Attribute* attr = dwarf_attr(&die, DW_AT_low_pc, &attr_mem);
if (attr) {
Dwarf_Addr low_pc;
if (dwarf_formaddr(attr, &low_pc) == 0) {
symbol s;
s.name = die_name;
s.start = low_pc;
s.end = s.start; // You need to find the high_pc to set the end.
// // ss.insert(s);
// }
// }
// } while (dwarf_siblingof(&die, &die) == 0);
ss.insert(s);
}
}
} while (dwarf_siblingof(&die, &die) == 0);
die_offset = next_offset;
}
}
// die_offset = next_offset;
// }
// }
bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) {
static int first_init = 0;
@@ -276,32 +285,32 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) {
int is_reloc = 0;
elf_version(EV_CURRENT);
int fd = open(path, O_RDONLY);
int fd = open(path, O_RDONLY); // open elf file, read only
Elf *elf = elf_begin(fd, ELF_C_READ, NULL);
Elf *elf = elf_begin(fd, ELF_C_READ, NULL); // 指向elf文件的指针
if (elf == NULL) {
close(fd);
return false;
}
Elf_Kind ek = elf_kind(elf);
Elf_Kind ek = elf_kind(elf); // 获取elf文件类型
if (ek != ELF_K_ELF) {
elf_end(elf);
close(fd);
return false;
}
GElf_Ehdr hdr;
GElf_Ehdr hdr; // elf文件头
if (gelf_getehdr(elf, &hdr) == NULL) {
elf_end(elf);
close(fd);
return false;
}
if (hdr.e_type == ET_EXEC) {
if (hdr.e_type == ET_EXEC) { // 可执行文件
is_reloc = 1;
}
if (!elf_rawdata(elf_getscn(elf, hdr.e_shstrndx), NULL)) {
if (!elf_rawdata(elf_getscn(elf, hdr.e_shstrndx), NULL)) { //
elf_end(elf);
close(fd);
return false;
@@ -323,25 +332,26 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) {
Elf_Scn *symtab_sec = NULL;
Elf_Scn *plt_sec = NULL;
Elf_Scn *plt_rel_sec = NULL;
Elf_Scn *debug_sec = NULL;
// 遍历elf文件的section header table
while ((sec = elf_nextscn(elf, sec)) != NULL) {
char *str;
gelf_getshdr(sec, &shdr);
gelf_getshdr(sec, &shdr); // 获取section header
str = elf_strptr(elf, hdr.e_shstrndx, shdr.sh_name);
if (str && strcmp(".symtab", str) == 0) {
if (str && strcmp(".symtab", str) == 0) { // .symtab section
symtab_sec = sec;
memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr));
memcpy(&symtab_shdr, &shdr, sizeof(dynsym_shdr));
}
if (str && strcmp(".dynsym", str) == 0) {
if (str && strcmp(".dynsym", str) == 0) { // .dynsym section
dynsym_sec = sec;
memcpy(&dynsym_shdr, &shdr, sizeof(dynsym_shdr));
}
if (str && strcmp(".rela.plt", str) == 0) {
if (str && strcmp(".rela.plt", str) == 0) { // .rela.plt section
plt_rel_sec = sec;
memcpy(&plt_rel_shdr, &shdr, sizeof(plt_rel_shdr));
}
if (str && strcmp(".plt", str) == 0) {
if (str && strcmp(".plt", str) == 0) { // .plt section
plt_sec = sec;
memcpy(&plt_shdr, &shdr, sizeof(plt_shdr));
}
@@ -375,11 +385,11 @@ bool get_symbol_from_elf(std::set<symbol> &ss, const char *path) {
elf_end(elf);
// After getting all symbols from .symtab and .dynsym
Dwarf *dw = dwarf_begin(fd, DWARF_C_READ);
if (dw) {
get_debug_symbols(ss, dw);
dwarf_end(dw);
}
// Dwarf *dw = dwarf_begin(fd, DWARF_C_READ);
// if (dw) {
// get_debug_symbols(ss, dw);
// dwarf_end(dw);
// }
close(fd);
return true;