📄 elf.cpp
字号:
_segments.push_back(s); } else { warn << "Failed to init segment\n"; } } return !_segments.empty();}// ------------------------------------------------------------/*typedef struct{ Elf32_Word p_type; // Segment type Elf32_Off p_offset; // Segment file offset Elf32_Addr p_vaddr; // Segment virtual address Elf32_Addr p_paddr; // Segment physical address Elf32_Word p_filesz; // Segment size in file Elf32_Word p_memsz; // Segment size in memory Elf32_Word p_flags; // Segment flags Elf32_Word p_align; // Segment alignment} Elf32_Phdr;*/bool Segment::init(const string &buffer){ switch (buffer.size()) { case sizeof(Elf32_Phdr): _segstruct.reset(new SegmentStruct<Elf32_Phdr>(buffer)); break; case sizeof(Elf64_Phdr): _segstruct.reset(new SegmentStruct<Elf64_Phdr>(buffer)); break; default: warn << "Invalid segment size: " << buffer.size(); return false; break; } _mem_range.reset(new Range(_segstruct->vaddr(), _segstruct->vaddr() + _segstruct->memsz())); _file_range.reset(new Range(_segstruct->offset(), _segstruct->offset() + _segstruct->filesz())); return true;}Address Segment::offset(){ return _segstruct->offset();}Address Segment::align(){ return _segstruct->align();}RangePtr Segment::mem_range(){ return _mem_range;}RangePtr Segment::file_range(){ return _file_range;}bool Segment::is_load(){ return _segstruct->type() == PT_LOAD;}bool Segment::is_readable(){ return flag_is_set(PF_R);}bool Segment::is_writable(){ return flag_is_set(PF_W);}bool Segment::is_executable(){ return flag_is_set(PF_X);}bool Segment::flag_is_set(int flag){ return _segstruct->flags() & flag;}// ------------------------------------------------------------/*typedef struct{ Elf32_Word sh_name; // Section name (string tbl index) Elf32_Word sh_type; // Section type Elf32_Word sh_flags; // Section flags Elf32_Addr sh_addr; // Section virtual addr at execution Elf32_Off sh_offset; // Section file offset Elf32_Word sh_size; // Section size in bytes Elf32_Word sh_link; // Link to another section Elf32_Word sh_info; // Additional section information Elf32_Word sh_addralign; // Section alignment Elf32_Word sh_entsize; // Entry size if section holds table} Elf32_Shdr;*/bool Section::init(const string &buffer){ switch (buffer.size()) { case sizeof(Elf32_Shdr): _sectstruct.reset(new SectionStruct<Elf32_Shdr>(buffer)); break; case sizeof(Elf64_Shdr): _sectstruct.reset(new SectionStruct<Elf64_Shdr>(buffer)); break; default: warn << "Invalid section size: " << buffer.size(); return false; break; } _file_range.reset(new Range(_sectstruct->offset(), _sectstruct->offset() + _sectstruct->size())); _mem_range.reset(new Range(_sectstruct->addr(), _sectstruct->addr() + _sectstruct->size())); return true;}string Section::name(){ return _name;}bool Section::set_name(istream &is, const SectionPtr &string_table){ int name_index = _sectstruct->name(); _name = string_table->find_string(is, name_index); return is.good();}RangePtr Section::file_range(){ return _file_range;}RangePtr Section::mem_range(){ return _mem_range;}bool Section::is_null(){ return _sectstruct->type() == SHT_NULL;}bool Section::is_string_table(){ return _sectstruct->type() == SHT_STRTAB;}bool Section::is_symbol_table(){ return _sectstruct->type() == SHT_SYMTAB;}bool Section::is_nobits(){ return _sectstruct->type() == SHT_NOBITS;}std::string Section::find_string(istream &is, int index){ if (!is_string_table() || index < 0) { return false; } int offset = _sectstruct->offset() + index; is.seekg(offset, ios_base::beg); // Symbols are null-terminated. const int MAX_SYMBOL_SIZE = 1024; char *buf = (char *)alloca(MAX_SYMBOL_SIZE); is.getline(buf, MAX_SYMBOL_SIZE, '\0'); string result(buf); if (!is) { result.clear(); } return result;}std::list<SymbolPtr> Section::symbols(){ return _symbols;}std::list<SymbolPtr> Section::find_symbols_in_mem_range(const RangePtr &mrange){ list<SymbolPtr> result; list<SymbolPtr>::iterator it; for (it = _symbols.begin(); it != _symbols.end(); ++it) { if ((*it)->is_defined() && mrange->overlaps(*(*it)->range())) { result.push_back(*it); } } return result;}unsigned long Section::addr(){ return _sectstruct->addr();}unsigned long Section::link(){ return _sectstruct->link();}unsigned long Section::size(){ return _sectstruct->size();}bool Section::load_symbols(std::istream &is, const SectionPtr &string_table){ if (!is_symbol_table()) { return false; } unsigned int symentry_size = _sectstruct->entsize(); if (symentry_size <= 0) { warn << "Invalid symbol entry table size " << symentry_size << "\n"; return false; } int total_size = _sectstruct->size(); if (total_size % symentry_size != 0) { warn << "Section::load_symbols - size mismatch " << symentry_size << ", " << total_size << "\n"; return false; } list<string> entries; if (!load_table(is, "symbol table", _sectstruct->offset(), (total_size / symentry_size), symentry_size, entries) || entries.empty()) { return false; } _symbols.clear(); list<string>::iterator it; for(it = entries.begin(); it != entries.end(); ++it) { SymbolPtr symbol(new Symbol); if (symbol->init(*it)) { symbol->set_name(is, string_table); _symbols.push_back(symbol); } else { warn << "Failed to init symbol from buffer\n"; } } return true;} // ------------------------------------------------------------bool Symbol::init(const string &buffer){ switch (buffer.size()) { case sizeof(Elf32_Sym): _symstruct.reset(new SymbolStruct<Elf32_Sym>(buffer)); break; case sizeof(Elf64_Sym): _symstruct.reset(new SymbolStruct<Elf64_Sym>(buffer)); break; default: warn << "Invalid symbol size: " << buffer.size() << "\n"; return false; break; } _range.reset(new Range(_symstruct->value(), _symstruct->value() + _symstruct->size())); return true;}bool Symbol::set_name(istream &is, const SectionPtr &string_table){ int name_index = _symstruct->name(); _name = string_table->find_string(is, name_index); return is.good();}string Symbol::name(){ return _name;}int Symbol::size(){ return _symstruct->size();}RangePtr Symbol::range(){ return _range;}bool Symbol::is_defined(){ return _symstruct->value() != 0 && !_name.empty();}int Symbol::type(){ return _symstruct->info() & 0xf;}bool Symbol::is_func(){ return type() == STT_FUNC;}bool Symbol::is_data(){ return type() == STT_OBJECT;}bool Symbol::is_file(){ return type() == STT_FILE;}bool Symbol::is_section(){ return type() == STT_SECTION;}// ------------------------------------------------------------bool load_table(istream &is, const std::string &table_name, unsigned long offset, short num_chunks, short chunksize, list<string> &entries){ entries.clear(); if (offset == 0) { warn << "No " << table_name << " present\n"; return false; } if (num_chunks < 1) { warn << "Invalid number of chunks " << num_chunks << " in " << table_name << "\n"; return false; } is.seekg(offset, ios_base::beg); if (!is.good()) { warn << "Can't seek to offset: " << offset << "\n"; return false; } unsigned long read_size = num_chunks * chunksize; char *buffer = (char *) alloca(read_size); is.read(buffer, read_size); if (!is.good()) { warn << "Can't read " << read_size << " bytes\n"; return false; } for (unsigned int i = 0; i < read_size; i += chunksize) { string s(buffer + i, chunksize); entries.push_back(s); } return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -