diff --git a/DEPENDENCIES b/DEPENDENCIES index a9030fa..f49fcdf 100644 --- a/DEPENDENCIES +++ b/DEPENDENCIES @@ -1,2 +1,2 @@ -lief https://github.com/lief-project/LIEF/ 9cf3b56cf004407c56695a61688ecc8ac511ef0e +lief https://github.com/lief-project/LIEF/ b183666a082d19ffc91ed0763f49e1d4f3814a59 vendorpull https://github.com/jviotti/vendorpull 8445d0d0b15d308906ee395cc3313cba461865c4 diff --git a/vendor/lief/CMakeLists.txt b/vendor/lief/CMakeLists.txt index 63052ab..551e8f7 100644 --- a/vendor/lief/CMakeLists.txt +++ b/vendor/lief/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required(VERSION 3.5) +# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + cmake_policy(SET CMP0135 NEW) +endif() + set_property(GLOBAL PROPERTY USE_FOLDERS ON) # Modules @@ -464,15 +469,6 @@ endif() target_compile_definitions(LIB_LIEF PUBLIC -D_GLIBCXX_USE_CXX11_ABI=1) -# Enable support for MD2 and MD4 for parsing the Authenticode sigs of older -# executables. Also, some older signed executables use certs with the -# SpcSpAgencyInfo Critical Extension, which mbed TLS doesn't support, so set -# MBEDTLS_X509_ALLOW_UNSUPPORTED_CRITICAL_EXTENSION to have it skip this -# extension. -add_definitions(-DMBEDTLS_FS_IO -DMBEDTLS_PEM_PARSE_C -DMBEDTLS_BIGNUM_C - -DMBEDTLS_X509_CRT_PARSE_C -DMBEDTLS_PEM_WRITE_C - -DMBEDTLS_PKCS1_V15 -DMBEDTLS_PKCS1_V21) - # LIEF Sanitizer options # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ set(SANITIZER_FLAGS -fno-omit-frame-pointer -g -O1) diff --git a/vendor/lief/api/c/MachO/Parser.cpp b/vendor/lief/api/c/MachO/Parser.cpp index 137443d..8f9efbf 100644 --- a/vendor/lief/api/c/MachO/Parser.cpp +++ b/vendor/lief/api/c/MachO/Parser.cpp @@ -25,11 +25,16 @@ using namespace LIEF::MachO; Macho_Binary_t** macho_parse(const char *file) { FatBinary* fat = Parser::parse(file).release(); + if (fat == nullptr) { + return nullptr; + } + + size_t nb_bin = fat->size(); auto** c_macho_binaries = static_cast( malloc((fat->size() + 1) * sizeof(Macho_Binary_t**))); - for (size_t i = 0; i < fat->size(); ++i) { + for (size_t i = 0; i < nb_bin; ++i) { Binary* binary = fat->at(i); if (binary != nullptr) { c_macho_binaries[i] = static_cast(malloc(sizeof(Macho_Binary_t))); @@ -37,7 +42,10 @@ Macho_Binary_t** macho_parse(const char *file) { } } - c_macho_binaries[fat->size()] = nullptr; + fat->release_all_binaries(); + + c_macho_binaries[nb_bin] = nullptr; + delete fat; return c_macho_binaries; } diff --git a/vendor/lief/api/python/CMakeLists.txt b/vendor/lief/api/python/CMakeLists.txt index 11c2de3..2e652c1 100644 --- a/vendor/lief/api/python/CMakeLists.txt +++ b/vendor/lief/api/python/CMakeLists.txt @@ -1,4 +1,10 @@ cmake_minimum_required(VERSION 3.1) + +# Avoid warning about DOWNLOAD_EXTRACT_TIMESTAMP in CMake 3.24: +if (CMAKE_VERSION VERSION_GREATER_EQUAL "3.24.0") + cmake_policy(SET CMP0135 NEW) +endif() + include(ExternalProject) include(CheckCXXCompilerFlag) include(CheckCCompilerFlag) diff --git a/vendor/lief/api/python/DEX/objects/pyType.cpp b/vendor/lief/api/python/DEX/objects/pyType.cpp index e8acbeb..1247c24 100644 --- a/vendor/lief/api/python/DEX/objects/pyType.cpp +++ b/vendor/lief/api/python/DEX/objects/pyType.cpp @@ -73,7 +73,7 @@ void create(py::module& m) { case Type::TYPES::CLASS: { - return py::cast(type.cls()); + return py::cast(type.cls(), py::return_value_policy::reference); } case Type::TYPES::PRIMITIVE: diff --git a/vendor/lief/api/python/ELF/objects/pyBinary.cpp b/vendor/lief/api/python/ELF/objects/pyBinary.cpp index 1f1f42a..9556b80 100644 --- a/vendor/lief/api/python/ELF/objects/pyBinary.cpp +++ b/vendor/lief/api/python/ELF/objects/pyBinary.cpp @@ -500,7 +500,7 @@ void create(py::module& m) { "permutation"_a) .def("write", - &Binary::write, + static_cast(&Binary::write), "Rebuild the binary and write it in a file", "output"_a, py::return_value_policy::reference_internal) diff --git a/vendor/lief/api/python/ELF/objects/pyBuilder.cpp b/vendor/lief/api/python/ELF/objects/pyBuilder.cpp index 089dae2..dd6f75e 100644 --- a/vendor/lief/api/python/ELF/objects/pyBuilder.cpp +++ b/vendor/lief/api/python/ELF/objects/pyBuilder.cpp @@ -68,7 +68,7 @@ void create(py::module& m) { py::return_value_policy::reference_internal) .def("write", - &Builder::write, + static_cast(&Builder::write), "Write the build result into the ``output`` file", "output"_a) diff --git a/vendor/lief/api/python/MachO/objects/pyBinary.cpp b/vendor/lief/api/python/MachO/objects/pyBinary.cpp index 096204c..f05b7f5 100644 --- a/vendor/lief/api/python/MachO/objects/pyBinary.cpp +++ b/vendor/lief/api/python/MachO/objects/pyBinary.cpp @@ -424,7 +424,7 @@ void create(py::module& m) { "address"_a) .def("write", - &Binary::write, + static_cast(&Binary::write), "Rebuild the binary and write and write its content if the file given in parameter", "output"_a, py::return_value_policy::reference_internal) @@ -584,7 +584,9 @@ void create(py::module& m) { py::return_value_policy::reference_internal) .def("shift", - &Binary::shift, + [] (Binary& self, size_t width) { + return error_or(&Binary::shift, self, width); + }, R"delim( Shift the content located right after the Load commands table. This operation can be used to add a new command diff --git a/vendor/lief/api/python/PE/objects/pyBinary.cpp b/vendor/lief/api/python/PE/objects/pyBinary.cpp index 00a543b..1108b1d 100644 --- a/vendor/lief/api/python/PE/objects/pyBinary.cpp +++ b/vendor/lief/api/python/PE/objects/pyBinary.cpp @@ -405,7 +405,7 @@ void create(py::module& m) { "Remove all imported libraries") .def("write", - &Binary::write, + static_cast(&Binary::write), "Build the binary and write the result to the given ``output`` file", "output_path"_a) diff --git a/vendor/lief/api/python/PE/objects/pyBuilder.cpp b/vendor/lief/api/python/PE/objects/pyBuilder.cpp index c022c8a..1f5602f 100644 --- a/vendor/lief/api/python/PE/objects/pyBuilder.cpp +++ b/vendor/lief/api/python/PE/objects/pyBuilder.cpp @@ -94,7 +94,7 @@ void create(py::module& m) { py::return_value_policy::reference) .def("write", - &Builder::write, + static_cast(&Builder::write), "Write the build result into the ``output`` file", "output"_a) diff --git a/vendor/lief/cmake/LIEFOptions.cmake b/vendor/lief/cmake/LIEFOptions.cmake index 14b2b2d..5845edd 100644 --- a/vendor/lief/cmake/LIEFOptions.cmake +++ b/vendor/lief/cmake/LIEFOptions.cmake @@ -34,7 +34,7 @@ cmake_dependent_option(LIEF_OAT "Build LIEF with OAT module" ON "LIEF_ELF;LIEF_DEX" OFF) # VDEX format depends on the DEX module -cmake_dependent_option(LIEF_VDEX "Build LIEF with DEX module" ON +cmake_dependent_option(LIEF_VDEX "Build LIEF with VDEX module" ON "LIEF_DEX" OFF) # Sanitizer diff --git a/vendor/lief/doc/sphinx/changelog.rst b/vendor/lief/doc/sphinx/changelog.rst index 22c5c40..e044752 100644 --- a/vendor/lief/doc/sphinx/changelog.rst +++ b/vendor/lief/doc/sphinx/changelog.rst @@ -6,6 +6,10 @@ Changelog :ELF: + * Fix a heap overflow found by :github_user:`CCWANG19` (:issue:`763`) + * :github_user:`aeflores` fixed an issue when there are multiple versions associated with a symbol + (see: :issue:`749` for the details). + * Handle binaries compiled with the `-static-pie` flag correctly (see: :issue:`747`) * Add support for modifying section-less binaries. The ELF :class:`~lief.ELF.Section` objects gain the :meth:`lief.ELF.Section.as_frame` method which defines the section as a *framed* section. @@ -27,6 +31,7 @@ Changelog :MachO: + * Fix a segfault when the Mach-O binary does not have segments (found by :github_user:`CCWANG19` via :issue:`764`) * Enable to create exports * Fix the layout of the binaries modified by LIEF such as they can be (re)signed. * Add support for `LC_DYLD_CHAINED_FIXUPS` and `LC_DYLD_EXPORTS_TRIE` @@ -56,6 +61,8 @@ Changelog :General Design: + * :github_user:`ZehMatt` added the support to write LIEF binaries object through a `std::ostream` interface + (:commit:`9d55f538602989c69454639565910884c5c5ac7c`) * Remove the exceptions diff --git a/vendor/lief/doc/sphinx/tutorials/03_elf_change_symbols.rst b/vendor/lief/doc/sphinx/tutorials/03_elf_change_symbols.rst index 532d76c..96a45dd 100644 --- a/vendor/lief/doc/sphinx/tutorials/03_elf_change_symbols.rst +++ b/vendor/lief/doc/sphinx/tutorials/03_elf_change_symbols.rst @@ -66,7 +66,7 @@ Basically, this program takes an integer as argument and performs some computati .. code-block:: console - $ hasme 123 + $ hashme 123 228886645.836282 .. image:: ../_static/tutorial/03/hashme.png @@ -86,7 +86,7 @@ First we have to load both the library and the binary: import lief - hasme = lief.parse("hasme") + hashme = lief.parse("hashme") libm = lief.parse("/usr/lib/libm.so.6") Then when change the name of the two imported functions in the **binary**: @@ -109,7 +109,7 @@ finally we swap ``log`` with ``sin`` and ``pow`` with ``cos`` in the **library** import lief - hasme = lief.parse("hasme") + hashme = lief.parse("hashme") libm = lief.parse("/usr/lib/libm.so.6") diff --git a/vendor/lief/include/LIEF/Abstract/Binary.hpp b/vendor/lief/include/LIEF/Abstract/Binary.hpp index 341bcee..59ade34 100644 --- a/vendor/lief/include/LIEF/Abstract/Binary.hpp +++ b/vendor/lief/include/LIEF/Abstract/Binary.hpp @@ -183,7 +183,7 @@ class LIEF_API Binary : public Object { virtual uint64_t imagebase() const = 0; //! Constructor functions that are called prior any other functions - virtual LIEF::Binary::functions_t ctor_functions() const = 0; + virtual functions_t ctor_functions() const = 0; //! Convert the given offset into a virtual address. //! @@ -195,6 +195,7 @@ class LIEF_API Binary : public Object { //! Build & transform the Binary object representation into a *real* executable virtual void write(const std::string& name) = 0; + virtual void write(std::ostream& os) = 0; LIEF_API friend std::ostream& operator<<(std::ostream& os, const Binary& binary); diff --git a/vendor/lief/include/LIEF/BinaryStream/BinaryStream.hpp b/vendor/lief/include/LIEF/BinaryStream/BinaryStream.hpp index 5b36a04..acfcf98 100644 --- a/vendor/lief/include/LIEF/BinaryStream/BinaryStream.hpp +++ b/vendor/lief/include/LIEF/BinaryStream/BinaryStream.hpp @@ -82,7 +82,10 @@ class BinaryStream { } // Even though offset + size < ... => offset < ... // the addition could overflow so it's worth checking both - const bool read_ok = offset <= this->size() && (offset + size) <= this->size(); + const bool read_ok = offset <= this->size() && (offset + size) <= this->size() + /* Check for an overflow */ + && (static_cast(offset) >= 0 && static_cast(size) >= 0) + && (static_cast(offset + size) >= 0); if (!read_ok) { return make_error_code(lief_errors::read_error); } diff --git a/vendor/lief/include/LIEF/DEX/Class.hpp b/vendor/lief/include/LIEF/DEX/Class.hpp index 9b573b2..36c7342 100644 --- a/vendor/lief/include/LIEF/DEX/Class.hpp +++ b/vendor/lief/include/LIEF/DEX/Class.hpp @@ -16,6 +16,8 @@ #ifndef LIEF_DEX_CLASS_H_ #define LIEF_DEX_CLASS_H_ +#include + #include "LIEF/visibility.h" #include "LIEF/Object.hpp" #include "LIEF/iterators.hpp" @@ -129,7 +131,7 @@ class LIEF_API Class : public Object { fields_t fields_; std::string source_filename_; - uint32_t original_index_ = -1u; + uint32_t original_index_ = UINT_MAX; }; } // Namespace DEX diff --git a/vendor/lief/include/LIEF/DEX/Field.hpp b/vendor/lief/include/LIEF/DEX/Field.hpp index ec1b98b..21aaf6c 100644 --- a/vendor/lief/include/LIEF/DEX/Field.hpp +++ b/vendor/lief/include/LIEF/DEX/Field.hpp @@ -15,6 +15,8 @@ #ifndef LIEF_DEX_FIELD_H_ #define LIEF_DEX_FIELD_H_ +#include + #include "LIEF/DEX/enums.hpp" #include "LIEF/visibility.h" @@ -84,7 +86,7 @@ class LIEF_API Field : public Object { Class* parent_ = nullptr; Type* type_ = nullptr; uint32_t access_flags_ = 0; - uint32_t original_index_ = -1u; + uint32_t original_index_ = UINT_MAX; bool is_static_ = false; }; diff --git a/vendor/lief/include/LIEF/DEX/Method.hpp b/vendor/lief/include/LIEF/DEX/Method.hpp index b722121..060db30 100644 --- a/vendor/lief/include/LIEF/DEX/Method.hpp +++ b/vendor/lief/include/LIEF/DEX/Method.hpp @@ -16,6 +16,7 @@ #ifndef LIEF_DEX_METHOD_H_ #define LIEF_DEX_METHOD_H_ +#include #include "LIEF/visibility.h" #include "LIEF/Object.hpp" @@ -99,7 +100,7 @@ class LIEF_API Method : public Object { Class* parent_ = nullptr; Prototype* prototype_ = nullptr; uint32_t access_flags_ = ACCESS_FLAGS::ACC_UNKNOWN; - uint32_t original_index_ = -1u; + uint32_t original_index_ = UINT_MAX; bool is_virtual_ = false; uint64_t code_offset_ = 0; diff --git a/vendor/lief/include/LIEF/ELF/Binary.hpp b/vendor/lief/include/LIEF/ELF/Binary.hpp index f8d5661..eb12ccd 100644 --- a/vendor/lief/include/LIEF/ELF/Binary.hpp +++ b/vendor/lief/include/LIEF/ELF/Binary.hpp @@ -565,6 +565,11 @@ class LIEF_API Binary : public LIEF::Binary { //! @param filename Path for the written ELF binary void write(const std::string& filename) override; + //! Reconstruct the binary object and write it in `os` stream + //! + //! @param Output stream for the written ELF binary + void write(std::ostream& os) override; + //! Reconstruct the binary object and return its content as a byte vector std::vector raw(); diff --git a/vendor/lief/include/LIEF/ELF/Builder.hpp b/vendor/lief/include/LIEF/ELF/Builder.hpp index ecff06e..11be8e1 100644 --- a/vendor/lief/include/LIEF/ELF/Builder.hpp +++ b/vendor/lief/include/LIEF/ELF/Builder.hpp @@ -102,6 +102,9 @@ class LIEF_API Builder { //! Write the built ELF binary in the ``filename`` given in parameter void write(const std::string& filename) const; + //! Write the built ELF binary in the stream ``os`` given in parameter + void write(std::ostream& os) const; + protected: template ok_error_t build(); diff --git a/vendor/lief/include/LIEF/MachO/Binary.hpp b/vendor/lief/include/LIEF/MachO/Binary.hpp index 31be40b..c0886bf 100644 --- a/vendor/lief/include/LIEF/MachO/Binary.hpp +++ b/vendor/lief/include/LIEF/MachO/Binary.hpp @@ -1,3 +1,4 @@ + /* Copyright 2017 - 2022 R. Thomas * Copyright 2017 - 2022 Quarkslab * @@ -226,6 +227,11 @@ class LIEF_API Binary : public LIEF::Binary { //! @param filename Path to write the reconstructed binary void write(const std::string& filename) override; + //! Reconstruct the binary object and write the result in the given `os` stream + //! + //! @param os Output stream to write the reconstructed binary + void write(std::ostream& os) override; + //! Reconstruct the binary object and return its content as bytes std::vector raw(); @@ -642,7 +648,7 @@ class LIEF_API Binary : public LIEF::Binary { //! Shift the content located right after the Load commands table. //! This operation can be used to add a new command - void shift(size_t value); + ok_error_t shift(size_t value); //! Shift the position on the __LINKEDIT data by `width` ok_error_t shift_linkedit(size_t width); @@ -661,7 +667,7 @@ class LIEF_API Binary : public LIEF::Binary { //! Default constructor Binary(); - void shift_command(size_t width, size_t from_offset); + void shift_command(size_t width, uint64_t from_offset); //! Insert a Segment command in the cache field (segments_) //! and keep a consistent state of the indexes. diff --git a/vendor/lief/include/LIEF/MachO/BinaryParser.hpp b/vendor/lief/include/LIEF/MachO/BinaryParser.hpp index 17b9e50..77b10ef 100644 --- a/vendor/lief/include/LIEF/MachO/BinaryParser.hpp +++ b/vendor/lief/include/LIEF/MachO/BinaryParser.hpp @@ -74,10 +74,10 @@ class LIEF_API BinaryParser : public LIEF::Parser { friend class MachO::Parser; //! Maximum number of relocations - constexpr static size_t MAX_RELOCATIONS = std::numeric_limits::max(); + constexpr static size_t MAX_RELOCATIONS = (std::numeric_limits::max)(); //! Maximum number of MachO LoadCommand - constexpr static size_t MAX_COMMANDS = std::numeric_limits::max(); + constexpr static size_t MAX_COMMANDS = (std::numeric_limits::max)(); public: static std::unique_ptr parse(const std::string& file); diff --git a/vendor/lief/include/LIEF/MachO/Builder.hpp b/vendor/lief/include/LIEF/MachO/Builder.hpp index 6503ddc..6ee6029 100644 --- a/vendor/lief/include/LIEF/MachO/Builder.hpp +++ b/vendor/lief/include/LIEF/MachO/Builder.hpp @@ -73,19 +73,26 @@ class LIEF_API Builder { static ok_error_t write(Binary& binary, std::vector& out); static ok_error_t write(Binary& binary, std::vector& out, config_t config); + static ok_error_t write(Binary& binary, std::ostream& out); + static ok_error_t write(Binary& binary, std::ostream& out, config_t config); + static ok_error_t write(FatBinary& fat, const std::string& filename); static ok_error_t write(FatBinary& fat, const std::string& filename, config_t config); static ok_error_t write(FatBinary& fat, std::vector& out); static ok_error_t write(FatBinary& fat, std::vector& out, config_t config); + static ok_error_t write(FatBinary& fat, std::ostream& out); + static ok_error_t write(FatBinary& fat, std::ostream& out, config_t config); + ~Builder(); private: ok_error_t build(); const std::vector& get_build(); ok_error_t write(const std::string& filename) const; - + ok_error_t write(std::ostream& os) const; + Builder(Binary& binary, config_t config); Builder(std::vector binaries, config_t config); diff --git a/vendor/lief/include/LIEF/MachO/FatBinary.hpp b/vendor/lief/include/LIEF/MachO/FatBinary.hpp index 51fbc8f..a211b89 100644 --- a/vendor/lief/include/LIEF/MachO/FatBinary.hpp +++ b/vendor/lief/include/LIEF/MachO/FatBinary.hpp @@ -69,6 +69,8 @@ class LIEF_API FatBinary { it_binaries end(); it_const_binaries end() const; + void release_all_binaries(); + //! Get a pointer to the last MachO::Binary object presents in this Fat Binary. //! It returns a nullptr if no binary are present. std::unique_ptr pop_back(); diff --git a/vendor/lief/include/LIEF/PE/Binary.hpp b/vendor/lief/include/LIEF/PE/Binary.hpp index e5febab..fe9c903 100644 --- a/vendor/lief/include/LIEF/PE/Binary.hpp +++ b/vendor/lief/include/LIEF/PE/Binary.hpp @@ -448,12 +448,18 @@ class LIEF_API Binary : public LIEF::Binary { // @deprecated This function will be removed in a future version of LIEF void hook_function(const std::string& library, const std::string& function, uint64_t address); - //! Reconstruct the binary object and write the raw PE in `filename` + //! Reconstruct the binary object and write the raw PE in `filename` //! //! Rebuild a PE binary from the current Binary object. //! When rebuilding, import table and relocations are not rebuilt. void write(const std::string& filename) override; + //! Reconstruct the binary object and write the raw PE in `os` stream + //! + //! Rebuild a PE binary from the current Binary object. + //! When rebuilding, import table and relocations are not rebuilt. + void write(std::ostream& os) override; + void accept(Visitor& visitor) const override; //! Patch the content at virtual address @p address with @p patch_value diff --git a/vendor/lief/include/LIEF/PE/Builder.hpp b/vendor/lief/include/LIEF/PE/Builder.hpp index e1efcac..cca15d4 100644 --- a/vendor/lief/include/LIEF/PE/Builder.hpp +++ b/vendor/lief/include/LIEF/PE/Builder.hpp @@ -92,6 +92,9 @@ class LIEF_API Builder { //! @brief Write the build result into the ``output`` file void write(const std::string& filename) const; + + //! @brief Write the build result into the ``os`` stream + void write(std::ostream& os) const; LIEF_API friend std::ostream& operator<<(std::ostream& os, const Builder& b); diff --git a/vendor/lief/include/LIEF/PE/ExportEntry.hpp b/vendor/lief/include/LIEF/PE/ExportEntry.hpp index 37adeb7..1bb6d07 100644 --- a/vendor/lief/include/LIEF/PE/ExportEntry.hpp +++ b/vendor/lief/include/LIEF/PE/ExportEntry.hpp @@ -70,7 +70,7 @@ class LIEF_API ExportEntry : public LIEF::Symbol { } inline void value(uint64_t value) override { - address(value); + address(static_cast(value)); } inline void set_forward_info(std::string lib, std::string function) { diff --git a/vendor/lief/include/LIEF/PE/resources/ResourceIcon.hpp b/vendor/lief/include/LIEF/PE/resources/ResourceIcon.hpp index 56e0eed..742717e 100644 --- a/vendor/lief/include/LIEF/PE/resources/ResourceIcon.hpp +++ b/vendor/lief/include/LIEF/PE/resources/ResourceIcon.hpp @@ -17,6 +17,7 @@ #define LIEF_PE_RESOURCE_ICON_H_ #include #include +#include #include "LIEF/visibility.h" @@ -110,7 +111,7 @@ class LIEF_API ResourceIcon : public Object { uint8_t reserved_ = 0; uint16_t planes_ = 0; uint16_t bit_count_ = 0; - uint32_t id_ = -1u; + uint32_t id_ = UINT_MAX; RESOURCE_LANGS lang_ = RESOURCE_LANGS::LANG_NEUTRAL; RESOURCE_SUBLANGS sublang_ = RESOURCE_SUBLANGS::SUBLANG_DEFAULT; std::vector pixels_; diff --git a/vendor/lief/scripts/docker/run_archlinux.sh b/vendor/lief/scripts/docker/run_archlinux.sh index 8baabcb..1adb7e3 100644 --- a/vendor/lief/scripts/docker/run_archlinux.sh +++ b/vendor/lief/scripts/docker/run_archlinux.sh @@ -23,6 +23,7 @@ python -m pytest -rsx \ /src/tests/elf/test_object_files.py \ /src/tests/elf/test_section_frame.py \ /src/tests/elf/test_466.py \ + /src/tests/elf/test_747.py \ /src/tests/elf/test_empty_gnu_hash.py diff --git a/vendor/lief/setup.py b/vendor/lief/setup.py index bb9474f..f5811e9 100644 --- a/vendor/lief/setup.py +++ b/vendor/lief/setup.py @@ -9,8 +9,9 @@ import distutils from pkg_resources import get_distribution from setuptools import setup, Extension -from setuptools.command.build_ext import build_ext, copy_file +from setuptools.command.build_ext import build_ext from distutils import log +from shutil import copy2 try: from packaging import version @@ -249,7 +250,7 @@ def build_extension(self, ext): if not os.path.exists(self.build_temp): os.makedirs(self.build_temp) - log.info(f"Platform: {platform.system()}", ) + log.info(f"Platform: %s", platform.system()) log.info("Wheel library: %s", self.get_ext_fullname(ext.name)) # 1. Configure @@ -282,21 +283,24 @@ def build_extension(self, ext): subprocess.check_call(['cmake', '--build', '.', '--target', targets['sdk']] + build_args, cwd=self.build_temp, env=env) else: - log.info(f"Using {jobs} jobs") + if self.parallel: + log.info(f"Using {jobs} jobs") + if build_with_ninja: + jobs_opt = ["-j", str(jobs)] if self.parallel else [] if self.distribution.lief_test: subprocess.check_call(configure_cmd, cwd=self.build_temp) - subprocess.check_call(['ninja', '-j', str(jobs)], cwd=self.build_temp) - subprocess.check_call(['ninja', '-j', str(jobs), "check-lief"], cwd=self.build_temp) + subprocess.check_call(['ninja'] + jobs_opt, cwd=self.build_temp) + subprocess.check_call(['ninja'] + jobs_opt + ["check-lief"], cwd=self.build_temp) else: - subprocess.check_call(['ninja', '-j', str(jobs), targets['python_bindings']], cwd=self.build_temp, env=env) + subprocess.check_call(['ninja'] + jobs_opt + [targets['python_bindings']], cwd=self.build_temp, env=env) if 'sdk' in targets: - subprocess.check_call(['ninja', '-j', str(jobs), targets['sdk']], cwd=self.build_temp, env=env) + subprocess.check_call(['ninja'] + jobs_opt + [targets['sdk']], cwd=self.build_temp, env=env) if 'doc' in targets: try: - subprocess.check_call(['ninja', '-j', str(jobs), targets['doc']], cwd=self.build_temp, env=env) + subprocess.check_call(['ninja'] + jobs_opt + [targets['doc']], cwd=self.build_temp, env=env) except Exception as e: log.error(f"Documentation failed: {e}") else: @@ -331,9 +335,8 @@ def build_extension(self, ext): os.makedirs(self.build_lib) log.info(f"Copying {pylief_path} into {pylief_dst}") - copy_file( - pylief_path, pylief_dst, verbose=self.verbose, - dry_run=self.dry_run) + if not self.dry_run: + copy2(pylief_path, pylief_dst) # SDK @@ -346,10 +349,8 @@ def build_extension(self, ext): sdk_path = str(sdk_path.pop()) sdk_output = str(pathlib.Path(CURRENT_DIR) / "build") - - copy_file( - sdk_path, sdk_output, verbose=self.verbose, - dry_run=self.dry_run) + if not self.dry_run: + copy2(sdk_path, sdk_output) def get_platform(): out = get_platform_backup() diff --git a/vendor/lief/src/BinaryStream/BinaryStream.cpp b/vendor/lief/src/BinaryStream/BinaryStream.cpp index 5760640..5d32898 100644 --- a/vendor/lief/src/BinaryStream/BinaryStream.cpp +++ b/vendor/lief/src/BinaryStream/BinaryStream.cpp @@ -29,6 +29,7 @@ #include #include #include +#include #define TMPL_DECL(T) template T BinaryStream::swap_endian(T u) @@ -250,7 +251,7 @@ result BinaryStream::read_u16string(size_t length) const { } result BinaryStream::peek_u16string(size_t length) const { - if (length == static_cast(-1u)) { + if (length == static_cast(SIZE_MAX)) { return peek_u16string(); } diff --git a/vendor/lief/src/DEX/Class.cpp b/vendor/lief/src/DEX/Class.cpp index 88f4a1a..4c1e94c 100644 --- a/vendor/lief/src/DEX/Class.cpp +++ b/vendor/lief/src/DEX/Class.cpp @@ -16,6 +16,7 @@ */ #include +#include #include "LIEF/DEX/Class.hpp" #include "LIEF/DEX/hash.hpp" @@ -30,7 +31,7 @@ Class::Class(std::string fullname, uint32_t access_flags, access_flags_{access_flags}, parent_{parent}, source_filename_{std::move(source_filename)}, - original_index_{-1u} + original_index_{UINT_MAX} {} std::string Class::package_normalized(const std::string& pkg) { diff --git a/vendor/lief/src/DEX/File.cpp b/vendor/lief/src/DEX/File.cpp index aac3501..48de09b 100644 --- a/vendor/lief/src/DEX/File.cpp +++ b/vendor/lief/src/DEX/File.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ #include +#include #include "logging.hpp" #include "LIEF/DEX/File.hpp" #include "LIEF/DEX/instructions.hpp" @@ -88,7 +89,7 @@ std::vector File::raw(bool deoptimize) const { while (inst_ptr < inst_end) { uint16_t dex_pc = (inst_ptr - inst_start) / sizeof(uint16_t); auto opcode = static_cast(*inst_ptr); - uint32_t value = -1u; + uint32_t value = UINT_MAX; if (meth_info.find(dex_pc) != std::end(meth_info)) { value = meth_info[dex_pc]; diff --git a/vendor/lief/src/DEX/Method.cpp b/vendor/lief/src/DEX/Method.cpp index 2beddbe..eefe1d1 100644 --- a/vendor/lief/src/DEX/Method.cpp +++ b/vendor/lief/src/DEX/Method.cpp @@ -156,9 +156,10 @@ std::ostream& operator<<(std::ostream& os, const Method& method) { if (!flags_str.empty()) { os << flags_str << " "; } - os << proto->return_type() - << " " - << pretty_cls_name << "->" << method.name(); + if (const auto* t = proto->return_type()) { + os << *t << " "; + } + os << pretty_cls_name << "->" << method.name(); os << "("; for (size_t i = 0; i < ps.size(); ++i) { diff --git a/vendor/lief/src/DEX/instructions.cpp b/vendor/lief/src/DEX/instructions.cpp index e7dce02..29ec2e7 100644 --- a/vendor/lief/src/DEX/instructions.cpp +++ b/vendor/lief/src/DEX/instructions.cpp @@ -20,6 +20,7 @@ #include #include #include +#include namespace LIEF { namespace DEX { @@ -282,7 +283,7 @@ INST_FORMATS inst_format_from_opcode(OPCODES op) { size_t inst_size_from_format(INST_FORMATS fmt) { static const std::map size_map { - { INST_FORMATS::F_00x, -1u }, + { INST_FORMATS::F_00x, SIZE_MAX }, { INST_FORMATS::F_10x, 2 }, { INST_FORMATS::F_12x, 2 }, { INST_FORMATS::F_11n, 2 }, @@ -365,7 +366,7 @@ bool is_switch_array(const uint8_t* ptr, const uint8_t* end) { size_t switch_array_size(const uint8_t* ptr, const uint8_t* end) { if (!is_switch_array(ptr, end)) { - return -1u; + return SIZE_MAX; } const auto opcode = static_cast(*ptr); @@ -401,7 +402,7 @@ size_t switch_array_size(const uint8_t* ptr, const uint8_t* end) { } default: { - return -1u; + return SIZE_MAX; } } diff --git a/vendor/lief/src/ELF/Binary.cpp b/vendor/lief/src/ELF/Binary.cpp index 354add4..5732c6a 100644 --- a/vendor/lief/src/ELF/Binary.cpp +++ b/vendor/lief/src/ELF/Binary.cpp @@ -1085,9 +1085,37 @@ bool Binary::is_pie() const { [] (const std::unique_ptr& entry) { return entry->type() == SEGMENT_TYPES::PT_INTERP; }); + if (header().file_type() != E_TYPE::ET_DYN) { + return false; + } + + /* If the ELF binary uses an interpreter, then it is position + * independant since the interpreter aims at loading the binary at a random base address + */ + if (it_segment != std::end(segments_)) { + return true; + } + /* It also exists ELF executables which don't have PT_INTERP but are + * PIE (see: https://github.com/lief-project/LIEF/issues/747). That's + * the case, for instance, when compiling with the -static-pie flag + * + * While header().file_type() == E_TYPE::ET_DYN is a requirement + * for PIC binary (Position independant **CODE**), it does not enable + * to distinguish PI **Executables** from libraries. + * + * Therefore, we add the following checks: + * 1. The binary embeds a PT_DYNAMIC segment + * 2. The dynamic table contains a DT_FLAGS_1 set with PIE + */ - return it_segment != std::end(segments_) && - header().file_type() == E_TYPE::ET_DYN; + + if (has(SEGMENT_TYPES::PT_DYNAMIC)) { + if (const auto* flag = static_cast(get(DYNAMIC_TAGS::DT_FLAGS_1))) { + return flag->has(DYNAMIC_FLAGS_1::DF_1_PIE); + } + } + + return false; } @@ -1672,6 +1700,11 @@ void Binary::write(const std::string& filename) { builder.write(filename); } +void Binary::write(std::ostream& os) { + Builder builder{*this}; + builder.build(); + builder.write(os); +} uint64_t Binary::entrypoint() const { return header().entrypoint(); @@ -2094,8 +2127,8 @@ uint64_t Binary::last_offset_segment() const { uint64_t Binary::next_virtual_address() const { - uint64_t va = std::accumulate(std::begin(segments_), std::end(segments_), 0llu, - [] (uint32_t address, const std::unique_ptr& segment) { + uint64_t va = std::accumulate(std::begin(segments_), std::end(segments_), uint64_t{ 0u }, + [] (uint64_t address, const std::unique_ptr& segment) { return std::max(segment->virtual_address() + segment->virtual_size(), address); }); diff --git a/vendor/lief/src/ELF/Binary.tcc b/vendor/lief/src/ELF/Binary.tcc index 8cfa884..a50e02f 100644 --- a/vendor/lief/src/ELF/Binary.tcc +++ b/vendor/lief/src/ELF/Binary.tcc @@ -566,6 +566,9 @@ Section* Binary::add_section(const Section& section) { new_section->offset(segment_added->file_offset()); new_section->original_size_ = segment_added->physical_size(); + new_section->segments_.push_back(segment_added); + segment_added->sections_.push_back(new_section.get()); + header().numberof_sections(header().numberof_sections() + 1); Section* sec_ptr = new_section.get(); diff --git a/vendor/lief/src/ELF/Builder.cpp b/vendor/lief/src/ELF/Builder.cpp index 27ae91f..58f3411 100644 --- a/vendor/lief/src/ELF/Builder.cpp +++ b/vendor/lief/src/ELF/Builder.cpp @@ -127,12 +127,15 @@ void Builder::write(const std::string& filename) const { LIEF_ERR("Can't open {}!", filename); return; } + write(output_file); +} + +void Builder::write(std::ostream& os) const { std::vector content; ios_.move(content); - output_file.write(reinterpret_cast(content.data()), content.size()); + os.write(reinterpret_cast(content.data()), content.size()); } - uint32_t Builder::sort_dynamic_symbols() { const auto it_begin = std::begin(binary_->dynamic_symbols_); const auto it_end = std::end(binary_->dynamic_symbols_); diff --git a/vendor/lief/src/ELF/Builder.tcc b/vendor/lief/src/ELF/Builder.tcc index f079d70..8d744b1 100644 --- a/vendor/lief/src/ELF/Builder.tcc +++ b/vendor/lief/src/ELF/Builder.tcc @@ -1266,9 +1266,10 @@ ok_error_t Builder::build_section_relocations() { if (std::is_same::value) { info = (static_cast(symidx) << 8) | reloc->type(); } else { - info = (static_cast(symidx) << 32) | (reloc->type() & 0xffffffffL); + // NOTE: To suppress a warning we require a cast here, this path is not constexpr but only uses Elf64_Xword + info = (static_cast(symidx) << 32) | (reloc->type() & 0xffffffffL); } - + if (is_rela) { Elf_Rela relahdr; relahdr.r_offset = static_cast(reloc->address()); @@ -1366,7 +1367,8 @@ ok_error_t Builder::build_dynamic_relocations() { if (std::is_same::value) { r_info = (static_cast(info) << 8) | relocation.type(); } else { - r_info = (static_cast(info) << 32) | (relocation.type() & 0xffffffffL); + // NOTE: To suppress a warning we require a cast here, this path is not constexpr but only uses Elf64_Xword + r_info = (static_cast(info) << 32) | (relocation.type() & 0xffffffffL); } @@ -1447,7 +1449,8 @@ ok_error_t Builder::build_pltgot_relocations() { if (std::is_same::value) { info = (static_cast(idx) << 8) | relocation.type(); } else { - info = (static_cast(idx) << 32) | (relocation.type() & 0xffffffffL); + // NOTE: To suppress a warning we require a cast here, this path is not constexpr but only uses Elf64_Xword + info = (static_cast(idx) << 32) | (relocation.type() & 0xffffffffL); } if (is_rela) { diff --git a/vendor/lief/src/ELF/EnumToString.cpp b/vendor/lief/src/ELF/EnumToString.cpp index 55a6be4..23e10a0 100644 --- a/vendor/lief/src/ELF/EnumToString.cpp +++ b/vendor/lief/src/ELF/EnumToString.cpp @@ -60,7 +60,7 @@ const char* to_string(VERSION e) { const char* to_string(ARCH e) { CONST_MAP(ARCH, const char*, 177) enumStrings { - { ARCH::EM_NONE, "None" }, + { ARCH::EM_NONE, "NONE" }, { ARCH::EM_M32, "M32"}, { ARCH::EM_SPARC, "SPARC"}, { ARCH::EM_386, "i386"}, diff --git a/vendor/lief/src/ELF/ExeLayout.hpp b/vendor/lief/src/ELF/ExeLayout.hpp index 4aba930..2503396 100644 --- a/vendor/lief/src/ELF/ExeLayout.hpp +++ b/vendor/lief/src/ELF/ExeLayout.hpp @@ -1311,24 +1311,24 @@ class LIEF_LOCAL ExeLayout : public Layout { if (binary_->has(type) && !has_section) { if (it_offset == std::end(notes_off_map_)) { LIEF_ERR("Can't find {}", to_string(type)); - return make_error_code(lief_errors::file_format_error); + } else { + const size_t note_offset = it_offset->second; + + const Note& note = *binary_->get(type); + + Section section{section_name, ELF_SECTION_TYPES::SHT_NOTE}; + section += ELF_SECTION_FLAGS::SHF_ALLOC; + + Section* section_added = binary_->add(section, /*loaded */ false); + if (section_added == nullptr) { + LIEF_ERR("Can't add SHT_NOTE section"); + return make_error_code(lief_errors::build_error); + } + section_added->offset(segment_note->file_offset() + note_offset); + section_added->size(note.size()); + section.virtual_address(segment_note->virtual_address() + note_offset); + section_added->alignment(4); } - const size_t note_offset = it_offset->second; - - const Note& note = *binary_->get(type); - - Section section{section_name, ELF_SECTION_TYPES::SHT_NOTE}; - section += ELF_SECTION_FLAGS::SHF_ALLOC; - - Section* section_added = binary_->add(section, /*loaded */ false); - if (section_added == nullptr) { - LIEF_ERR("Can't add SHT_NOTE section"); - return make_error_code(lief_errors::build_error); - } - section_added->offset(segment_note->file_offset() + note_offset); - section_added->size(note.size()); - section.virtual_address(segment_note->virtual_address() + note_offset); - section_added->alignment(4); } } } diff --git a/vendor/lief/src/ELF/NoteDetails/core/CoreFile.tcc b/vendor/lief/src/ELF/NoteDetails/core/CoreFile.tcc index 25df4b3..cfea064 100644 --- a/vendor/lief/src/ELF/NoteDetails/core/CoreFile.tcc +++ b/vendor/lief/src/ELF/NoteDetails/core/CoreFile.tcc @@ -66,7 +66,10 @@ void CoreFile::parse_() { if (!res_path) { break; } - files_[idx].path = std::move(*res_path); + std::string path = std::move(*res_path); + if (!path.empty()) { + files_[idx].path = std::move(path); + } } } diff --git a/vendor/lief/src/ELF/NoteDetails/core/CorePrPsInfo.tcc b/vendor/lief/src/ELF/NoteDetails/core/CorePrPsInfo.tcc index a7ece56..4330d21 100644 --- a/vendor/lief/src/ELF/NoteDetails/core/CorePrPsInfo.tcc +++ b/vendor/lief/src/ELF/NoteDetails/core/CorePrPsInfo.tcc @@ -38,7 +38,7 @@ void CorePrPsInfo::parse_() { const auto* info = reinterpret_cast(desc.data()); // parse info structure - file_name_ = info->pr_fname; + file_name_ = std::string(info->pr_fname, sizeof(info->pr_fname)).c_str(); flags_ = info->pr_flag; uid_ = info->pr_uid; gid_ = info->pr_gid; diff --git a/vendor/lief/src/ELF/Parser.tcc b/vendor/lief/src/ELF/Parser.tcc index 66a593c..255d117 100644 --- a/vendor/lief/src/ELF/Parser.tcc +++ b/vendor/lief/src/ELF/Parser.tcc @@ -1526,7 +1526,7 @@ ok_error_t Parser::parse_symbol_version_definition(uint64_t offset, uint32_t nb_ for (std::unique_ptr& sva : svd->symbol_version_aux_) { binary_->sizing_info_->verdef += sizeof(Elf_Verdaux); for (std::unique_ptr& sv : binary_->symbol_version_table_) { - if (svd->ndx() > 1 && (sv->value() & 0x7FFF) == svd->ndx()) { + if (svd->ndx() > 1 && (sv->value() & 0x7FFF) == svd->ndx() && !sv->symbol_aux_) { sv->symbol_aux_ = sva.get(); } } diff --git a/vendor/lief/src/ELF/Relocation.cpp b/vendor/lief/src/ELF/Relocation.cpp index cffbbf0..0e82acf 100644 --- a/vendor/lief/src/ELF/Relocation.cpp +++ b/vendor/lief/src/ELF/Relocation.cpp @@ -14,6 +14,7 @@ * limitations under the License. */ #include +#include #include "LIEF/exception.hpp" #include "LIEF/ELF/hash.hpp" @@ -170,7 +171,7 @@ size_t Relocation::size() const { const auto it = relocation_x86_64_sizes.find(static_cast(type())); if (it == std::end(relocation_x86_64_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -180,7 +181,7 @@ size_t Relocation::size() const { const auto it = relocation_i386_sizes.find(static_cast(type())); if (it == std::end(relocation_i386_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -190,7 +191,7 @@ size_t Relocation::size() const { const auto it = relocation_ARM_sizes.find(static_cast(type())); if (it == std::end(relocation_ARM_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -200,7 +201,7 @@ size_t Relocation::size() const { const auto it = relocation_AARCH64_sizes.find(static_cast(type())); if (it == std::end(relocation_AARCH64_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -210,7 +211,7 @@ size_t Relocation::size() const { const auto it = relocation_MIPS_sizes.find(static_cast(type())); if (it == std::end(relocation_MIPS_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -221,7 +222,7 @@ size_t Relocation::size() const { const auto it = relocation_PPC_sizes.find(static_cast(type())); if (it == std::end(relocation_PPC_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -231,7 +232,7 @@ size_t Relocation::size() const { const auto it = relocation_PPC64_sizes.find(static_cast(type())); if (it == std::end(relocation_PPC64_sizes)) { LIEF_ERR("{} - {}", to_string(architecture()), to_string(static_cast(type()))); - return -1u; + return SIZE_MAX; } return it->second; } @@ -239,7 +240,7 @@ size_t Relocation::size() const { default: { LIEF_ERR("Architecture {} not implemented", to_string(architecture())); - return -1u; + return SIZE_MAX; } } diff --git a/vendor/lief/src/ELF/Symbol.cpp b/vendor/lief/src/ELF/Symbol.cpp index d014f99..c95c294 100644 --- a/vendor/lief/src/ELF/Symbol.cpp +++ b/vendor/lief/src/ELF/Symbol.cpp @@ -187,7 +187,7 @@ bool Symbol::is_exported() const { bool is_exported = shndx() != static_cast(SYMBOL_SECTION_INDEX::SHN_UNDEF); // An export must have an address - is_exported = is_exported && value() != 0; + is_exported = is_exported && (value() != 0 || (value() == 0 && size() > 0)); // An export must be bind to GLOBAL or WEAK is_exported = is_exported && (binding() == SYMBOL_BINDINGS::STB_GLOBAL || diff --git a/vendor/lief/src/MachO/Binary.cpp b/vendor/lief/src/MachO/Binary.cpp index 1260fee..f0504ef 100644 --- a/vendor/lief/src/MachO/Binary.cpp +++ b/vendor/lief/src/MachO/Binary.cpp @@ -463,6 +463,9 @@ void Binary::write(const std::string& filename) { Builder::write(*this, filename); } +void Binary::write(std::ostream& os) { + Builder::write(*this, os); +} const Section* Binary::section_from_offset(uint64_t offset) const { const auto it_section = std::find_if( @@ -527,13 +530,17 @@ SegmentCommand* Binary::segment_from_virtual_address(uint64_t virtual_address) { } const SegmentCommand* Binary::segment_from_offset(uint64_t offset) const { + if (offset_seg_.empty()) { + return nullptr; + } + const auto it_begin = std::begin(offset_seg_); if (offset < it_begin->first) { return nullptr; } auto it = offset_seg_.lower_bound(offset); - if (it->first == offset || it == it_begin) { + if (it != std::end(offset_seg_) && (it->first == offset || it == it_begin)) { SegmentCommand* seg = it->second; if (seg->file_offset() <= offset && offset < (seg->file_offset() + seg->file_size())) { return seg; @@ -700,11 +707,11 @@ uint32_t Binary::page_size() const { return is_arm ? 0x4000 : 0x1000; } -void Binary::shift_command(size_t width, size_t from_offset) { +void Binary::shift_command(size_t width, uint64_t from_offset) { const SegmentCommand* segment = segment_from_offset(from_offset); - size_t __text_base_addr = 0; - size_t virtual_address = 0; + uint64_t __text_base_addr = 0; + uint64_t virtual_address = 0; if (segment != nullptr) { virtual_address = segment->virtual_address() + from_offset; @@ -933,7 +940,7 @@ void Binary::shift_command(size_t width, size_t from_offset) { } -void Binary::shift(size_t value) { +ok_error_t Binary::shift(size_t value) { Header& header = this->header(); // Offset of the load commands table @@ -957,7 +964,7 @@ void Binary::shift(size_t value) { SegmentCommand* load_cmd_segment = segment_from_offset(loadcommands_end); if (load_cmd_segment == nullptr) { LIEF_WARN("Can't find segment associated with last load command"); - return; + return make_error_code(lief_errors::file_format_error); } LIEF_DEBUG("LC Table wrapped by {} / End offset: 0x{:x} (size: {:x})", load_cmd_segment->name(), loadcommands_end, load_cmd_segment->data_.size()); @@ -1009,6 +1016,7 @@ void Binary::shift(size_t value) { } } refresh_seg_offset(); + return ok(); } @@ -1019,7 +1027,9 @@ LoadCommand* Binary::add(const LoadCommand& command) { // Check there is enough spaces between the load command table // and the raw content if (available_command_space_ < size_aligned) { - shift(shift_value); + if (!shift(shift_value)) { + return nullptr; + } available_command_space_ += shift_value; return add(command); } @@ -1102,7 +1112,7 @@ LoadCommand* Binary::add(const LoadCommand& command, size_t index) { // Get offset of the LC border LoadCommand* cmd_border = commands_[index].get(); - size_t border_off = cmd_border->command_offset(); + uint64_t border_off = cmd_border->command_offset(); std::unique_ptr copy{command.clone()}; copy->command_offset(cmd_border->command_offset()); @@ -1165,7 +1175,7 @@ bool Binary::remove(const LoadCommand& command) { } } - const size_t cmd_rm_offset = cmd_rm->command_offset(); + const uint64_t cmd_rm_offset = cmd_rm->command_offset(); for (std::unique_ptr& cmd : commands_) { if (cmd->command_offset() >= cmd_rm_offset) { cmd->command_offset(cmd->command_offset() - cmd_rm->size()); @@ -1280,8 +1290,8 @@ bool Binary::extend_segment(const SegmentCommand& segment, size_t size) { } SegmentCommand* target_segment = *it_segment; - const size_t last_offset = target_segment->file_offset() + target_segment->file_size(); - const size_t last_va = target_segment->virtual_address() + target_segment->virtual_size(); + const uint64_t last_offset = target_segment->file_offset() + target_segment->file_size(); + const uint64_t last_va = target_segment->virtual_address() + target_segment->virtual_size(); const int32_t size_aligned = align(size, pointer_size()); @@ -1465,7 +1475,7 @@ Section* Binary::add_section(const SegmentCommand& segment, const Section& secti sections_.push_back(new_section.get()); // Copy data to segment - const size_t relative_offset = new_section->offset() - target_segment->file_offset(); + const uint64_t relative_offset = new_section->offset() - target_segment->file_offset(); std::move(std::begin(content), std::end(content), std::begin(target_segment->data_) + relative_offset); @@ -1515,7 +1525,6 @@ LoadCommand* Binary::add(const SegmentCommand& segment) { * ``` * Therefore, we must shift __LINKEDIT by at least 4 * 0x1000 for Mach-O files targeting ARM */ - LIEF_DEBUG("Adding the new segment '{}' ({} bytes)", segment.name(), segment.content().size()); const uint32_t alignment = page_size(); const uint64_t new_fsize = align(segment.content().size(), alignment); @@ -1560,18 +1569,19 @@ LoadCommand* Binary::add(const SegmentCommand& segment) { const bool has_linkedit = it_linkedit != std::end(commands_); - size_t pos = std::distance(std::begin(commands_), it_linkedit); LIEF_DEBUG(" -> index: {}", pos); - auto* segment_added = add(new_segment, pos)->as(); + auto* new_cmd = add(new_segment, pos); - if (segment_added == nullptr) { + if (new_cmd == nullptr) { LIEF_WARN("Fail to insert new '{}' segment", segment.name()); return nullptr; } + auto* segment_added = new_cmd->as(); + if (!has_linkedit) { /* If there are not __LINKEDIT segment we can point the Segment's content to the EOF * NOTE(romain): I don't know if a binary without a __LINKEDIT segment exists @@ -1581,7 +1591,7 @@ LoadCommand* Binary::add(const SegmentCommand& segment) { if (segment.virtual_address() == 0 && segment_added->virtual_size() != 0) { const uint64_t new_va = align(new_va_ranges.end, alignment); segment_added->virtual_address(new_va); - size_t current_va = segment_added->virtual_address(); + uint64_t current_va = segment_added->virtual_address(); for (Section& section : segment_added->sections()) { section.virtual_address(current_va); current_va += section.size(); @@ -1591,7 +1601,7 @@ LoadCommand* Binary::add(const SegmentCommand& segment) { if (segment.file_offset() == 0 && segment_added->virtual_size() != 0) { const uint64_t new_offset = align(new_off_ranges.end, alignment); segment_added->file_offset(new_offset); - size_t current_offset = new_offset; + uint64_t current_offset = new_offset; for (Section& section : segment_added->sections()) { section.offset(current_offset); current_offset += section.size(); @@ -1616,14 +1626,14 @@ LoadCommand* Binary::add(const SegmentCommand& segment) { segment_added->virtual_address(lnk_va); segment_added->virtual_size(segment_added->virtual_size()); - size_t current_va = segment_added->virtual_address(); + uint64_t current_va = segment_added->virtual_address(); for (Section& section : segment_added->sections()) { section.virtual_address(current_va); current_va += section.size(); } segment_added->file_offset(lnk_offset); - size_t current_offset = lnk_offset; + uint64_t current_offset = lnk_offset; for (Section& section : segment_added->sections()) { section.offset(current_offset); current_offset += section.size(); diff --git a/vendor/lief/src/MachO/BinaryParser.tcc b/vendor/lief/src/MachO/BinaryParser.tcc index 61bb294..33480d3 100644 --- a/vendor/lief/src/MachO/BinaryParser.tcc +++ b/vendor/lief/src/MachO/BinaryParser.tcc @@ -887,16 +887,24 @@ ok_error_t BinaryParser::parse_load_commands() { * with the BinaryParser constructor */ const size_t current_pos = stream_->pos(); + if (!visited_.insert(cmd->fileoff).second) { + break; + } + stream_->setpos(cmd->fileoff); BinaryParser bp; - bp.stream_ = std::move(stream_); - bp.config_ = config_; + bp.binary_ = std::unique_ptr(new Binary{}); + bp.stream_ = std::move(stream_); + bp.config_ = config_; + bp.visited_ = visited_; + if (!bp.init_and_parse()) { LIEF_WARN("Parsing the Binary fileset raised error."); } stream_ = std::move(bp.stream_); stream_->setpos(current_pos); + visited_ = std::move(bp.visited_); if (bp.binary_ != nullptr) { std::unique_ptr filset_bin = std::move(bp.binary_); @@ -1004,6 +1012,7 @@ ok_error_t BinaryParser::parse_load_commands() { if (load_command != nullptr) { if (!stream_->peek_data(load_command->original_data_, loadcommands_offset, command->cmdsize)) { LIEF_ERR("Can't read the raw data of the load command"); + load_command->size_ = 0; } load_command->command_offset(loadcommands_offset); binary_->commands_.push_back(std::move(load_command)); @@ -1625,6 +1634,10 @@ ok_error_t BinaryParser::parse_dyldinfo_generic_bind() { case BIND_SUBOPCODE_THREADED::BIND_SUBOPCODE_THREADED_APPLY: { uint64_t delta = 0; + if (segment_idx >= segments.size()) { + LIEF_ERR("Wrong index ({:d})", segment_idx); + return make_error_code(lief_errors::corrupted); + } const SegmentCommand& current_segment = segments[segment_idx]; do { const uint64_t address = current_segment.virtual_address() + segment_offset; @@ -1678,12 +1691,19 @@ ok_error_t BinaryParser::parse_dyldinfo_generic_bind() { } case BIND_SUBOPCODE_THREADED::BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB: { + // Maxium number of elements according to dyld's MachOAnalyzer.cpp + static constexpr size_t MAX_COUNT = 65535; auto val = stream_->read_uleb128(); if (!val) { LIEF_ERR("Can't read BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB count"); break; } count = *val; + if (count > MAX_COUNT) { + LIEF_ERR("BIND_SUBOPCODE_THREADED_SET_BIND_ORDINAL_TABLE_SIZE_ULEB" + "count is too large ({})", count); + break; + } ordinal_table_size = count + 1; // the +1 comes from: 'ld64 wrote the wrong value here and we need to offset by 1 for now.' use_threaded_rebase_bind = true; ordinal_table.reserve(ordinal_table_size); @@ -3315,7 +3335,7 @@ ok_error_t BinaryParser::post_process(DynamicSymbolCommand& cmd) { } if (cmd.nb_external_define_symbols() > 0 && - cmd.idx_external_define_symbol() <= isym && isym < (cmd.idx_external_define_symbol() + cmd.nb_local_symbols())) + cmd.idx_external_define_symbol() <= isym && isym < (cmd.idx_external_define_symbol() + cmd.nb_external_define_symbols())) { sym->category_ = Symbol::CATEGORY::EXTERNAL; } diff --git a/vendor/lief/src/MachO/Builder.cpp b/vendor/lief/src/MachO/Builder.cpp index 8690a41..c67ca93 100644 --- a/vendor/lief/src/MachO/Builder.cpp +++ b/vendor/lief/src/MachO/Builder.cpp @@ -292,6 +292,28 @@ ok_error_t Builder::write(Binary& binary, const std::string& filename, config_t return ok(); } +ok_error_t Builder::write(Binary& binary, std::ostream& out) { + config_t config; + return write(binary, out, std::move(config)); +} + +ok_error_t Builder::write(Binary& binary, std::ostream& out, config_t config) { + Builder builder{binary, std::move(config)}; + builder.build(); + builder.write(out); + return ok(); +} + +ok_error_t Builder::write(Binary& binary, std::vector& out) { + config_t config; + return write(binary, out, config); +} + +ok_error_t Builder::write(Binary& binary, std::vector& out, config_t config) { + out = build_raw(binary, config); + return ok(); +} + ok_error_t Builder::write(FatBinary& fat, const std::string& filename) { config_t config; return write(fat, filename, std::move(config)); @@ -312,22 +334,32 @@ ok_error_t Builder::write(FatBinary& fat, const std::string& filename, config_t return ok(); } -ok_error_t Builder::write(Binary& binary, std::vector& out) { +ok_error_t Builder::write(FatBinary& fat, std::vector& out) { config_t config; - return write(binary, out, config); + return write(fat, out, config); } -ok_error_t Builder::write(Binary& binary, std::vector& out, config_t config) { - out = build_raw(binary, config); +ok_error_t Builder::write(FatBinary& fat, std::vector& out, config_t config) { + std::vector binaries; + binaries.reserve(fat.binaries_.size()); + std::transform(std::begin(fat.binaries_), std::end(fat.binaries_), + std::back_inserter(binaries), + [] (const std::unique_ptr& bin) { + return bin.get(); + }); + + Builder builder{std::move(binaries), std::move(config)}; + builder.build_fat(); + out = builder.get_build(); return ok(); } -ok_error_t Builder::write(FatBinary& fat, std::vector& out) { +ok_error_t Builder::write(FatBinary& fat, std::ostream& out) { config_t config; - return write(fat, out, config); + return write(fat, out, std::move(config)); } -ok_error_t Builder::write(FatBinary& fat, std::vector& out, config_t config) { +ok_error_t Builder::write(FatBinary& fat, std::ostream& out, config_t config) { std::vector binaries; binaries.reserve(fat.binaries_.size()); std::transform(std::begin(fat.binaries_), std::end(fat.binaries_), @@ -338,11 +370,10 @@ ok_error_t Builder::write(FatBinary& fat, std::vector& out, config_t co Builder builder{std::move(binaries), std::move(config)}; builder.build_fat(); - out = builder.get_build(); + builder.write(out); return ok(); } - std::vector Builder::build_raw(Binary& binary, config_t config) { Builder builder{binary, std::move(config)}; builder.build(); @@ -355,10 +386,13 @@ ok_error_t Builder::write(const std::string& filename) const { LIEF_ERR("Can't write back the LIEF Mach-O object into '{}'", filename); return make_error_code(lief_errors::build_error); } + return write(output_file); +} +ok_error_t Builder::write(std::ostream& os) const { std::vector content; raw_.move(content); - output_file.write(reinterpret_cast(content.data()), content.size()); + os.write(reinterpret_cast(content.data()), content.size()); return ok(); } diff --git a/vendor/lief/src/MachO/FatBinary.cpp b/vendor/lief/src/MachO/FatBinary.cpp index 763be57..e25bc7d 100644 --- a/vendor/lief/src/MachO/FatBinary.cpp +++ b/vendor/lief/src/MachO/FatBinary.cpp @@ -147,6 +147,12 @@ std::vector FatBinary::raw() { return buffer; } +void FatBinary::release_all_binaries() { + for (auto& bin : binaries_) { + bin.release(); + } +} + std::ostream& operator<<(std::ostream& os, const FatBinary& fatbinary) { for (const Binary& binary : fatbinary) { os << binary; diff --git a/vendor/lief/src/MachO/ThreadCommand.cpp b/vendor/lief/src/MachO/ThreadCommand.cpp index 3996907..3c6286e 100644 --- a/vendor/lief/src/MachO/ThreadCommand.cpp +++ b/vendor/lief/src/MachO/ThreadCommand.cpp @@ -77,24 +77,36 @@ uint64_t ThreadCommand::pc() const { switch(architecture_) { case CPU_TYPES::CPU_TYPE_X86: { + if (state_.size() < sizeof(details::x86_thread_state_t)) { + return entry; + } entry = reinterpret_cast(state_.data())->eip; break; } case CPU_TYPES::CPU_TYPE_X86_64: { + if (state_.size() < sizeof(details::x86_thread_state64_t)) { + return entry; + } entry = reinterpret_cast(state_.data())->rip; break; } case CPU_TYPES::CPU_TYPE_ARM: { + if (state_.size() < sizeof(details::arm_thread_state_t)) { + return entry; + } entry = reinterpret_cast(state_.data())->r15; break; } case CPU_TYPES::CPU_TYPE_ARM64: { + if (state_.size() < sizeof(details::arm_thread_state64_t)) { + return entry; + } entry = reinterpret_cast(state_.data())->pc; break; } diff --git a/vendor/lief/src/OAT/Class.cpp b/vendor/lief/src/OAT/Class.cpp index 56a7e35..cbec35e 100644 --- a/vendor/lief/src/OAT/Class.cpp +++ b/vendor/lief/src/OAT/Class.cpp @@ -15,6 +15,7 @@ */ #include +#include #include "LIEF/OAT/Class.hpp" #include "LIEF/OAT/Method.hpp" @@ -91,7 +92,7 @@ size_t Class::index() const { if (has_dex_class()) { return dex_class()->index(); } - return -1ull; + return SIZE_MAX; } const std::vector& Class::bitmap() const { @@ -148,7 +149,7 @@ bool Class::is_quickened(uint32_t relative_index) const { uint32_t Class::method_offsets_index(const DEX::Method& m) const { if (!has_dex_class()) { - return -1u; + return UINT_MAX; } const DEX::Class& cls = *dex_class(); @@ -160,7 +161,7 @@ uint32_t Class::method_offsets_index(const DEX::Method& m) const { if (it_method_index == std::end(methods)) { LIEF_ERR("Can't find '{}' in {}", m.name(), cls.fullname()); - return -1u; + return UINT_MAX; } uint32_t relative_index = std::distance(std::begin(methods), it_method_index); @@ -170,7 +171,7 @@ uint32_t Class::method_offsets_index(const DEX::Method& m) const { uint32_t Class::method_offsets_index(uint32_t relative_index) const { if (!is_quickened(relative_index) || type() == OAT_CLASS_TYPES::OAT_CLASS_NONE_COMPILED) { - return -1u; + return UINT_MAX; } if (type() == OAT_CLASS_TYPES::OAT_CLASS_ALL_COMPILED) { @@ -192,12 +193,12 @@ uint32_t Class::method_offsets_index(uint32_t relative_index) const { return count; } - return -1u; + return UINT_MAX; } uint32_t Class::relative_index(const DEX::Method& m) const { if (!has_dex_class()) { - return -1u; + return UINT_MAX; } const DEX::Class& cls = *dex_class(); @@ -209,7 +210,7 @@ uint32_t Class::relative_index(const DEX::Method& m) const { if (it_method_index == std::end(methods)) { LIEF_ERR("Can't find '{}' in {}", m.name(), cls.fullname()); - return -1u; + return UINT_MAX; } return std::distance(std::begin(methods), it_method_index); @@ -217,7 +218,7 @@ uint32_t Class::relative_index(const DEX::Method& m) const { uint32_t Class::relative_index(uint32_t method_absolute_index) const { if (!has_dex_class()) { - return -1u; + return UINT_MAX; } const DEX::Class& cls = *dex_class(); @@ -229,7 +230,7 @@ uint32_t Class::relative_index(uint32_t method_absolute_index) const { if (it_method_index == std::end(methods)) { LIEF_ERR("Can't find find method with index {:d} in {}", method_absolute_index, cls.fullname()); - return -1u; + return UINT_MAX; } return std::distance(std::begin(methods), it_method_index); diff --git a/vendor/lief/src/PE/Binary.cpp b/vendor/lief/src/PE/Binary.cpp index 51c2888..4ad2501 100644 --- a/vendor/lief/src/PE/Binary.cpp +++ b/vendor/lief/src/PE/Binary.cpp @@ -157,8 +157,10 @@ Binary::Binary(const std::string& name, PE_TYPE type) : optional_header().sizeof_image(virtual_size()); } -void Binary::write(const std::string& filename) { - Builder builder{*this}; +template +static void write_impl(Binary& binary, T&& dest) +{ + Builder builder{binary}; builder. build_imports(false). @@ -168,7 +170,15 @@ void Binary::write(const std::string& filename) { build_resources(true); builder.build(); - builder.write(filename); + builder.write(dest); +} + +void Binary::write(const std::string& filename) { + write_impl(*this, filename); +} + +void Binary::write(std::ostream& os) { + write_impl(*this, os); } TLS& Binary::tls() { @@ -614,7 +624,7 @@ Section* Binary::add_section(const Section& section, PE_SECTION_TYPES type) { // Compute new section offset uint64_t new_section_offset = align(std::accumulate( - std::begin(sections_), std::end(sections_), sizeof_headers(), + std::begin(sections_), std::end(sections_), static_cast(sizeof_headers()), [] (uint64_t offset, const std::unique_ptr
& s) { return std::max(s->pointerto_raw_data() + s->sizeof_raw_data(), offset); }), optional_header().file_alignment()); @@ -623,11 +633,12 @@ Section* Binary::add_section(const Section& section, PE_SECTION_TYPES type) { // Compute new section Virtual address + const uint64_t section_align = static_cast(optional_header().section_alignment()); const uint64_t new_section_va = align(std::accumulate( - std::begin(sections_), std::end(sections_), optional_header().section_alignment(), + std::begin(sections_), std::end(sections_), section_align, [] (uint64_t va, const std::unique_ptr
& s) { return std::max(s->virtual_address() + s->virtual_size(), va); - }), optional_header().section_alignment()); + }), section_align); LIEF_DEBUG("New section VA: 0x{:x}", new_section_va); @@ -865,12 +876,13 @@ uint32_t Binary::predict_function_rva(const std::string& library, const std::str // We assume the the idata section will be the last section + const uint64_t section_align = static_cast(optional_header().section_alignment()); const uint64_t next_virtual_address = align(std::accumulate( std::begin(sections_), - std::end(sections_), optional_header().section_alignment(), + std::end(sections_), section_align, [] (uint64_t va, const std::unique_ptr
& s) { return std::max(s->virtual_address() + s->virtual_size(), va); - }), optional_header().section_alignment()); + }), section_align); return next_virtual_address + address; } diff --git a/vendor/lief/src/PE/Builder.cpp b/vendor/lief/src/PE/Builder.cpp index 8b414d2..1a84fbb 100644 --- a/vendor/lief/src/PE/Builder.cpp +++ b/vendor/lief/src/PE/Builder.cpp @@ -86,22 +86,22 @@ Builder& Builder::build_dos_stub(bool flag) { return *this; } - void Builder::write(const std::string& filename) const { std::ofstream output_file{filename, std::ios::out | std::ios::binary | std::ios::trunc}; if (!output_file) { LIEF_ERR("Can't write in {}", filename); return; } + write(output_file); +} +void Builder::write(std::ostream& os) const { std::vector content; ios_.get(content); std::copy(std::begin(content), std::end(content), - std::ostreambuf_iterator(output_file)); - + std::ostreambuf_iterator(os)); } - ok_error_t Builder::build() { LIEF_DEBUG("Build process started"); @@ -397,7 +397,7 @@ ok_error_t Builder::construct_resources(ResourceNode& node, std::vector ok_error_t Builder::build_overlay() { const uint64_t last_section_offset = std::accumulate( - std::begin(binary_->sections_), std::end(binary_->sections_), 0, + std::begin(binary_->sections_), std::end(binary_->sections_), uint64_t{ 0u }, [] (uint64_t offset, const std::unique_ptr
& section) { return std::max(section->offset() + section->size(), offset); }); diff --git a/vendor/lief/src/PE/Parser.cpp b/vendor/lief/src/PE/Parser.cpp index 8869b5c..922d282 100644 --- a/vendor/lief/src/PE/Parser.cpp +++ b/vendor/lief/src/PE/Parser.cpp @@ -220,7 +220,7 @@ ok_error_t Parser::parse_sections() { const uint32_t opt_header_off = pe_header_off + sizeof(details::pe_header); const uint32_t sections_offset = opt_header_off + binary_->header().sizeof_optional_header(); - uint32_t first_section_offset = -1u; + uint32_t first_section_offset = UINT_MAX; uint32_t numberof_sections = binary_->header().numberof_sections(); if (numberof_sections > NB_MAX_SECTIONS) { @@ -1044,7 +1044,7 @@ ok_error_t Parser::parse_signature() { ok_error_t Parser::parse_overlay() { LIEF_DEBUG("== Parsing Overlay =="); const uint64_t last_section_offset = std::accumulate( - std::begin(binary_->sections_), std::end(binary_->sections_), 0, + std::begin(binary_->sections_), std::end(binary_->sections_), uint64_t{ 0u }, [] (uint64_t offset, const std::unique_ptr
& section) { return std::max(section->offset() + section->size(), offset); }); diff --git a/vendor/lief/src/visitors/hash.cpp b/vendor/lief/src/visitors/hash.cpp index 593bd9a..b162494 100644 --- a/vendor/lief/src/visitors/hash.cpp +++ b/vendor/lief/src/visitors/hash.cpp @@ -153,13 +153,12 @@ size_t Hash::hash(const std::vector& raw) { size_t Hash::hash(const void* raw, size_t size) { const auto* start = reinterpret_cast(raw); - std::vector sha256(32, 0); + std::vector sha256(32, 0u); mbedtls_sha256(start, size, sha256.data(), 0); - return std::accumulate(std::begin(sha256), std::end(sha256), 0, + return std::accumulate(std::begin(sha256), std::end(sha256), 0llu, [] (size_t v, uint8_t n) { - size_t r = v; - return (r << sizeof(uint8_t) * 8) | n; + return (v << sizeof(uint8_t) * 8u) | n; }); } diff --git a/vendor/lief/tests/elf/CMakeLists.txt b/vendor/lief/tests/elf/CMakeLists.txt index 14641e6..cfa9e3e 100644 --- a/vendor/lief/tests/elf/CMakeLists.txt +++ b/vendor/lief/tests/elf/CMakeLists.txt @@ -168,6 +168,16 @@ add_test(ELF_PYTHON_issue_466 ${PYTHON_EXECUTABLE} -m pytest -rsx ${CMAKE_CURRENT_SOURCE_DIR}/test_466.py) +add_test(ELF_PYTHON_issue_747 + ${CMAKE_COMMAND} -E env "PYTHONPATH=${PYTHONENV}" + ${PYTHON_EXECUTABLE} -m pytest -rsx + ${CMAKE_CURRENT_SOURCE_DIR}/test_747.py) + +add_test(ELF_PYTHON_issue_760 + ${CMAKE_COMMAND} -E env "PYTHONPATH=${PYTHONENV}" + ${PYTHON_EXECUTABLE} -m pytest -rsx + ${CMAKE_CURRENT_SOURCE_DIR}/test_760.py) + add_test(ELF_PYTHON_empty_gnu_hash ${CMAKE_COMMAND} -E env "PYTHONPATH=${PYTHONENV}" ${PYTHON_EXECUTABLE} -m pytest -rsx @@ -193,6 +203,11 @@ add_test(ELF_binary_size ${PYTHON_EXECUTABLE} -m pytest -rsx ${CMAKE_CURRENT_SOURCE_DIR}/test_binary_size.py) +add_test(ELF_symbol_versions + ${CMAKE_COMMAND} -E env "PYTHONPATH=${PYTHONENV}" + ${PYTHON_EXECUTABLE} -m pytest -rsx + ${CMAKE_CURRENT_SOURCE_DIR}/test_symbol_versions.py) + # Examples # -------- diff --git a/vendor/lief/tests/elf/test_466.py b/vendor/lief/tests/elf/test_466.py index b0a36c4..1c858bd 100644 --- a/vendor/lief/tests/elf/test_466.py +++ b/vendor/lief/tests/elf/test_466.py @@ -37,10 +37,7 @@ def test_freebl(tmp_path): output_ls.chmod(output_ls.stat().st_mode | stat.S_IEXEC) output_libfreebl3.chmod(output_libfreebl3.stat().st_mode | stat.S_IEXEC) - with Popen([output_ls, "--version"], stdout=subprocess.PIPE, stderr=subprocess.STDOUT) as proc: stdout = proc.stdout.read() print(stdout.decode("utf8")) assert re.search(r'ls \(GNU coreutils\) ', stdout.decode("utf8")) is not None - proc.poll() - assert proc.returncode == 0 diff --git a/vendor/lief/tests/elf/test_747.py b/vendor/lief/tests/elf/test_747.py new file mode 100755 index 0000000..9b06498 --- /dev/null +++ b/vendor/lief/tests/elf/test_747.py @@ -0,0 +1,32 @@ +#!/usr/bin/env python +import pytest + +import lief +import pathlib + +from utils import get_sample + +def test_static_pie(): + static_pie_path = get_sample('ELF/elf64_static_pie.bin') + static_pie = lief.parse(static_pie_path) + assert static_pie.is_pie + +def test_static(): + static_path = get_sample('ELF/batch-x86-64/test.gcc.fullstatic.nothread.bin') + static = lief.parse(static_path) + assert not static.is_pie + +def test_pie(): + pie_path = get_sample('ELF/batch-x86-64/test.go.pie.bin') + pie = lief.parse(pie_path) + assert pie.is_pie + +def test_non_pie(): + not_pie_path = get_sample('ELF/ELF32_x86_library_libshellx.so') + not_pie = lief.parse(not_pie_path) + assert not not_pie.is_pie + +def test_non_pie_bin(): + path = get_sample('ELF/ELF64_x86-64_binary_ls.bin') + target = lief.parse(path) + assert not target.is_pie diff --git a/vendor/lief/tests/elf/test_760.py b/vendor/lief/tests/elf/test_760.py new file mode 100755 index 0000000..6a8011c --- /dev/null +++ b/vendor/lief/tests/elf/test_760.py @@ -0,0 +1,18 @@ +#!/usr/bin/env python +import pytest + +import lief +import pathlib + +from utils import get_sample + +def test_zero_export(): + """ + Check that LIEF does not skip an exported function + that is located at the address 0 + """ + triton_stub = get_sample('ELF/triton-x8664-systemv-stubs.o') + triton_stub = lief.parse(triton_stub) + exports = {s.name for s in triton_stub.exported_functions} + assert "memccpy" in exports + diff --git a/vendor/lief/tests/elf/test_parser.py b/vendor/lief/tests/elf/test_parser.py index 2022c24..9c9e415 100644 --- a/vendor/lief/tests/elf/test_parser.py +++ b/vendor/lief/tests/elf/test_parser.py @@ -256,7 +256,7 @@ def test_tiny(self): self.assertEqual(self.target.segments[0].physical_size, 0x17fffff2) self.assertEqual(len(self.target.segments[0].content), 84) if is_64bits_platform(): - self.assertEqual(lief.hash(self.target.segments[0].content), 18446744073657409468) + self.assertEqual(lief.hash(self.target.segments[0].content), 2547808573126369212) class TestCorruptedIdentity(TestCase): diff --git a/vendor/lief/tests/elf/test_symbol_versions.py b/vendor/lief/tests/elf/test_symbol_versions.py new file mode 100644 index 0000000..f5e28fe --- /dev/null +++ b/vendor/lief/tests/elf/test_symbol_versions.py @@ -0,0 +1,15 @@ +import pytest + +import lief +import pathlib + +from utils import get_sample + +def test_issue_749(): + lib_path = get_sample('ELF/lib_symbol_versions.so') + lib: lief.ELF.Binary = lief.parse(lib_path) + sym = lib.get_dynamic_symbol("foo") + assert sym.symbol_version.symbol_version_auxiliary.name == "LIBFOO_2.0" + + + diff --git a/vendor/lief/tests/pe/test_parser.py b/vendor/lief/tests/pe/test_parser.py index 25a2cd3..9f6c8c6 100644 --- a/vendor/lief/tests/pe/test_parser.py +++ b/vendor/lief/tests/pe/test_parser.py @@ -171,8 +171,8 @@ def test_sections(): assert sections[0].numberof_line_numbers == 0x0 assert int(sections[0].characteristics) == 0x68000020 if is_64bits_platform(): - assert lief.hash(list(sections[0].padding)) == 0xffffffffc691aee8 - assert lief.hash(list(sections[0].content)) == 0x2023e2e + assert lief.hash(list(sections[0].padding)) == 16581494691545067240 + assert lief.hash(list(sections[0].content)) == 12119947047017266734 assert sections[1].name == ".rdata" assert sections[1].virtual_size == 0x2b4 @@ -186,8 +186,8 @@ def test_sections(): assert int(sections[1].characteristics) == 0x48000040 if is_64bits_platform(): - assert lief.hash(list(sections[1].padding)) == 0xffffffffdc061565 - assert lief.hash(list(sections[1].content)) == 0x7f4ae4d9 + assert lief.hash(list(sections[1].padding)) == 13095545801059734885 + assert lief.hash(list(sections[1].content)) == 6944188420063945945 assert sections[2].name == ".data" assert sections[2].virtual_size == 0x114 @@ -201,8 +201,8 @@ def test_sections(): assert int(sections[2].characteristics) == 0xc8000040 if is_64bits_platform(): - assert lief.hash(list(sections[2].padding)) == 0x391e5290 - assert lief.hash(list(sections[2].content)) == 0x2109ac81 + assert lief.hash(list(sections[2].padding)) == 16286773346125632144 + assert lief.hash(list(sections[2].content)) == 7978755463523708033 assert sections[3].name == ".pdata" assert sections[3].virtual_size == 0x1e0 @@ -216,8 +216,8 @@ def test_sections(): assert int(sections[3].characteristics) == 0x48000040 if is_64bits_platform(): - assert lief.hash(list(sections[3].padding)) == 0xd5f2925 - assert lief.hash(list(sections[3].content)) == 0x13f38a3e + assert lief.hash(list(sections[3].padding)) == 10388213471796734245 + assert lief.hash(list(sections[3].content)) == 2565729174231943742 assert sections[4].name == "INIT" assert sections[4].virtual_size == 0x42a @@ -231,8 +231,8 @@ def test_sections(): assert int(sections[4].characteristics) == 0xe2000020 if is_64bits_platform(): - assert lief.hash(list(sections[4].padding)) == 0xffffffff93471cc1 - assert lief.hash(list(sections[4].content)) == 0xffffffffb3ea2b8b + assert lief.hash(list(sections[4].padding)) == 6267801405663681729 + assert lief.hash(list(sections[4].content)) == 9792162199629343627 assert sections[5].name == ".rsrc" assert sections[5].virtual_size == 0x3f0 @@ -246,8 +246,8 @@ def test_sections(): assert int(sections[5].characteristics) == 0x42000040 if is_64bits_platform(): - assert lief.hash(list(sections[5].padding)) == 0x28ec37bb - assert lief.hash(list(sections[5].content)) == 0x65f49890 + assert lief.hash(list(sections[5].padding)) == 2694043916712032187 + assert lief.hash(list(sections[5].content)) == 17560174430803761296 def test_tls(): assert winhello64.has_tls diff --git a/vendor/lief/tests/pe/test_resources.py b/vendor/lief/tests/pe/test_resources.py index 93347a1..9233437 100644 --- a/vendor/lief/tests/pe/test_resources.py +++ b/vendor/lief/tests/pe/test_resources.py @@ -18,7 +18,7 @@ from subprocess import Popen from unittest import TestCase -from utils import get_sample +from utils import get_sample, is_64bits_platform class TestResource(TestCase): def setUp(self): @@ -192,7 +192,8 @@ def test_resource_dialogs(self): evince = lief.parse(fbytes) manager = evince.resources_manager - self.assertEqual(lief.hash(manager.manifest), 0x762c0ae9) + if is_64bits_platform(): + self.assertEqual(lief.hash(manager.manifest), 16239254889843919593) self.assertEqual(len(manager.dialogs), 15) dialog = manager.dialogs[0]