diff options
| -rw-r--r-- | src/cs2/hack.cpp | 2 | ||||
| -rw-r--r-- | src/heavens-gate.vcxproj | 1 | ||||
| -rw-r--r-- | src/heavens-gate.vcxproj.filters | 3 | ||||
| -rw-r--r-- | src/menu.cpp | 4 | ||||
| -rw-r--r-- | src/xorstr.hpp | 200 |
5 files changed, 208 insertions, 2 deletions
diff --git a/src/cs2/hack.cpp b/src/cs2/hack.cpp index c98337a..a9be030 100644 --- a/src/cs2/hack.cpp +++ b/src/cs2/hack.cpp @@ -20,7 +20,7 @@ PROCESS64* hack_init() { } bool hack_run( PROCESS64* p ) { - perf_run_metric( perf_loop_start ); + perf_run_metric( perf_loop_begin ); CS2* cs = (CS2*)p; for( I32 i = 0; i < 64; ++i ) { diff --git a/src/heavens-gate.vcxproj b/src/heavens-gate.vcxproj index e2e0742..ed749c5 100644 --- a/src/heavens-gate.vcxproj +++ b/src/heavens-gate.vcxproj @@ -236,6 +236,7 @@ <ClInclude Include="vec3.h" /> <ClInclude Include="winintern.h" /> <ClInclude Include="x86.h" /> + <ClInclude Include="xorstr.hpp" /> </ItemGroup> <ItemGroup> <Image Include="..\resource\heavens-gate-ico.ico" /> diff --git a/src/heavens-gate.vcxproj.filters b/src/heavens-gate.vcxproj.filters index 25a909f..ecd163a 100644 --- a/src/heavens-gate.vcxproj.filters +++ b/src/heavens-gate.vcxproj.filters @@ -96,6 +96,9 @@ <ClInclude Include="color.h"> <Filter>Util</Filter> </ClInclude> + <ClInclude Include="xorstr.hpp"> + <Filter>Util</Filter> + </ClInclude> </ItemGroup> <ItemGroup> <Filter Include="Console"> diff --git a/src/menu.cpp b/src/menu.cpp index 27c8bae..c94fde6 100644 --- a/src/menu.cpp +++ b/src/menu.cpp @@ -6,6 +6,8 @@ #include "cs2/hack.h" +#include "xorstr.hpp" + PROCESS64* cs2p; I32 perf_tickrate = 2048; @@ -351,7 +353,7 @@ void menu_show_ui( PROCESS64 *p ) { show_paging( 1 ); con_set_bottomline_text( - "LOCALPLAYER: %08X | FLAGS: %08X | menu", + xorstr( "LOCALPLAYER: %08X | FLAGS: %08X | menu" ).get(), 0x0,0x0 ); }
\ No newline at end of file diff --git a/src/xorstr.hpp b/src/xorstr.hpp new file mode 100644 index 0000000..1bcea88 --- /dev/null +++ b/src/xorstr.hpp @@ -0,0 +1,200 @@ +#ifndef JM_XORSTR_HPP +#define JM_XORSTR_HPP + +#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__) +#include <arm_neon.h> +#elif defined(_M_X64) || defined(__amd64__) || defined(_M_IX86) || defined(__i386__) +#include <immintrin.h> +#else +#error Unsupported platform +#endif + +#include <cstdint> +#include <cstddef> +#include <utility> +#include <type_traits> + +#define JM_XORSTR_DISABLE_AVX_INTRINSICS + +#define xorstr(str) ::jm::xor_string([]() { return str; }, std::integral_constant<std::size_t, sizeof(str) / sizeof(*str)>{}, std::make_index_sequence<::jm::detail::_buffer_size<sizeof(str)>()>{}) +#define xorstr_(str) xorstr(str).crypt_get() + +#ifdef _MSC_VER +#define XORSTR_FORCEINLINE __forceinline +#else +#define XORSTR_FORCEINLINE __attribute__((always_inline)) inline +#endif + +namespace jm { + namespace detail { + template<std::size_t Size> + XORSTR_FORCEINLINE constexpr std::size_t _buffer_size() { return ((Size / 16) + (Size % 16 != 0)) * 2; } + + template<std::uint32_t Seed> + XORSTR_FORCEINLINE constexpr std::uint32_t key4() noexcept + { + std::uint32_t value = Seed; + for(char c : __TIME__) + value = static_cast<std::uint32_t>((value ^ c) * 16777619ull); + return value; + } + + template<std::size_t S> + XORSTR_FORCEINLINE constexpr std::uint64_t key8() + { + constexpr auto first_part = key4<2166136261 + S>(); + constexpr auto second_part = key4<first_part>(); + return (static_cast<std::uint64_t>(first_part) << 32) | second_part; + } + + template<std::size_t N, class CharT> + XORSTR_FORCEINLINE constexpr std::uint64_t + load_xored_str8(std::uint64_t key, std::size_t idx, const CharT* str) noexcept + { + using cast_type = typename std::make_unsigned<CharT>::type; + constexpr auto value_size = sizeof(CharT); + constexpr auto idx_offset = 8 / value_size; + + std::uint64_t value = key; + for(std::size_t i = 0; i < idx_offset && i + idx * idx_offset < N; ++i) + value ^= (std::uint64_t{ static_cast<cast_type>(str[i + idx * idx_offset]) } << ((i % idx_offset) * 8 * value_size)); + + return value; + } + + XORSTR_FORCEINLINE std::uint64_t load_from_reg(std::uint64_t value) noexcept + { +#if defined(__clang__) || defined(__GNUC__) + asm("" : "=r"(value) : "0"(value) :); + return value; +#else + volatile std::uint64_t reg = value; + return reg; +#endif + } + } + + template<class CharT, std::size_t Size, class Keys, class Indices> + class xor_string; + + template<class CharT, std::size_t Size, std::uint64_t... Keys, std::size_t... Indices> + class xor_string<CharT, Size, std::integer_sequence<std::uint64_t, Keys...>, std::index_sequence<Indices...>> { +#ifndef JM_XORSTR_DISABLE_AVX_INTRINSICS + constexpr static inline std::uint64_t alignment = ((Size > 16) ? 32 : 16); +#else + constexpr static inline std::uint64_t alignment = 16; +#endif + + alignas(alignment) std::uint64_t _storage[sizeof...(Keys)]; + + public: + using value_type = CharT; + using size_type = std::size_t; + using pointer = CharT*; + using const_pointer = const CharT*; + + template<class L> + XORSTR_FORCEINLINE xor_string(L l, std::integral_constant<std::size_t, Size>, std::index_sequence<Indices...>) noexcept + : _storage{ ::jm::detail::load_from_reg((std::integral_constant<std::uint64_t, detail::load_xored_str8<Size>(Keys, Indices, l())>::value))... } + {} + + XORSTR_FORCEINLINE constexpr size_type size() const noexcept { return Size - 1; } + + XORSTR_FORCEINLINE void crypt() noexcept + { +#if defined(__clang__) + alignas(alignment) + std::uint64_t arr[]{ ::jm::detail::load_from_reg(Keys)... }; + std::uint64_t* keys = + (std::uint64_t*)::jm::detail::load_from_reg((std::uint64_t)arr); +#else + alignas(alignment) std::uint64_t keys[]{ ::jm::detail::load_from_reg(Keys)... }; +#endif + +#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__) +#if defined(__clang__) + ((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : __builtin_neon_vst1q_v( + reinterpret_cast<uint64_t*>(_storage) + Indices * 2, + veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2, 51), + __builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(keys) + Indices * 2, 51)), + 51)), ...); +#else // GCC, MSVC + ((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : vst1q_u64( + reinterpret_cast<uint64_t*>(_storage) + Indices * 2, + veorq_u64(vld1q_u64(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2), + vld1q_u64(reinterpret_cast<const uint64_t*>(keys) + Indices * 2)))), ...); +#endif +#elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS) + ((Indices >= sizeof(_storage) / 32 ? static_cast<void>(0) : _mm256_store_si256( + reinterpret_cast<__m256i*>(_storage) + Indices, + _mm256_xor_si256( + _mm256_load_si256(reinterpret_cast<const __m256i*>(_storage) + Indices), + _mm256_load_si256(reinterpret_cast<const __m256i*>(keys) + Indices)))), ...); + + if constexpr(sizeof(_storage) % 32 != 0) + _mm_store_si128( + reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2), + _mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage + sizeof...(Keys) - 2)), + _mm_load_si128(reinterpret_cast<const __m128i*>(keys + sizeof...(Keys) - 2)))); +#else + ((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : _mm_store_si128( + reinterpret_cast<__m128i*>(_storage) + Indices, + _mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage) + Indices), + _mm_load_si128(reinterpret_cast<const __m128i*>(keys) + Indices)))), ...); +#endif + } + + XORSTR_FORCEINLINE const_pointer get() const noexcept { return reinterpret_cast<const_pointer>(_storage); } + + XORSTR_FORCEINLINE pointer get() noexcept { return reinterpret_cast<pointer>(_storage); } + + XORSTR_FORCEINLINE pointer crypt_get() noexcept + { +#if defined(__clang__) + alignas(alignment) + std::uint64_t arr[]{ ::jm::detail::load_from_reg(Keys)... }; + std::uint64_t* keys = + (std::uint64_t*)::jm::detail::load_from_reg((std::uint64_t)arr); +#else + alignas(alignment) std::uint64_t keys[]{ ::jm::detail::load_from_reg(Keys)... }; +#endif + +#if defined(_M_ARM64) || defined(__aarch64__) || defined(_M_ARM) || defined(__arm__) +#if defined(__clang__) + ((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : __builtin_neon_vst1q_v( + reinterpret_cast<uint64_t*>(_storage) + Indices * 2, + veorq_u64(__builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2, 51), + __builtin_neon_vld1q_v(reinterpret_cast<const uint64_t*>(keys) + Indices * 2, 51)), + 51)), ...); +#else // GCC, MSVC + ((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : vst1q_u64( + reinterpret_cast<uint64_t*>(_storage) + Indices * 2, + veorq_u64(vld1q_u64(reinterpret_cast<const uint64_t*>(_storage) + Indices * 2), + vld1q_u64(reinterpret_cast<const uint64_t*>(keys) + Indices * 2)))), ...); +#endif +#elif !defined(JM_XORSTR_DISABLE_AVX_INTRINSICS) + ((Indices >= sizeof(_storage) / 32 ? static_cast<void>(0) : _mm256_store_si256( + reinterpret_cast<__m256i*>(_storage) + Indices, + _mm256_xor_si256( + _mm256_load_si256(reinterpret_cast<const __m256i*>(_storage) + Indices), + _mm256_load_si256(reinterpret_cast<const __m256i*>(keys) + Indices)))), ...); + + if constexpr(sizeof(_storage) % 32 != 0) + _mm_store_si128( + reinterpret_cast<__m128i*>(_storage + sizeof...(Keys) - 2), + _mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage + sizeof...(Keys) - 2)), + _mm_load_si128(reinterpret_cast<const __m128i*>(keys + sizeof...(Keys) - 2)))); +#else + ((Indices >= sizeof(_storage) / 16 ? static_cast<void>(0) : _mm_store_si128( + reinterpret_cast<__m128i*>(_storage) + Indices, + _mm_xor_si128(_mm_load_si128(reinterpret_cast<const __m128i*>(_storage) + Indices), + _mm_load_si128(reinterpret_cast<const __m128i*>(keys) + Indices)))), ...); +#endif + return (pointer)(_storage); + } + }; + + template<class L, std::size_t Size, std::size_t... Indices> + xor_string(L l, std::integral_constant<std::size_t, Size>, std::index_sequence<Indices...>) -> xor_string<std::remove_const_t<std::remove_reference_t<decltype(l()[0])>>, Size, std::integer_sequence<std::uint64_t, detail::key8<Indices>()...>, std::index_sequence<Indices...>>; +} +#endif
\ No newline at end of file |
