diff --git a/include/libhat/Defines.hpp b/include/libhat/Defines.hpp index e27d1c0..118aff2 100644 --- a/include/libhat/Defines.hpp +++ b/include/libhat/Defines.hpp @@ -30,3 +30,9 @@ #define LIBHAT_BLSR64(num) num & (num - 1) #endif #endif + +#if __cpp_if_consteval >= 202106L + #define LIBHAT_IF_CONSTEVAL consteval +#else + #define LIBHAT_IF_CONSTEVAL (std::is_constant_evaluated()) +#endif diff --git a/include/libhat/ScanMode.hpp b/include/libhat/ScanMode.hpp deleted file mode 100644 index 08b3b12..0000000 --- a/include/libhat/ScanMode.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once - -namespace hat { - - enum class scan_mode { - Search, - FastFirst, - AVX2, - AVX512, - Neon - }; - - template - scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature); -} diff --git a/include/libhat/Scanner.hpp b/include/libhat/Scanner.hpp index 5158778..4ef9f1a 100644 --- a/include/libhat/Scanner.hpp +++ b/include/libhat/Scanner.hpp @@ -2,8 +2,10 @@ #include #include +#include #include +#include "Defines.hpp" #include "Process.hpp" #include "Signature.hpp" @@ -47,6 +49,46 @@ namespace hat { std::byte* result; }; + namespace detail { + + enum class scan_mode { + Auto, + Search, + FastFirst, + AVX2, + AVX512, + Neon + }; + + template + scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature); + + template<> + scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature); + + template<> + constexpr scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { + const auto firstByte = *signature[0]; + const auto scanEnd = end - signature.size() + 1; + + for (auto i = begin; i != scanEnd; i++) { + // Use std::find to efficiently find the first byte + i = std::find(std::execution::unseq, i, scanEnd, firstByte); + if (i == scanEnd) { + break; + } + // Compare everything after the first byte + auto match = std::equal(signature.begin() + 1, signature.end(), i + 1, [](auto opt, auto byte) { + return !opt.has_value() || *opt == byte; + }); + if (match) { + return i; + } + } + return nullptr; + } + } + enum class compiler_type { MSVC, MinGW @@ -73,9 +115,15 @@ namespace hat { ); /// Root implementation of FindPattern - scan_result find_pattern( + constexpr scan_result find_pattern( std::byte* begin, std::byte* end, signature_view signature - ); + ) { + if LIBHAT_IF_CONSTEVAL { + return detail::find_pattern(begin, end, signature); + } else { + return detail::find_pattern(begin, end, signature); + } + } } diff --git a/src/Scanner.cpp b/src/Scanner.cpp index 676f2d2..1e5a5e0 100644 --- a/src/Scanner.cpp +++ b/src/Scanner.cpp @@ -1,11 +1,9 @@ #include #include -#include #include #include -#include namespace hat { @@ -90,6 +88,9 @@ namespace hat { } return find_pattern(std::to_address(data.begin()), std::to_address(data.end()), signature); } +} + +namespace hat::detail { template<> [[deprecated]] scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { @@ -103,28 +104,7 @@ namespace hat { } template<> - scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { - const auto firstByte = *signature[0]; - const auto scanEnd = end - signature.size() + 1; - - for (auto i = begin; i != scanEnd; i++) { - // Use std::find to efficiently find the first byte - i = std::find(std::execution::unseq, i, scanEnd, firstByte); - if (i == scanEnd) { - break; - } - // Compare everything after the first byte - auto match = std::equal(signature.begin() + 1, signature.end(), i + 1, [](auto opt, auto byte) { - return !opt.has_value() || *opt == byte; - }); - if (match) { - return i; - } - } - return nullptr; - } - - scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { + scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { const auto size = signature.size(); #if defined(LIBHAT_X86) const auto& ext = get_system().extensions; diff --git a/src/arch/arm/Neon.cpp b/src/arch/arm/Neon.cpp index 095f7d9..659ca23 100644 --- a/src/arch/arm/Neon.cpp +++ b/src/arch/arm/Neon.cpp @@ -2,9 +2,8 @@ #ifdef LIBHAT_ARM #include -#include -namespace hat { +namespace hat::detail { template<> scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { diff --git a/src/arch/x86/AVX2.cpp b/src/arch/x86/AVX2.cpp index 9dddcf7..2e9ad8f 100644 --- a/src/arch/x86/AVX2.cpp +++ b/src/arch/x86/AVX2.cpp @@ -3,11 +3,10 @@ #ifdef LIBHAT_X86 #include -#include #include -namespace hat { +namespace hat::detail { template<> scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) { diff --git a/src/arch/x86/AVX512.cpp b/src/arch/x86/AVX512.cpp index 211b8df..b099a26 100644 --- a/src/arch/x86/AVX512.cpp +++ b/src/arch/x86/AVX512.cpp @@ -2,11 +2,10 @@ #ifdef LIBHAT_X86 #include -#include #include -namespace hat { +namespace hat::detail { template<> scan_result find_pattern(std::byte* begin, std::byte* end, signature_view signature) {