📄 elf.cpp
字号:
/* * (c) John Berthels 2005 <jjberthels@gmail.com>. See COPYING for license. */#include "Elf.hpp"#include <sstream>#include <unistd.h> // getpagesize()using namespace std;using namespace jutil;using namespace Elf;static bool load_table(std::istream &is, const std::string &table_name, unsigned long offset, short num_chunks, short chunksize, std::list<std::string> &entries);int Elf::page_size(){ static int _page_size = 0; if (_page_size == 0) { _page_size = getpagesize(); } return _page_size;}Address Elf::page_align_down(const Address &addr){ return addr & ~(page_size()-1);}Address Elf::page_align_up(const Address &addr){ return page_align_down(addr + page_size() - 1);}// ------------------------------------------------------------File::File() : _lazy_load_sections(false){ }unsigned long File::elf_file_type(){ return _filestruct->type();}bool File::load(const string &fname, bool warn_if_non_elf){ unload(); _fname = fname; if (!is_regular_file(fname)) { return false; } if (!open_file()) { warn << "File::load - can't open file: " << fname << "\n"; return false; } if (!load_file_header()) { if (warn_if_non_elf) { warn << "File::load - failed to load header: " << fname << "\n"; } return false; } if (!load_segments()) { warn << "File::load - failed to load segment info: " << fname << "\n"; return false; } return true;} void File::unload(void){ _lazy_load_sections = false; _ifs.clear(); _ifs.close(); _fname.clear(); _segments.clear(); _sections.clear(); _symbol_table_section.reset(); _filestruct.reset();}list<SymbolPtr> File::find_symbols_in_mem_range(const RangePtr &mrange){ if (!lazy_load_sections() || !_symbol_table_section) { list<SymbolPtr> empty; return empty; } return _symbol_table_section->find_symbols_in_mem_range(mrange);}list<SymbolPtr> File::defined_symbols(){ list<SymbolPtr> syms; list<SymbolPtr> result; list<SymbolPtr>::iterator it; syms = all_symbols(); for (it = syms.begin(); it != syms.end(); ++it) { if ((*it)->is_defined()) { result.push_back(*it); } } return result;}list<SymbolPtr> File::all_symbols(){ if (!lazy_load_sections() || !_symbol_table_section) { list<SymbolPtr> empty; return empty; } return _symbol_table_section->symbols();}SymbolPtr File::symbol(const string &symname){ list<SymbolPtr> syms = all_symbols(); list<SymbolPtr>::iterator it; for (it = syms.begin(); it != syms.end(); ++it) { if ((*it)->name() == symname) { return *it; } } return SymbolPtr((Symbol *) 0);}list<SymbolPtr> File::symbols_in_section(const SectionPtr §ion){ list<SymbolPtr> result; if (!lazy_load_sections() || !section) { list<SymbolPtr> empty; return empty; } return find_symbols_in_mem_range(section->mem_range());}string File::filename(){ return _fname;}int File::num_sections(){ return sections().size();}int File::num_segments(){ return segments().size();}list<SegmentPtr> File::segments(){ return _segments;}list<SegmentPtr> File::loadable_segments(){ list<SegmentPtr> result; list<SegmentPtr>::iterator it; for (it = _segments.begin(); it != _segments.end(); ++it) { if ((*it)->is_load()) { result.push_back(*it); } } return result;}SectionPtr File::section(int i){ list<SectionPtr>::iterator it; if (lazy_load_sections()) { for (it = _sections.begin(); it != _sections.end(); ++it) { if (i-- == 0) { return *it; } } } return SectionPtr((Section *) 0);}SectionPtr File::section(const string &name){ list<SectionPtr>::iterator it; if (lazy_load_sections()) { for (it = _sections.begin(); it != _sections.end(); ++it) { if ((*it)->name() == name) { return *it; } } } return SectionPtr((Section *) 0);}list<SectionPtr> File::mappable_sections(){ list<SectionPtr> result; list<SectionPtr>::iterator it; if (!lazy_load_sections()) { list<SectionPtr> empty; return empty; } for (it = _sections.begin(); it != _sections.end(); ++it) { if ((*it)->addr() != 0) { result.push_back(*it); } } return result;}list<SectionPtr> File::sections(){ if (!lazy_load_sections()) { list<SectionPtr> empty; return empty; } return _sections;}bool File::is_executable(){ return elf_file_type() == ET_EXEC;}bool File::is_shared_object(){ return elf_file_type() == ET_DYN;}bool File::lazy_load_sections(){ // Stop possible recursion if (_lazy_load_sections) { return true; } _lazy_load_sections = true; if (!load_sections()) { return false; } return correlate_string_sections();}bool File::open_file(){ uid_t new_euid = 0, orig_euid = 0; // If we are root, become the file owner. Otherwise, we might not // be able to open the file (e.g. a file on an NFS mount with root // squash). orig_euid = geteuid(); if (orig_euid == 0 && file_owner(_fname, new_euid) && new_euid != 0) { seteuid(new_euid); } if (_ifs.is_open()) { _ifs.close(); } _ifs.clear(); _ifs.open(_fname.c_str()); if (!_ifs.is_open()) { warn << "Can't open file: " << _fname << "\n"; } if (new_euid != 0) { seteuid(orig_euid); // ok, it will always be 0... } return _ifs.is_open();}bool File::correlate_string_sections(){ list<SectionPtr>::iterator it; SectionPtr string_table; int string_table_index = _filestruct->shstrndx(); if (string_table_index >= num_sections()) { warn << "correlate_string_sections - invalid string index\n"; return false; } string_table = section(string_table_index); if (!string_table->is_string_table()) { warn << "correlate_string_sections - invalid string section\n"; return false; } for (it = _sections.begin(); it != _sections.end(); ++it) { (*it)->set_name(_ifs, string_table); if ((*it)->is_symbol_table()) { _symbol_table_section = *it; SectionPtr string_table = section((*it)->link()); (*it)->load_symbols(_ifs, string_table); } } return true;}bool File::load_file_header(){ char ident_buf[EI_NIDENT]; memset(ident_buf, '\0', sizeof(ident_buf)); binary_read(_ifs, ident_buf); _ifs.clear(); _ifs.seekg(0, ios::beg); if (memcmp(ident_buf, "\x7f\x45\x4c\x46", 4) != 0) { /* Not an ELF file */ return false; } char e_class = ident_buf[EI_CLASS]; switch (e_class) { case ELFCLASS32: _filestruct.reset(new FileStruct<Elf32_Ehdr>(_ifs)); break; case ELFCLASS64: _filestruct.reset(new FileStruct<Elf64_Ehdr>(_ifs)); break; default: warn << "Unrecognised ELF class: " << e_class << "\n"; return false; break; } return _ifs.good();}bool File::load_sections(){ list<string> entries; list<string>::iterator it; if (!load_table(_ifs, "section header table", _filestruct->shoff(), _filestruct->shnum(), _filestruct->shentsize(), entries) || entries.empty()) { return false; } for (it = entries.begin(); it != entries.end(); ++it) { SectionPtr s(new Section); if (s->init(*it)) { _sections.push_back(s); } else { warn << "Failed to init section\n"; } } return !_sections.empty();}bool File::load_segments(){ list<string> entries; list<string>::iterator it; if (!load_table(_ifs, "segment header table", _filestruct->phoff(), _filestruct->phnum(), _filestruct->phentsize(), entries) || entries.empty()) { return false; } for (it = entries.begin(); it != entries.end(); ++it) { SegmentPtr s(new Segment); if (s->init(*it)) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -