diff --git a/api/python/lief/MachO.pyi b/api/python/lief/MachO.pyi index 672c83954e..5ce9db8b51 100644 --- a/api/python/lief/MachO.pyi +++ b/api/python/lief/MachO.pyi @@ -299,6 +299,10 @@ class Binary(lief.Binary): @property def has_main_command(self) -> bool: ... @property + def has_nx_heap(self) -> bool: ... + @property + def has_nx_stack(self) -> bool: ... + @property def has_rpath(self) -> bool: ... @property def has_segment_split_info(self) -> bool: ... diff --git a/api/python/lief/PE.pyi b/api/python/lief/PE.pyi index e462de6158..4e2a5e66a3 100644 --- a/api/python/lief/PE.pyi +++ b/api/python/lief/PE.pyi @@ -20,6 +20,7 @@ import lief.PE.LoadConfigurationV1 # type: ignore import lief.PE.OptionalHeader # type: ignore import lief.PE.Pogo # type: ignore import lief.PE.Relocation # type: ignore +import lief.PE.RelocationEntry # type: ignore import lief.PE.ResourceDialog # type: ignore import lief.PE.ResourceNode # type: ignore import lief.PE.ResourcesManager # type: ignore @@ -1470,33 +1471,6 @@ class PogoEntry(lief.Object): def __init__(self) -> None: ... def copy(self) -> lief.PE.PogoEntry: ... -class RELOCATIONS_BASE_TYPES: - ABSOLUTE: ClassVar[RELOCATIONS_BASE_TYPES] = ... - ARM_MOV32: ClassVar[RELOCATIONS_BASE_TYPES] = ... - ARM_MOV32A: ClassVar[RELOCATIONS_BASE_TYPES] = ... - ARM_MOV32T: ClassVar[RELOCATIONS_BASE_TYPES] = ... - DIR64: ClassVar[RELOCATIONS_BASE_TYPES] = ... - HIGH: ClassVar[RELOCATIONS_BASE_TYPES] = ... - HIGH3ADJ: ClassVar[RELOCATIONS_BASE_TYPES] = ... - HIGHADJ: ClassVar[RELOCATIONS_BASE_TYPES] = ... - HIGHLOW: ClassVar[RELOCATIONS_BASE_TYPES] = ... - IA64_IMM64: ClassVar[RELOCATIONS_BASE_TYPES] = ... - LOW: ClassVar[RELOCATIONS_BASE_TYPES] = ... - MIPS_JMPADDR: ClassVar[RELOCATIONS_BASE_TYPES] = ... - MIPS_JMPADDR16: ClassVar[RELOCATIONS_BASE_TYPES] = ... - REL: ClassVar[RELOCATIONS_BASE_TYPES] = ... - RISCV_HI20: ClassVar[RELOCATIONS_BASE_TYPES] = ... - RISCV_LOW12I: ClassVar[RELOCATIONS_BASE_TYPES] = ... - RISCV_LOW12S: ClassVar[RELOCATIONS_BASE_TYPES] = ... - SECTION: ClassVar[RELOCATIONS_BASE_TYPES] = ... - THUMB_MOV32: ClassVar[RELOCATIONS_BASE_TYPES] = ... - __name__: Any - def __init__(self, *args, **kwargs) -> None: ... - @staticmethod - def from_value(arg: int, /) -> lief.PE.RELOCATIONS_BASE_TYPES: ... - @property - def value(self) -> int: ... - class RESOURCE_LANGS: AFRIKAANS: ClassVar[RESOURCE_LANGS] = ... ALBANIAN: ClassVar[RESOURCE_LANGS] = ... @@ -1624,9 +1598,36 @@ class Relocation(lief.Object): def entries(self) -> lief.PE.Relocation.it_entries: ... class RelocationEntry(lief.Relocation): + class BASE_TYPES: + ABSOLUTE: ClassVar[RelocationEntry.BASE_TYPES] = ... + ARM_MOV32: ClassVar[RelocationEntry.BASE_TYPES] = ... + ARM_MOV32A: ClassVar[RelocationEntry.BASE_TYPES] = ... + ARM_MOV32T: ClassVar[RelocationEntry.BASE_TYPES] = ... + DIR64: ClassVar[RelocationEntry.BASE_TYPES] = ... + HIGH: ClassVar[RelocationEntry.BASE_TYPES] = ... + HIGH3ADJ: ClassVar[RelocationEntry.BASE_TYPES] = ... + HIGHADJ: ClassVar[RelocationEntry.BASE_TYPES] = ... + HIGHLOW: ClassVar[RelocationEntry.BASE_TYPES] = ... + IA64_IMM64: ClassVar[RelocationEntry.BASE_TYPES] = ... + LOW: ClassVar[RelocationEntry.BASE_TYPES] = ... + MIPS_JMPADDR: ClassVar[RelocationEntry.BASE_TYPES] = ... + MIPS_JMPADDR16: ClassVar[RelocationEntry.BASE_TYPES] = ... + REL: ClassVar[RelocationEntry.BASE_TYPES] = ... + RISCV_HI20: ClassVar[RelocationEntry.BASE_TYPES] = ... + RISCV_LOW12I: ClassVar[RelocationEntry.BASE_TYPES] = ... + RISCV_LOW12S: ClassVar[RelocationEntry.BASE_TYPES] = ... + SECTION: ClassVar[RelocationEntry.BASE_TYPES] = ... + THUMB_MOV32: ClassVar[RelocationEntry.BASE_TYPES] = ... + UNKNOWN: ClassVar[RelocationEntry.BASE_TYPES] = ... + __name__: Any + def __init__(self, *args, **kwargs) -> None: ... + @staticmethod + def from_value(arg: int, /) -> lief.PE.RelocationEntry.BASE_TYPES: ... + @property + def value(self) -> int: ... data: int position: int - type: lief.PE.RELOCATIONS_BASE_TYPES + type: lief.PE.RelocationEntry.BASE_TYPES def __init__(self) -> None: ... class Repro(Debug): diff --git a/api/python/src/PE/enums.cpp b/api/python/src/PE/enums.cpp index ade0562bfe..550d69f9db 100644 --- a/api/python/src/PE/enums.cpp +++ b/api/python/src/PE/enums.cpp @@ -100,28 +100,6 @@ void init_enums(nb::module_& m) { .value(PY_ENUM(SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_WEAK_EXTERNAL)) .value(PY_ENUM(SYMBOL_STORAGE_CLASS::IMAGE_SYM_CLASS_CLR_TOKEN)); - - enum_(m, "RELOCATIONS_BASE_TYPES") - .value("ABSOLUTE", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ABSOLUTE) - .value("HIGH", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH) - .value("LOW", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_LOW) - .value("HIGHLOW", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHLOW) - .value("HIGHADJ", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHADJ) - .value("MIPS_JMPADDR", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_MIPS_JMPADDR) - .value("ARM_MOV32A", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ARM_MOV32A) - .value("ARM_MOV32", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ARM_MOV32) - .value("RISCV_HI20", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_RISCV_HI20) - .value("ARM_MOV32T", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ARM_MOV32T) - .value("THUMB_MOV32", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_THUMB_MOV32) - .value("RISCV_LOW12I", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_RISCV_LOW12I) - .value("RISCV_LOW12S", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_RISCV_LOW12S) - .value("SECTION", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_SECTION) - .value("REL", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_REL) - .value("MIPS_JMPADDR16", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_MIPS_JMPADDR16) - .value("IA64_IMM64", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_IA64_IMM64) - .value("DIR64", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_DIR64) - .value("HIGH3ADJ", RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH3ADJ); - enum_(m, "EXTENDED_WINDOW_STYLES") .value(PY_ENUM(EXTENDED_WINDOW_STYLES::WS_EX_DLGMODALFRAME)) .value(PY_ENUM(EXTENDED_WINDOW_STYLES::WS_EX_NOPARENTNOTIFY)) @@ -143,8 +121,6 @@ void init_enums(nb::module_& m) { .value(PY_ENUM(EXTENDED_WINDOW_STYLES::WS_EX_STATICEDGE)) .value(PY_ENUM(EXTENDED_WINDOW_STYLES::WS_EX_APPWINDOW)); - - enum_(m, "WINDOW_STYLES") .value(PY_ENUM(WINDOW_STYLES::WS_OVERLAPPED)) .value(PY_ENUM(WINDOW_STYLES::WS_POPUP)) diff --git a/api/python/src/PE/objects/pyRelocationEntry.cpp b/api/python/src/PE/objects/pyRelocationEntry.cpp index 126aa01cbf..6c1ebfd4f6 100644 --- a/api/python/src/PE/objects/pyRelocationEntry.cpp +++ b/api/python/src/PE/objects/pyRelocationEntry.cpp @@ -17,6 +17,8 @@ #include "LIEF/PE/RelocationEntry.hpp" +#include "enums_wrapper.hpp" + #include #include #include @@ -25,14 +27,39 @@ namespace LIEF::PE::py { template<> void create(nb::module_& m) { - nb::class_(m, "RelocationEntry", + nb::class_ entry(m, "RelocationEntry", R"delim( Class which represents an entry of the PE relocation table. - It extends the :class:`lief.Relocation` object to provide an uniform API across the file formats - )delim"_doc) - .def(nb::init<>()) + It extends the :class:`lief.Relocation` object to provide an uniform API across the file formats. + )delim"_doc); + #define ENTRY(X) .value(to_string(RelocationEntry::BASE_TYPES::X), RelocationEntry::BASE_TYPES::X) + enum_(entry, "BASE_TYPES") + ENTRY(UNKNOWN) + ENTRY(ABSOLUTE) + ENTRY(HIGH) + ENTRY(LOW) + ENTRY(HIGHLOW) + ENTRY(HIGHADJ) + ENTRY(MIPS_JMPADDR) + ENTRY(ARM_MOV32A) + ENTRY(ARM_MOV32) + ENTRY(RISCV_HI20) + ENTRY(SECTION) + ENTRY(REL) + ENTRY(ARM_MOV32T) + ENTRY(THUMB_MOV32) + ENTRY(RISCV_LOW12I) + ENTRY(RISCV_LOW12S) + ENTRY(MIPS_JMPADDR16) + ENTRY(IA64_IMM64) + ENTRY(DIR64) + ENTRY(HIGH3ADJ); + #undef ENTRY + + entry + .def(nb::init<>()) .def_prop_rw("data", nb::overload_cast<>(&RelocationEntry::data, nb::const_), nb::overload_cast(&RelocationEntry::data), @@ -50,8 +77,8 @@ void create(nb::module_& m) { .def_prop_rw("type", nb::overload_cast<>(&RelocationEntry::type, nb::const_), - nb::overload_cast(&RelocationEntry::type), - "Type of the relocation (see: " RST_CLASS_REF(lief.PE.RELOCATIONS_BASE_TYPES) ")"_doc) + nb::overload_cast(&RelocationEntry::type), + "Type of the relocation"_doc) LIEF_DEFAULT_STR(RelocationEntry); } diff --git a/doc/sphinx/api/cpp/pe.rst b/doc/sphinx/api/cpp/pe.rst index f4c7cdb076..d78bab0fc2 100644 --- a/doc/sphinx/api/cpp/pe.rst +++ b/doc/sphinx/api/cpp/pe.rst @@ -639,9 +639,6 @@ Enums .. doxygenenum:: LIEF::PE::SYMBOL_COMPLEX_TYPES :project: lief -.. doxygenenum:: LIEF::PE::RELOCATIONS_BASE_TYPES - :project: lief - .. doxygenenum:: LIEF::PE::RELOCATIONS_I386 :project: lief diff --git a/doc/sphinx/api/python/pe.rst b/doc/sphinx/api/python/pe.rst index b8fb22739c..1fc315890f 100644 --- a/doc/sphinx/api/python/pe.rst +++ b/doc/sphinx/api/python/pe.rst @@ -544,13 +544,6 @@ SYMBOL_STORAGE_CLASS ---------- -RELOCATIONS_BASE_TYPES -~~~~~~~~~~~~~~~~~~~~~~ - -.. autoclass:: lief.PE.RELOCATIONS_BASE_TYPES - ----------- - FIXED_VERSION_FILE_SUB_TYPES ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ diff --git a/include/LIEF/PE/Relocation.hpp b/include/LIEF/PE/Relocation.hpp index 5119857698..d9ec9896e9 100644 --- a/include/LIEF/PE/Relocation.hpp +++ b/include/LIEF/PE/Relocation.hpp @@ -23,13 +23,9 @@ #include "LIEF/visibility.h" #include "LIEF/iterators.hpp" -#include "LIEF/PE/enums.hpp" - namespace LIEF { namespace PE { -class Parser; -class Builder; class RelocationEntry; namespace details { @@ -37,9 +33,8 @@ struct pe_base_relocation_block; } //! Class which represents the *Base Relocation Block* -//! Usually, we find this structure in the ``.reloc`` section +//! We usually find this structure in the ``.reloc`` section class LIEF_API Relocation : public Object { - friend class Parser; friend class Builder; @@ -48,27 +43,39 @@ class LIEF_API Relocation : public Object { using it_entries = ref_iterator; using it_const_entries = const_ref_iterator; - Relocation(); + Relocation() = default; Relocation(const Relocation& other); Relocation& operator=(Relocation other); Relocation(const details::pe_base_relocation_block& header); - ~Relocation() override; + ~Relocation() override = default; void swap(Relocation& other); //! The RVA for which the offset of the relocation entries (RelocationEntry) is added - uint32_t virtual_address() const; + uint32_t virtual_address() const { + return virtual_address_; + } //! The total number of bytes in the base relocation block. //! ``block_size = sizeof(BaseRelocationBlock) + nb_of_relocs * sizeof(uint16_t = RelocationEntry)`` - uint32_t block_size() const; + uint32_t block_size() const { + return block_size_; + } //! Iterator over the RelocationEntry - it_const_entries entries() const; - it_entries entries(); - - void virtual_address(uint32_t virtual_address); - void block_size(uint32_t block_size); + it_const_entries entries() const { + return entries_; + } + it_entries entries() { + return entries_; + } + + void virtual_address(uint32_t virtual_address) { + virtual_address_ = virtual_address; + } + void block_size(uint32_t block_size) { + block_size_ = block_size; + } RelocationEntry& add_entry(const RelocationEntry& entry); diff --git a/include/LIEF/PE/RelocationEntry.hpp b/include/LIEF/PE/RelocationEntry.hpp index 18a08f9866..368c5cdd67 100644 --- a/include/LIEF/PE/RelocationEntry.hpp +++ b/include/LIEF/PE/RelocationEntry.hpp @@ -24,13 +24,11 @@ #include "LIEF/Object.hpp" #include "LIEF/visibility.h" -#include "LIEF/PE/enums.hpp" +#include "LIEF/PE/Header.hpp" namespace LIEF { namespace PE { -class Parser; -class Builder; class Relocation; //! Class which represents an entry of the PE relocation table @@ -43,12 +41,45 @@ class LIEF_API RelocationEntry : public LIEF::Relocation { friend class PE::Relocation; public: - RelocationEntry(); + enum class BASE_TYPES { + UNKNOWN = -1, + + ABSOLUTE = 0, + HIGH = 1, + LOW = 2, + HIGHLOW = 3, + HIGHADJ = 4, + + MIPS_JMPADDR = 5, + ARM_MOV32A = 5 + 0x101, + ARM_MOV32 = 5 + 0x102, + RISCV_HI20 = 5 + 0x103, + + SECTION = 6, + + REL = 7, + ARM_MOV32T = 7 + 0x201, + THUMB_MOV32 = 7 + 0x202, + RISCV_LOW12I = 7 + 0x203, + + RISCV_LOW12S = 8, + + IA64_IMM64 = 9, + MIPS_JMPADDR16 = 9 + 0x300, + + DIR64 = 10, + HIGH3ADJ = 11, + }; + static RelocationEntry from_raw(Header::MACHINE_TYPES arch, uint16_t raw) { + return RelocationEntry(raw, arch); + } + + RelocationEntry() = default; RelocationEntry(const RelocationEntry& other); RelocationEntry& operator=(RelocationEntry other); - RelocationEntry(uint16_t data); - RelocationEntry(uint16_t position, RELOCATIONS_BASE_TYPES type); - ~RelocationEntry() override; + + RelocationEntry(uint16_t position, BASE_TYPES type); + ~RelocationEntry() override = default; void swap(RelocationEntry& other); @@ -68,26 +99,40 @@ class LIEF_API RelocationEntry : public LIEF::Relocation { uint16_t data() const; //! Offset relative to Relocation::virtual_address where the relocation occurs. - uint16_t position() const; + uint16_t position() const { + return position_; + } //! Type of the relocation - RELOCATIONS_BASE_TYPES type() const; + BASE_TYPES type() const { + return type_; + } void data(uint16_t data); - void position(uint16_t position); - void type(RELOCATIONS_BASE_TYPES type); - void accept(Visitor& visitor) const override; + void position(uint16_t position) { + position_ = position; + } + void type(BASE_TYPES type) { + type_ = type; + } + + void accept(Visitor& visitor) const override; LIEF_API friend std::ostream& operator<<(std::ostream& os, const RelocationEntry& entry); private: - uint16_t position_; - RELOCATIONS_BASE_TYPES type_; - PE::Relocation* relocation_{nullptr}; // Used to compute some information + RelocationEntry(uint16_t data, Header::MACHINE_TYPES arch); + + uint16_t position_ = 0; + BASE_TYPES type_ = BASE_TYPES::ABSOLUTE; + Header::MACHINE_TYPES arch_ = Header::MACHINE_TYPES::UNKNOWN; + PE::Relocation* relocation_ = nullptr; // Used to compute some information }; +LIEF_API const char* to_string(RelocationEntry::BASE_TYPES e); + } } #endif diff --git a/include/LIEF/PE/enums.hpp b/include/LIEF/PE/enums.hpp index 8778094b75..322910f562 100644 --- a/include/LIEF/PE/enums.hpp +++ b/include/LIEF/PE/enums.hpp @@ -101,28 +101,6 @@ enum class AuxSymbolType: size_t { }; -enum class RELOCATIONS_BASE_TYPES: size_t { - IMAGE_REL_BASED_ABSOLUTE = 0, - IMAGE_REL_BASED_HIGH = 1, - IMAGE_REL_BASED_LOW = 2, - IMAGE_REL_BASED_HIGHLOW = 3, - IMAGE_REL_BASED_HIGHADJ = 4, - IMAGE_REL_BASED_MIPS_JMPADDR = 5, - IMAGE_REL_BASED_ARM_MOV32A = 5, - IMAGE_REL_BASED_ARM_MOV32 = 5, - IMAGE_REL_BASED_RISCV_HI20 = 5, - IMAGE_REL_BASED_SECTION = 6, - IMAGE_REL_BASED_REL = 7, - IMAGE_REL_BASED_ARM_MOV32T = 7, - IMAGE_REL_BASED_THUMB_MOV32 = 7, - IMAGE_REL_BASED_RISCV_LOW12I = 7, - IMAGE_REL_BASED_RISCV_LOW12S = 8, - IMAGE_REL_BASED_MIPS_JMPADDR16 = 9, - IMAGE_REL_BASED_IA64_IMM64 = 9, - IMAGE_REL_BASED_DIR64 = 10, - IMAGE_REL_BASED_HIGH3ADJ = 11, -}; - enum class RELOCATIONS_I386: size_t { IMAGE_REL_I386_ABSOLUTE = 0x0000, IMAGE_REL_I386_DIR16 = 0x0001, diff --git a/src/PE/EnumToString.cpp b/src/PE/EnumToString.cpp index f9814afd37..561343d084 100644 --- a/src/PE/EnumToString.cpp +++ b/src/PE/EnumToString.cpp @@ -200,33 +200,6 @@ const char* to_string(RELOCATIONS_ARM e) { } -const char* to_string(RELOCATIONS_BASE_TYPES e) { - CONST_MAP(RELOCATIONS_BASE_TYPES, const char*, 19) enumStrings { - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ABSOLUTE, "ABSOLUTE" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH, "HIGH" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_LOW, "LOW" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHLOW, "HIGHLOW" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHADJ, "HIGHADJ" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_MIPS_JMPADDR, "MIPS_JMPADDR | ARM_MOV32A | ARM_MOV32 | RISCV_HI20" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ARM_MOV32A, "MIPS_JMPADDR | ARM_MOV32A | ARM_MOV32 | RISCV_HI20" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ARM_MOV32, "MIPS_JMPADDR | ARM_MOV32A | ARM_MOV32 | RISCV_HI20" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_RISCV_HI20, "MIPS_JMPADDR | ARM_MOV32A | ARM_MOV32 | RISCV_HI20" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_SECTION, "SECTION" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_REL, "REL | ARM_MOV32T | THUMB_MOV32 | RISCV_LOW12I" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ARM_MOV32T, "REL | ARM_MOV32T | THUMB_MOV32 | RISCV_LOW12I" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_THUMB_MOV32, "REL | ARM_MOV32T | THUMB_MOV32 | RISCV_LOW12I" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_RISCV_LOW12I, "REL | ARM_MOV32T | THUMB_MOV32 | RISCV_LOW12I" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_RISCV_LOW12S, "RISCV_LOW12S" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_MIPS_JMPADDR16, "MIPS_JMPADDR16 | IA64_IMM64" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_IA64_IMM64, "MIPS_JMPADDR16 | IA64_IMM64" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_DIR64, "DIR64" }, - { RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH3ADJ, "HIGH3ADJ" }, - }; - - const auto it = enumStrings.find(e); - return it == enumStrings.end() ? "Out of range" : it->second; -} - const char* to_string(EXTENDED_WINDOW_STYLES e) { CONST_MAP(EXTENDED_WINDOW_STYLES, const char*, 17) enumStrings { { EXTENDED_WINDOW_STYLES::WS_EX_DLGMODALFRAME, "DLGMODALFRAME" }, diff --git a/src/PE/Parser.cpp b/src/PE/Parser.cpp index f24af8abe2..2dc96cf84f 100644 --- a/src/PE/Parser.cpp +++ b/src/PE/Parser.cpp @@ -340,7 +340,7 @@ ok_error_t Parser::parse_relocations() { LIEF_ERR("Can't parse relocation entry #{}", i); break; } - auto entry = std::make_unique(*res_entry); + auto entry = std::make_unique(RelocationEntry::from_raw(this->binary_->header().machine(), *res_entry)); entry->relocation_ = relocation.get(); relocation->entries_.push_back(std::move(entry)); } @@ -753,9 +753,10 @@ std::unique_ptr Parser::parse_pogo(const details::pe_debug& debug_info) { std::unique_ptr Parser::parse_repro(const details::pe_debug& debug_info) { LIEF_DEBUG("Parsing Debug Repro"); - const uint32_t debug_size = debug_info.SizeOfData; const uint32_t debug_off = debug_info.PointerToRawData; - const uint32_t debug_end = debug_off + debug_size; + + /* const uint32_t debug_size = debug_info.SizeOfData; */ + /* const uint32_t debug_end = debug_off + debug_size; */ ScopedStream sscoped(*stream_, debug_off); auto res_size = sscoped->read(); diff --git a/src/PE/Relocation.cpp b/src/PE/Relocation.cpp index 8e676da386..3526a95e3b 100644 --- a/src/PE/Relocation.cpp +++ b/src/PE/Relocation.cpp @@ -13,19 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include - -#include "LIEF/PE/hash.hpp" +#include "LIEF/Visitor.hpp" #include "PE/Structures.hpp" #include "LIEF/PE/Relocation.hpp" #include "LIEF/PE/RelocationEntry.hpp" +#include + namespace LIEF { namespace PE { -Relocation::~Relocation() = default; - Relocation::Relocation(const Relocation& other) : Object{other}, block_size_{other.block_size_}, @@ -37,7 +35,6 @@ Relocation::Relocation(const Relocation& other) : copy->relocation_ = this; entries_.push_back(std::move(copy)); } - } Relocation& Relocation::operator=(Relocation other) { @@ -45,13 +42,6 @@ Relocation& Relocation::operator=(Relocation other) { return *this; } - - - -Relocation::Relocation() = default; - - - Relocation::Relocation(const details::pe_base_relocation_block& header) : block_size_{header.BlockSize}, virtual_address_{header.PageRVA} @@ -64,27 +54,6 @@ void Relocation::swap(Relocation& other) { std::swap(entries_, other.entries_); } - -uint32_t Relocation::virtual_address() const { - return virtual_address_; -} - - -uint32_t Relocation::block_size() const { - return block_size_; -} - -Relocation::it_const_entries Relocation::entries() const { - return entries_; -} - - -Relocation::it_entries Relocation::entries() { - return entries_; -} - - - RelocationEntry& Relocation::add_entry(const RelocationEntry& entry) { auto newone = std::make_unique(entry); newone->relocation_ = this; @@ -92,29 +61,16 @@ RelocationEntry& Relocation::add_entry(const RelocationEntry& entry) { return *entries_.back(); } - -void Relocation::virtual_address(uint32_t virtual_address) { - virtual_address_ = virtual_address; -} - - -void Relocation::block_size(uint32_t block_size) { - block_size_ = block_size; -} - - void Relocation::accept(LIEF::Visitor& visitor) const { visitor.visit(*this); } std::ostream& operator<<(std::ostream& os, const Relocation& relocation) { + os << fmt::format("0x{:06x} 0x{:06x}\n", relocation.virtual_address(), + relocation.block_size()); - os << std::hex << std::left; - os << std::setw(10) << relocation.virtual_address(); - os << std::setw(10) << relocation.block_size(); - os << std::endl; for (const RelocationEntry& entry : relocation.entries()) { - os << " - " << entry << std::endl; + os << " - " << entry << '\n'; } return os; diff --git a/src/PE/RelocationEntry.cpp b/src/PE/RelocationEntry.cpp index 27bfcbfd5e..fea85dbd95 100644 --- a/src/PE/RelocationEntry.cpp +++ b/src/PE/RelocationEntry.cpp @@ -13,16 +13,17 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include - #include "logging.hpp" -#include "LIEF/PE/hash.hpp" +#include "LIEF/Visitor.hpp" #include "LIEF/PE/RelocationEntry.hpp" #include "LIEF/PE/Relocation.hpp" -#include "LIEF/PE/EnumToString.hpp" +#include "frozen.hpp" +#include "fmt_formatter.hpp" + +FMT_FORMATTER(LIEF::PE::RelocationEntry::BASE_TYPES, LIEF::PE::to_string); namespace LIEF { namespace PE { @@ -30,71 +31,38 @@ namespace PE { RelocationEntry::RelocationEntry(const RelocationEntry& other) : LIEF::Relocation{other}, position_{other.position_}, - type_{other.type_} + type_{other.type_}, + arch_{other.arch_}, + relocation_{nullptr} {} -RelocationEntry& RelocationEntry::operator=(RelocationEntry other) { - swap(other); - return *this; +RelocationEntry::RelocationEntry(uint16_t data, Header::MACHINE_TYPES arch) : + arch_(arch) +{ + this->data(data); } -RelocationEntry::~RelocationEntry() = default; - -RelocationEntry::RelocationEntry() : - position_{0}, - type_{RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ABSOLUTE} -{} - -RelocationEntry::RelocationEntry(uint16_t data) : - position_{static_cast(data & 0x0FFF)}, - type_{static_cast(data >> 12)} -{} - - -RelocationEntry::RelocationEntry(uint16_t position, RELOCATIONS_BASE_TYPES type) : - position_{position}, - type_{type} -{} - - void RelocationEntry::swap(RelocationEntry& other) { LIEF::Relocation::swap(other); std::swap(position_, other.position_); std::swap(type_, other.type_); std::swap(relocation_, other.relocation_); + std::swap(arch_, other.arch_); } uint16_t RelocationEntry::data() const { - return (static_cast(type_) << 12 | static_cast(position_)); -} - - -uint16_t RelocationEntry::position() const { - return position_; -} - - -RELOCATIONS_BASE_TYPES RelocationEntry::type() const { - return type_; + auto raw_type = uint8_t(uint32_t(type_) & 0xFF); + return (uint16_t(raw_type) << 12 | uint16_t(position_)); } void RelocationEntry::data(uint16_t data) { position_ = static_cast(data & 0x0FFF); - type_ = static_cast(data >> 12); + auto raw_type = uint8_t(data >> 12); + // TODO(romain): Support arch-dependent types (ARM_MOV32A, RISCV_LOW12I, ...) + type_ = BASE_TYPES(raw_type); } -void RelocationEntry::position(uint16_t position) { - position_ = position; -} - - -void RelocationEntry::type(RELOCATIONS_BASE_TYPES type) { - type_ = type; -} - - - uint64_t RelocationEntry::address() const { if (relocation_ != nullptr) { return relocation_->virtual_address() + position(); @@ -109,23 +77,23 @@ void RelocationEntry::address(uint64_t /*address*/) { size_t RelocationEntry::size() const { switch (type()) { - case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_LOW: - case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGH: - case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHADJ: + case BASE_TYPES::LOW: + case BASE_TYPES::HIGH: + case BASE_TYPES::HIGHADJ: { return 16; } - case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_HIGHLOW: // Addr += delta + case BASE_TYPES::HIGHLOW: // Addr += delta { return 32; } - case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_DIR64: // Addr += delta + case BASE_TYPES::DIR64: // Addr += delta { return 64; } - case RELOCATIONS_BASE_TYPES::IMAGE_REL_BASED_ABSOLUTE: + case BASE_TYPES::ABSOLUTE: default: { return 0; @@ -133,25 +101,53 @@ size_t RelocationEntry::size() const { } return 0; } -void RelocationEntry::size(size_t /*size*/) { - LIEF_WARN("Setting size of a PE relocation is not implemented!"); +void RelocationEntry::size(size_t /*size*/) { + LIEF_WARN("Setting size of a PE relocation is not supported!"); } void RelocationEntry::accept(Visitor& visitor) const { visitor.visit(*this); } - - std::ostream& operator<<(std::ostream& os, const RelocationEntry& entry) { - os << std::hex << std::left; - os << std::setw(10) << to_string(entry.type()); - os << std::setw(6) << static_cast(entry.position()); - + os << fmt::format("{}: 0x{:04x}", entry.type(), entry.position()); return os; +} + +const char* to_string(RelocationEntry::BASE_TYPES type) { + #define ENTRY(X) std::pair(RelocationEntry::BASE_TYPES::X, #X) + STRING_MAP enums2str { + ENTRY(UNKNOWN), + ENTRY(ABSOLUTE), + ENTRY(HIGH), + ENTRY(LOW), + ENTRY(HIGHLOW), + ENTRY(HIGHADJ), + ENTRY(MIPS_JMPADDR), + ENTRY(ARM_MOV32A), + ENTRY(ARM_MOV32), + ENTRY(RISCV_HI20), + ENTRY(SECTION), + ENTRY(REL), + ENTRY(ARM_MOV32T), + ENTRY(THUMB_MOV32), + ENTRY(RISCV_LOW12I), + ENTRY(RISCV_LOW12S), + ENTRY(MIPS_JMPADDR16), + ENTRY(IA64_IMM64), + ENTRY(DIR64), + ENTRY(HIGH3ADJ), + }; + #undef ENTRY + + if (auto it = enums2str.find(type); it != enums2str.end()) { + return it->second; + } + return "UNKNOWN"; } + } } diff --git a/tests/pe/test_parser.py b/tests/pe/test_parser.py index c3b2b461da..63e94fd68b 100644 --- a/tests/pe/test_parser.py +++ b/tests/pe/test_parser.py @@ -437,16 +437,16 @@ def test_relocations(): assert relocation.entries[46].address == 0xdeb8 assert relocation.entries[46].data == 0xaeb8 assert relocation.entries[46].position == 0xeb8 - assert relocation.entries[46].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[46].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[25].data == 0xae10 assert relocation.entries[25].position == 0xe10 - assert relocation.entries[25].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[25].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[56].data == 0xaf08 assert relocation.entries[56].position == 0xf08 - assert relocation.entries[56].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[56].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[75].data == 0xafa0 assert relocation.entries[75].position == 0xfa0 - assert relocation.entries[75].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[75].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocations[8].virtual_address == 0x15000 assert relocations[8].block_size == 0xc0 @@ -454,16 +454,16 @@ def test_relocations(): relocation = relocations[8] assert relocation.entries[87].data == 0xa9f8 assert relocation.entries[87].position == 0x9f8 - assert relocation.entries[87].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[87].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[24].data == 0xa0c0 assert relocation.entries[24].position == 0xc0 - assert relocation.entries[24].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[24].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[67].data == 0xa218 assert relocation.entries[67].position == 0x218 - assert relocation.entries[67].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[67].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[54].data == 0xa1b0 assert relocation.entries[54].position == 0x1b0 - assert relocation.entries[54].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[54].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocations[9].virtual_address == 0x1c000 assert relocations[9].block_size == 0x80 @@ -471,30 +471,30 @@ def test_relocations(): relocation = relocations[9] assert relocation.entries[40].data == 0xa628 assert relocation.entries[40].position == 0x628 - assert relocation.entries[40].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[40].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[17].data == 0xa2d8 assert relocation.entries[17].position == 0x2d8 - assert relocation.entries[17].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[17].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[36].data == 0xa5a0 assert relocation.entries[36].position == 0x5a0 - assert relocation.entries[36].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[36].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 assert relocation.entries[52].data == 0xa7f8 assert relocation.entries[52].position == 0x7f8 - assert relocation.entries[52].type == lief.PE.RELOCATIONS_BASE_TYPES.DIR64 + assert relocation.entries[52].type == lief.PE.RelocationEntry.BASE_TYPES.DIR64 r1 = lief.PE.RelocationEntry() r1.position = 0x123 - r1.type = lief.PE.RELOCATIONS_BASE_TYPES.LOW + r1.type = lief.PE.RelocationEntry.BASE_TYPES.LOW assert r1.address == r1.position assert r1.size == 16 r2 = lief.PE.RelocationEntry() - r2.type = lief.PE.RELOCATIONS_BASE_TYPES.HIGHLOW + r2.type = lief.PE.RelocationEntry.BASE_TYPES.HIGHLOW assert r2.size == 32 r3 = lief.PE.RelocationEntry() - r3.type = lief.PE.RELOCATIONS_BASE_TYPES.ABSOLUTE + r3.type = lief.PE.RelocationEntry.BASE_TYPES.ABSOLUTE assert r3.size == 0 r3.data = 0xBAAA assert r3.position == 0xAAA