mirror of
https://github.com/QuasarApp/LIEF.git
synced 2025-05-11 11:09:32 +00:00
Resolve #551
This commit is contained in:
parent
980ed6b3fb
commit
9fb11539da
api/python/PE/objects
doc/sphinx
include/LIEF
src
tests/pe
@ -105,6 +105,10 @@ void create<Section>(py::module& m) {
|
||||
&Section::characteristics_list,
|
||||
":attr:`~lief.PE.Section.characteristics` as a ``list``")
|
||||
|
||||
.def_property_readonly("fullname",
|
||||
&Section::fullname,
|
||||
"Return the **fullname** of the section including the trailing bytes")
|
||||
|
||||
.def("has_characteristic",
|
||||
&Section::has_characteristic,
|
||||
"``True`` if the a section has the given " RST_CLASS_REF(lief.PE.SECTION_CHARACTERISTICS) "",
|
||||
|
@ -1,6 +1,13 @@
|
||||
Changelog
|
||||
=========
|
||||
|
||||
0.11.2 - February 24, 2021
|
||||
--------------------------
|
||||
|
||||
:PE:
|
||||
* Fix regression in the behavior of the PE section's name. One can now access the full
|
||||
section's name (with trailing bytes) through :attr:`lief.PE.Section.fullname` (see: :issue:`551`)
|
||||
|
||||
.. _release-0111:
|
||||
|
||||
0.11.1 - February 22, 2021
|
||||
|
@ -38,7 +38,7 @@ class LIEF_API Section : public Object {
|
||||
Section(const Section&);
|
||||
|
||||
//! @brief section's name
|
||||
virtual const std::string& name(void) const;
|
||||
virtual std::string name(void) const;
|
||||
|
||||
//! @brief section's content
|
||||
virtual std::vector<uint8_t> content(void) const;
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
#include <functional>
|
||||
|
||||
#include "LIEF/visibility.h"
|
||||
#include "LIEF/iostream.hpp"
|
||||
@ -103,6 +104,7 @@ class LIEF_API Builder {
|
||||
|
||||
template<typename T, typename HANDLER>
|
||||
std::vector<std::string> optimize(const HANDLER& e,
|
||||
std::function<std::string(const typename HANDLER::value_type)> getter,
|
||||
std::unordered_map<std::string, size_t> *of_map_p=nullptr);
|
||||
|
||||
template<typename ELF_T>
|
||||
|
@ -71,6 +71,11 @@ class LIEF_API Section : public LIEF::Section {
|
||||
uint16_t numberof_line_numbers(void) const;
|
||||
uint32_t characteristics(void) const;
|
||||
|
||||
//! Return the **fullname** of the section including the trailing bytes
|
||||
inline const std::string& fullname() const {
|
||||
return this->name_;
|
||||
}
|
||||
|
||||
bool is_type(PE_SECTION_TYPES type) const;
|
||||
const std::set<PE_SECTION_TYPES>& types(void) const;
|
||||
bool has_characteristic(SECTION_CHARACTERISTICS c) const;
|
||||
|
@ -48,8 +48,8 @@ Section::~Section(void) = default;
|
||||
Section& Section::operator=(const Section&) = default;
|
||||
Section::Section(const Section&) = default;
|
||||
|
||||
const std::string& Section::name(void) const {
|
||||
return this->name_;
|
||||
std::string Section::name(void) const {
|
||||
return this->name_.c_str();
|
||||
}
|
||||
|
||||
|
||||
|
@ -164,6 +164,7 @@ void Builder::build(void) {
|
||||
|
||||
template<typename T, typename HANDLER>
|
||||
std::vector<std::string> Builder::optimize(const HANDLER& container,
|
||||
std::function<std::string(const typename HANDLER::value_type)> getter,
|
||||
std::unordered_map<std::string, size_t> *of_map_p) {
|
||||
|
||||
std::set<std::string> string_table;
|
||||
@ -173,12 +174,9 @@ std::vector<std::string> Builder::optimize(const HANDLER& container,
|
||||
// reverse all symbol names and sort them so we can merge then in the linear time:
|
||||
// aaa, aadd, aaaa, cca, ca -> aaaa, aaa, acc, ac ddaa
|
||||
std::transform(
|
||||
std::begin(container),
|
||||
std::end(container),
|
||||
std::inserter(
|
||||
string_table,
|
||||
std::end(string_table)),
|
||||
std::mem_fn(static_cast<const std::string& (T::*)(void) const>(&T::name)));
|
||||
std::begin(container), std::end(container),
|
||||
std::inserter(string_table, std::end(string_table)),
|
||||
getter);
|
||||
|
||||
for (auto &val: string_table) {
|
||||
string_table_optimized.emplace_back(std::move(val));
|
||||
@ -302,7 +300,8 @@ void Builder::build_sections(void) {
|
||||
const Elf_Off section_headers_offset = header.section_headers_offset();
|
||||
|
||||
std::vector<std::string> shstrtab_opt =
|
||||
this->optimize<Section, decltype(this->binary_->sections_)>(this->binary_->sections_);
|
||||
this->optimize<Section, decltype(this->binary_->sections_)>(this->binary_->sections_,
|
||||
[] (const Section* sec) { return sec->name(); });
|
||||
|
||||
// Build section's name
|
||||
std::vector<uint8_t> section_names;
|
||||
@ -528,7 +527,8 @@ void Builder::build_static_symbols(void) {
|
||||
// Container which will hold symbols name (optimized)
|
||||
std::vector<std::string> string_table_optimize =
|
||||
this->optimize<Symbol, decltype(this->binary_->static_symbols_)>(this->binary_->static_symbols_,
|
||||
&offset_name_map);
|
||||
[] (const Symbol* sym) { return sym->name(); },
|
||||
&offset_name_map);
|
||||
|
||||
// We can't start with a symbol name
|
||||
string_table_raw.push_back(0);
|
||||
@ -1131,6 +1131,7 @@ void Builder::build_dynamic_symbols(void) {
|
||||
|
||||
std::vector<std::string> string_table_optimized =
|
||||
this->optimize<Symbol, decltype(this->binary_->dynamic_symbols_)>(this->binary_->dynamic_symbols_,
|
||||
[] (const Symbol* sym) { return sym->name(); },
|
||||
&offset_name_map);
|
||||
|
||||
for (const std::string& name : string_table_optimized) {
|
||||
|
@ -1112,7 +1112,7 @@ std::vector<uint8_t> Binary::authentihash(ALGORITHMS algo) const {
|
||||
|
||||
for (const Section* sec : this->sections_) {
|
||||
std::array<char, 8> name = {0};
|
||||
const std::string& sec_name = sec->name();
|
||||
const std::string& sec_name = sec->fullname();
|
||||
uint32_t name_length = std::min<uint32_t>(sec_name.size() + 1, sizeof(name));
|
||||
std::copy(sec_name.c_str(), sec_name.c_str() + name_length, std::begin(name));
|
||||
ios
|
||||
|
@ -540,10 +540,12 @@ Builder& Builder::operator<<(const Section& section) {
|
||||
header.NumberOfRelocations = static_cast<uint16_t>(section.numberof_relocations());
|
||||
header.NumberOfLineNumbers = static_cast<uint16_t>(section.numberof_line_numbers());
|
||||
header.Characteristics = static_cast<uint32_t>(section.characteristics());
|
||||
const char* name = section.name().c_str();
|
||||
|
||||
uint32_t name_length = std::min<uint32_t>(section.name().size(), sizeof(header.Name));
|
||||
std::copy(name, name + name_length, std::begin(header.Name));
|
||||
std::array<char, 8> name = {0};
|
||||
const std::string& sec_name = section.fullname();
|
||||
uint32_t name_length = std::min<uint32_t>(sec_name.size() + 1, sizeof(name));
|
||||
std::copy(sec_name.c_str(), sec_name.c_str() + name_length, std::begin(header.Name));
|
||||
|
||||
this->ios_.write(reinterpret_cast<uint8_t*>(&header), sizeof(pe_section));
|
||||
|
||||
size_t pad_length = 0;
|
||||
|
@ -129,6 +129,12 @@ class TestPe(TestCase):
|
||||
self.assertEqual(pogo_entries[23].size, 820)
|
||||
|
||||
|
||||
def test_sections(self):
|
||||
path = get_sample("PE/PE32_x86_binary_PGO-LTCG.exe")
|
||||
pe = lief.parse(path)
|
||||
self.assertIsNotNone(pe.get_section(".text"))
|
||||
self.assertEqual(pe.sections[0].name, ".text")
|
||||
self.assertEqual(pe.sections[0].fullname.encode("utf8"), b".text\x00\x00\x00")
|
||||
|
||||
def tearDown(self):
|
||||
# Delete it
|
||||
|
Loading…
x
Reference in New Issue
Block a user