diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 0d25599..e6d9977 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,7 +11,7 @@ on: jobs: lint: - runs-on: ubuntu-latest + runs-on: ubuntu-18.04 steps: - uses: actions/checkout@v2 @@ -30,7 +30,7 @@ jobs: pe-parse: strategy: matrix: - platform: ["ubuntu-latest", "macos-latest"] + platform: ["ubuntu-18.04", "macos-latest"] build-type: ["Debug", "Release"] build-shared: ["0", "1"] compiler: @@ -42,6 +42,8 @@ jobs: runs-on: ${{ matrix.platform }} steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: build env: CC: ${{ matrix.compiler.CC }} @@ -52,16 +54,20 @@ jobs: cmake \ -DCMAKE_BUILD_TYPE=${{ matrix.build-type }} \ -DBUILD_SHARED_LIBS=${{ matrix.build-shared }} \ + -DPEPARSE_ENABLE_TESTING=ON \ .. cmake --build . - name: test + env: + CTEST_OUTPUT_ON_FAILURE: 1 run: | - ./build/dump-pe/dump-pe ./test/assets/example.exe + cd build && ctest -V + ./dump-pe/dump-pe ../tests/assets/example.exe pepy: strategy: matrix: - platform: ["ubuntu-latest", "macos-latest"] + platform: ["ubuntu-18.04", "macos-latest"] python: - "3.6" - "3.7" @@ -81,7 +87,7 @@ jobs: python3 -m pip install --user dist/*.tar.gz - name: test run: | - python3 test/test_pepy.py test/assets/example.exe + python3 tests/test_pepy.py tests/assets/example.exe pe-parse-windows: strategy: @@ -92,6 +98,8 @@ jobs: runs-on: windows-latest steps: - uses: actions/checkout@v2 + with: + submodules: 'true' - name: build run: | mkdir build @@ -100,15 +108,20 @@ jobs: -G "Visual Studio 16 2019" ` -A ${{ matrix.build-arch }} ` -DBUILD_SHARED_LIBS=${{ matrix.build-shared }} ` + -DPEPARSE_ENABLE_TESTING=ON ` .. cmake --build . --config ${{ matrix.build-type }} - name: install run: | cd build - cmake --build . --target install + cmake --build . --config ${{ matrix.build-type }} --target install - name: test + env: + CTEST_OUTPUT_ON_FAILURE: 1 run: | - .\build\bin\dump-pe.exe .\test\assets\example.exe + cd build + ctest -V + .\bin\dump-pe.exe ..\tests\assets\example.exe pepy-windows: strategy: @@ -131,4 +144,4 @@ jobs: python -m pip install --user . - name: test run: | - python test/test_pepy.py test/assets/example.exe + python tests/test_pepy.py tests/assets/example.exe diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..c215120 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "test/assets/corkami-poc-dataset"] + path = tests/assets/corkami-poc-dataset + url = https://github.com/corkami/pocs diff --git a/CMakeLists.txt b/CMakeLists.txt index ff1f191..abccbe5 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,9 @@ if (NOT CMAKE_BUILD_TYPE) endif () include(cmake/compilation_flags.cmake) +# Greater c++17 filesystem compatibility (like with experimental) +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") +find_package(Filesystem COMPONENTS Experimental Final REQUIRED) list(APPEND GLOBAL_CXXFLAGS ${DEFAULT_CXX_FLAGS}) option(BUILD_SHARED_LIBS "Build Shared Libraries" ON) @@ -45,6 +48,8 @@ file( dump-pe/*.cpp examples/*.cpp examples/*.h + tests/*.cpp + tests/*.h ) add_custom_target( peparse_format @@ -58,3 +63,9 @@ message(STATUS "Build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Build Shared: ${BUILD_SHARED_LIBS} ${BUILD_SHARED_LIBS_MESSAGE}") message(STATUS "Build Command Line Tools: ${BUILD_COMMAND_LINE_TOOLS}") message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}") + +option(PEPARSE_ENABLE_TESTING "Enable building tests" OFF) +if (PEPARSE_ENABLE_TESTING) + enable_testing() + add_subdirectory(tests) +endif() diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c08017d..1aaef10 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -10,7 +10,7 @@ automatically prompted to sign it during your first PR. ## General contribution guidelines -* Your changes should be valid C++11 +* Your changes should be valid C++17 * Your changes should work across all major compiler vendors (GCC, Clang, MSVC) and all major operating systems (Linux, macOS, Windows) * Your changes should be auto-formatted with `clang-format -style=file` diff --git a/README.md b/README.md index 3ba8351..12371c5 100644 --- a/README.md +++ b/README.md @@ -88,6 +88,12 @@ cmake -G "Visual Studio 16 2019" -A Win64 .. cmake --build . --config Release ``` +## Testing + +You can build the (catch2-based) tests by adding `-DPEPARSE_ENABLE_TESTING=ON` during CMake configuration. Build, and then run with `ctest` or `cmake --build . --target test`. + +To run the full test suite with the [Corkami test suite](https://github.com/corkami/pocs/tree/master/PE), you must clone the submodule with `git submodule update --init`. + ## Using the library Once the library is installed, linking to it is easy! Add the following lines in your CMake project: diff --git a/cmake/compilation_flags.cmake b/cmake/compilation_flags.cmake index 140a669..b856209 100644 --- a/cmake/compilation_flags.cmake +++ b/cmake/compilation_flags.cmake @@ -1,3 +1,7 @@ +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + if (MSVC) list(APPEND DEFAULT_CXX_FLAGS /W4 /analyze) @@ -10,10 +14,6 @@ if (MSVC) endif () else () - set(CMAKE_CXX_STANDARD 11) - set(CMAKE_CXX_STANDARD_REQUIRED ON) - set(CMAKE_CXX_EXTENSIONS OFF) - if (NOT MINGW) list(APPEND DEFAULT_CXX_FLAGS -fPIC) endif () diff --git a/cmake/modules/FindFilesystem.cmake b/cmake/modules/FindFilesystem.cmake new file mode 100644 index 0000000..8b28f7e --- /dev/null +++ b/cmake/modules/FindFilesystem.cmake @@ -0,0 +1,250 @@ +# Distributed under the OSI-approved BSD 3-Clause License. See accompanying +# file Copyright.txt or https://cmake.org/licensing for details. + +# Copied from https://github.com/vector-of-bool/CMakeCM/tree/6cb8a6ada09eb40c271d2f83a032e03cd4005fa3/modules/FindFilesystem.cmake +# Latest commit as of March 10, 2021 + +#[=======================================================================[.rst: + +FindFilesystem +############## + +This module supports the C++17 standard library's filesystem utilities. Use the +:imp-target:`std::filesystem` imported target to + +Options +******* + +The ``COMPONENTS`` argument to this module supports the following values: + +.. find-component:: Experimental + :name: fs.Experimental + + Allows the module to find the "experimental" Filesystem TS version of the + Filesystem library. This is the library that should be used with the + ``std::experimental::filesystem`` namespace. + +.. find-component:: Final + :name: fs.Final + + Finds the final C++17 standard version of the filesystem library. + +If no components are provided, behaves as if the +:find-component:`fs.Final` component was specified. + +If both :find-component:`fs.Experimental` and :find-component:`fs.Final` are +provided, first looks for ``Final``, and falls back to ``Experimental`` in case +of failure. If ``Final`` is found, :imp-target:`std::filesystem` and all +:ref:`variables ` will refer to the ``Final`` version. + + +Imported Targets +**************** + +.. imp-target:: std::filesystem + + The ``std::filesystem`` imported target is defined when any requested + version of the C++ filesystem library has been found, whether it is + *Experimental* or *Final*. + + If no version of the filesystem library is available, this target will not + be defined. + + .. note:: + This target has ``cxx_std_17`` as an ``INTERFACE`` + :ref:`compile language standard feature `. Linking + to this target will automatically enable C++17 if no later standard + version is already required on the linking target. + + +.. _fs.variables: + +Variables +********* + +.. variable:: CXX_FILESYSTEM_IS_EXPERIMENTAL + + Set to ``TRUE`` when the :find-component:`fs.Experimental` version of C++ + filesystem library was found, otherwise ``FALSE``. + +.. variable:: CXX_FILESYSTEM_HAVE_FS + + Set to ``TRUE`` when a filesystem header was found. + +.. variable:: CXX_FILESYSTEM_HEADER + + Set to either ``filesystem`` or ``experimental/filesystem`` depending on + whether :find-component:`fs.Final` or :find-component:`fs.Experimental` was + found. + +.. variable:: CXX_FILESYSTEM_NAMESPACE + + Set to either ``std::filesystem`` or ``std::experimental::filesystem`` + depending on whether :find-component:`fs.Final` or + :find-component:`fs.Experimental` was found. + + +Examples +******** + +Using `find_package(Filesystem)` with no component arguments: + +.. code-block:: cmake + + find_package(Filesystem REQUIRED) + + add_executable(my-program main.cpp) + target_link_libraries(my-program PRIVATE std::filesystem) + + +#]=======================================================================] + + +if(TARGET std::filesystem) + # This module has already been processed. Don't do it again. + return() +endif() + +cmake_minimum_required(VERSION 3.10) + +include(CMakePushCheckState) +include(CheckIncludeFileCXX) + +# If we're not cross-compiling, try to run test executables. +# Otherwise, assume that compile + link is a sufficient check. +if(CMAKE_CROSSCOMPILING) + include(CheckCXXSourceCompiles) + macro(_cmcm_check_cxx_source code var) + check_cxx_source_compiles("${code}" ${var}) + endmacro() +else() + include(CheckCXXSourceRuns) + macro(_cmcm_check_cxx_source code var) + check_cxx_source_runs("${code}" ${var}) + endmacro() +endif() + +cmake_push_check_state() + +set(CMAKE_REQUIRED_QUIET ${Filesystem_FIND_QUIETLY}) + +# All of our tests required C++17 or later +set(CMAKE_CXX_STANDARD 17) + +# Normalize and check the component list we were given +set(want_components ${Filesystem_FIND_COMPONENTS}) +if(Filesystem_FIND_COMPONENTS STREQUAL "") + set(want_components Final) +endif() + +# Warn on any unrecognized components +set(extra_components ${want_components}) +list(REMOVE_ITEM extra_components Final Experimental) +foreach(component IN LISTS extra_components) + message(WARNING "Extraneous find_package component for Filesystem: ${component}") +endforeach() + +# Detect which of Experimental and Final we should look for +set(find_experimental TRUE) +set(find_final TRUE) +if(NOT "Final" IN_LIST want_components) + set(find_final FALSE) +endif() +if(NOT "Experimental" IN_LIST want_components) + set(find_experimental FALSE) +endif() + +if(find_final) + check_include_file_cxx("filesystem" _CXX_FILESYSTEM_HAVE_HEADER) + mark_as_advanced(_CXX_FILESYSTEM_HAVE_HEADER) + if(_CXX_FILESYSTEM_HAVE_HEADER) + # We found the non-experimental header. Don't bother looking for the + # experimental one. + set(find_experimental FALSE) + endif() +else() + set(_CXX_FILESYSTEM_HAVE_HEADER FALSE) +endif() + +if(find_experimental) + check_include_file_cxx("experimental/filesystem" _CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) + mark_as_advanced(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) +else() + set(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER FALSE) +endif() + +if(_CXX_FILESYSTEM_HAVE_HEADER) + set(_have_fs TRUE) + set(_fs_header filesystem) + set(_fs_namespace std::filesystem) + set(_is_experimental FALSE) +elseif(_CXX_FILESYSTEM_HAVE_EXPERIMENTAL_HEADER) + set(_have_fs TRUE) + set(_fs_header experimental/filesystem) + set(_fs_namespace std::experimental::filesystem) + set(_is_experimental TRUE) +else() + set(_have_fs FALSE) +endif() + +set(CXX_FILESYSTEM_HAVE_FS ${_have_fs} CACHE BOOL "TRUE if we have the C++ filesystem headers") +set(CXX_FILESYSTEM_HEADER ${_fs_header} CACHE STRING "The header that should be included to obtain the filesystem APIs") +set(CXX_FILESYSTEM_NAMESPACE ${_fs_namespace} CACHE STRING "The C++ namespace that contains the filesystem APIs") +set(CXX_FILESYSTEM_IS_EXPERIMENTAL ${_is_experimental} CACHE BOOL "TRUE if the C++ filesystem library is the experimental version") + +set(_found FALSE) + +if(CXX_FILESYSTEM_HAVE_FS) + # We have some filesystem library available. Do link checks + string(CONFIGURE [[ + #include + #include <@CXX_FILESYSTEM_HEADER@> + + int main() { + auto cwd = @CXX_FILESYSTEM_NAMESPACE@::current_path(); + printf("%s", cwd.c_str()); + return EXIT_SUCCESS; + } + ]] code @ONLY) + + # Check a simple filesystem program without any linker flags + _cmcm_check_cxx_source("${code}" CXX_FILESYSTEM_NO_LINK_NEEDED) + + set(can_link ${CXX_FILESYSTEM_NO_LINK_NEEDED}) + + if(NOT CXX_FILESYSTEM_NO_LINK_NEEDED) + set(prev_libraries ${CMAKE_REQUIRED_LIBRARIES}) + # Add the libstdc++ flag + set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lstdc++fs) + _cmcm_check_cxx_source("${code}" CXX_FILESYSTEM_STDCPPFS_NEEDED) + set(can_link ${CXX_FILESYSTEM_STDCPPFS_NEEDED}) + if(NOT CXX_FILESYSTEM_STDCPPFS_NEEDED) + # Try the libc++ flag + set(CMAKE_REQUIRED_LIBRARIES ${prev_libraries} -lc++fs) + _cmcm_check_cxx_source("${code}" CXX_FILESYSTEM_CPPFS_NEEDED) + set(can_link ${CXX_FILESYSTEM_CPPFS_NEEDED}) + endif() + endif() + + if(can_link) + add_library(std::filesystem INTERFACE IMPORTED) + set_property(TARGET std::filesystem APPEND PROPERTY INTERFACE_COMPILE_FEATURES cxx_std_17) + set(_found TRUE) + + if(CXX_FILESYSTEM_NO_LINK_NEEDED) + # Nothing to add... + elseif(CXX_FILESYSTEM_STDCPPFS_NEEDED) + set_property(TARGET std::filesystem APPEND PROPERTY INTERFACE_LINK_LIBRARIES -lstdc++fs) + elseif(CXX_FILESYSTEM_CPPFS_NEEDED) + set_property(TARGET std::filesystem APPEND PROPERTY INTERFACE_LINK_LIBRARIES -lc++fs) + endif() + endif() +endif() + +cmake_pop_check_state() + +set(Filesystem_FOUND ${_found} CACHE BOOL "TRUE if we can run a program using std::filesystem" FORCE) + +if(Filesystem_FIND_REQUIRED AND NOT Filesystem_FOUND) + message(FATAL_ERROR "Cannot run simple program using std::filesystem") +endif() diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt new file mode 100644 index 0000000..005c65d --- /dev/null +++ b/tests/CMakeLists.txt @@ -0,0 +1,47 @@ +include(CTest) + +# Path for corkami dataset +set(CORKAMI_SUBMODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/assets/corkami-poc-dataset") +set(CORKAMI_PE_PATH "${CORKAMI_SUBMODULE_PATH}/PE/bin") + +if (NOT EXISTS "${CORKAMI_PE_PATH}") + message(WARNING "Could not find Corkami dataset for testing.\nUse 'git submodule update --init'") +endif() + +# To reconfigure and rebuild when submodule status changes +# See https://gitlab.kitware.com/cmake/cmake/-/issues/18755 to read why using +# (potentially non-existant) CORKAMI_PE_PATH doesn't work +set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS "${CORKAMI_SUBMODULE_PATH}") + +if (NOT USE_EXTERNAL_CATCH2) + include("${CMAKE_CURRENT_SOURCE_DIR}/cmake/catch.cmake.in") +else() + find_package(Catch2 REQUIRED) +endif() + +add_executable(tests + test_main.cpp + simple_test.cpp + corkami_test.cpp + + filesystem_compat.h + ) +target_compile_definitions(tests PRIVATE ASSETS_DIR="${CMAKE_CURRENT_SOURCE_DIR}/assets") +target_link_libraries(tests PRIVATE std::filesystem ${PROJECT_NAME} Catch2::Catch2) +target_include_directories(tests PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + +if (EXISTS "${CORKAMI_PE_PATH}") + target_compile_definitions(tests PRIVATE CORKAMI_PE_PATH="${CORKAMI_PE_PATH}") +endif() + +if (WIN32 AND BUILD_SHARED_LIBS) + # Workaround for shared lib loading in Windows. + # Need to copy all dependent DLLs to the same directory + add_custom_command (TARGET tests POST_BUILD + COMMAND ${CMAKE_COMMAND} -E copy_if_different + $ $ + ) +endif() + +include(Catch) +catch_discover_tests(tests) diff --git a/tests/assets/corkami-poc-dataset b/tests/assets/corkami-poc-dataset new file mode 160000 index 0000000..befb363 --- /dev/null +++ b/tests/assets/corkami-poc-dataset @@ -0,0 +1 @@ +Subproject commit befb3632214640a4af20be3b463f41e4b82f04f6 diff --git a/test/assets/example.exe b/tests/assets/example.exe similarity index 100% rename from test/assets/example.exe rename to tests/assets/example.exe diff --git a/tests/cmake/catch.cmake.in b/tests/cmake/catch.cmake.in new file mode 100644 index 0000000..73f5c9b --- /dev/null +++ b/tests/cmake/catch.cmake.in @@ -0,0 +1,9 @@ +Include(FetchContent) + +FetchContent_Declare( + Catch2 + GIT_REPOSITORY https://github.com/catchorg/Catch2.git + GIT_TAG v2.13.4) + +FetchContent_MakeAvailable(Catch2) +list(APPEND CMAKE_MODULE_PATH ${catch2_SOURCE_DIR}/contrib) diff --git a/tests/corkami_test.cpp b/tests/corkami_test.cpp new file mode 100644 index 0000000..d2f7404 --- /dev/null +++ b/tests/corkami_test.cpp @@ -0,0 +1,74 @@ +#include + +#include +#include +#include +#include + +#include "filesystem_compat.h" + +// Whether the corkami testset has been downloaded +// Path to corkami PEs +#if defined(CORKAMI_PE_PATH) + +// Return a vector of all PE files immediately under `dir` +static std::vector PEFilesInDir(const fs::path &dir) { + std::vector all_entries; + if (!fs::exists(dir)) { + return all_entries; + } + + for (const auto &entry : fs::directory_iterator(dir)) { + if ((entry.path().extension() == ".exe" || + entry.path().extension() == ".dll" || + entry.path().extension() == ".sys") && + fs::is_regular_file(entry)) { + all_entries.emplace_back(entry.path()); + } + } + return all_entries; +} + +namespace peparse { + +static const std::unordered_set kKnownPEFailure{ + "virtsectblXP.exe", "maxsec_lowaligW7.exe", + "maxsecXP.exe", "nullSOH-XP.exe", + "tinyXP.exe", "tinydllXP.dll", + "virtrelocXP.exe", "foldedhdrW7.exe", + "maxvals.exe", "d_nonnull.dll", + "reloccrypt.exe", "d_resource.dll", + "fakerelocs.exe", "lfanew_relocW7.exe", + "bigSoRD.exe", "tinyW7.exe", + "reloccryptW8.exe", "standard.exe", + "exe2pe.exe", "tinygui.exe", + "dllfwloop.dll", "tinydrivXP.sys", + "tiny.exe", "tinydll.dll", + "foldedhdr.exe", "dllmaxvals.dll", + "reloccryptXP.exe", "dosZMXP.exe", + "tinyW7_3264.exe", "dllfw.dll", + "hdrcode.exe", "ibrelocW7.exe", + "d_tiny.dll", "sc.exe"}; + +TEST_CASE("Corkami PEs smoketest", "[corkami]") { + for (fs::path path : PEFilesInDir(CORKAMI_PE_PATH)) { + std::string pe_name = path.filename().string(); + SECTION(pe_name) { + parsed_pe *p = ParsePEFromFile(path.string().c_str()); + + if (kKnownPEFailure.count(pe_name)) { + CHECKED_ELSE(!p) { + FAIL("Previously failing test now passes! Remove from set"); + } + } else { + CHECKED_ELSE(p) { + FAIL(GetPEErrString() + " at " + GetPEErrLoc()); + } + DestructParsedPE(p); + } + } + } +} + +} // namespace peparse +#endif diff --git a/tests/filesystem_compat.h b/tests/filesystem_compat.h new file mode 100644 index 0000000..0d8d055 --- /dev/null +++ b/tests/filesystem_compat.h @@ -0,0 +1,12 @@ +// This header is for C++17 filesystem compatibility for different versions of +// compilers and c++ standard libraries header placement + +#if __has_include() +#include +namespace fs = std::filesystem; +#elif __has_include() +#include +namespace fs = std::experimental::filesystem; +#else +#error "no filesystem support" +#endif diff --git a/tests/simple_test.cpp b/tests/simple_test.cpp new file mode 100644 index 0000000..42b153e --- /dev/null +++ b/tests/simple_test.cpp @@ -0,0 +1,52 @@ +#include + +#include + +#include "filesystem_compat.h" + +namespace peparse { + +TEST_CASE("Simple testing of PE", "[example]") { + fs::path path = fs::path(ASSETS_DIR) / "example.exe"; + parsed_pe *p = ParsePEFromFile(path.string().c_str()); + + REQUIRE(p); + + SECTION("dos header correctness") { + auto dos = p->peHeader.dos; + REQUIRE(dos.e_magic == 0x5a4d); + REQUIRE(dos.e_cp == 0x3); + REQUIRE(dos.e_crlc == 0x0); + REQUIRE(dos.e_cparhdr == 0x4); + REQUIRE(dos.e_minalloc == 0x0); + REQUIRE(dos.e_maxalloc == 0xffff); + REQUIRE(dos.e_ss == 0x0); + REQUIRE(dos.e_sp == 0xb8); + REQUIRE(dos.e_csum == 0x0); + REQUIRE(dos.e_ip == 0x0); + REQUIRE(dos.e_cs == 0x0); + REQUIRE(dos.e_lfarlc == 0x40); + REQUIRE(dos.e_ovno == 0x0); + REQUIRE(dos.e_res[0] == 0x0); + REQUIRE(dos.e_res[1] == 0x0); + REQUIRE(dos.e_res[2] == 0x0); + REQUIRE(dos.e_res[3] == 0x0); + REQUIRE(dos.e_oemid == 0x0); + REQUIRE(dos.e_oeminfo == 0x0); + REQUIRE(dos.e_res2[0] == 0x0); + REQUIRE(dos.e_res2[1] == 0x0); + REQUIRE(dos.e_res2[2] == 0x0); + REQUIRE(dos.e_res2[3] == 0x0); + REQUIRE(dos.e_res2[4] == 0x0); + REQUIRE(dos.e_res2[5] == 0x0); + REQUIRE(dos.e_res2[6] == 0x0); + REQUIRE(dos.e_res2[7] == 0x0); + REQUIRE(dos.e_res2[8] == 0x0); + REQUIRE(dos.e_res2[9] == 0x0); + REQUIRE(dos.e_lfanew == 0xf8); + } + + DestructParsedPE(p); +} + +} // namespace peparse diff --git a/tests/test_main.cpp b/tests/test_main.cpp new file mode 100644 index 0000000..bf06436 --- /dev/null +++ b/tests/test_main.cpp @@ -0,0 +1,7 @@ +// In a Catch project with multiple files, dedicate one file to compile the +// source code of Catch itself and reuse the resulting object file for linking. + +// Let Catch provide main(): +#define CATCH_CONFIG_MAIN + +#include diff --git a/test/test_pepy.py b/tests/test_pepy.py similarity index 100% rename from test/test_pepy.py rename to tests/test_pepy.py