From d04cbd5ca896938a17f38b88083847961adb72be Mon Sep 17 00:00:00 2001 From: lightbulblighter <59720715+lightbulblighter@users.noreply.github.com> Date: Sun, 5 Jun 2022 22:53:30 -0700 Subject: [PATCH] remove openssl --- PolygonClientUtilities/Crypt.cpp | 146 +++++++++++------- PolygonClientUtilities/Crypt.h | 18 ++- .../PolygonClientUtilities.vcxproj | 4 +- PolygonClientUtilities/Util.cpp | 29 +--- PolygonClientUtilities/Util.h | 2 +- vcpkg.json | 1 - 6 files changed, 112 insertions(+), 88 deletions(-) diff --git a/PolygonClientUtilities/Crypt.cpp b/PolygonClientUtilities/Crypt.cpp index 71d3e11..c0ac3bc 100644 --- a/PolygonClientUtilities/Crypt.cpp +++ b/PolygonClientUtilities/Crypt.cpp @@ -3,6 +3,93 @@ #include "Patches.h" #include "Util.h" + +Crypt::Crypt() +{ + if (!CryptAcquireContext(&context, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) + { + if (::GetLastError() == NTE_BAD_KEYSET) + { + if (!CryptAcquireContext(&context, NULL, MS_ENH_RSA_AES_PROV, PROV_RSA_AES, CRYPT_VERIFYCONTEXT | CRYPT_NEWKEYSET)) + { + throw std::runtime_error("Error during CryptAcquireContext 2\n"); + } + } + else + { + throw std::runtime_error("Error during CryptAcquireContext\n"); + } + } + + std::vector publicKey = Util::base64Decode(Util::publicKey); + BYTE* blob = new BYTE[publicKey.size()]; + + std::copy(publicKey.begin(), publicKey.end(), blob); + + if (!CryptImportKey(context, blob, publicKey.size(), 0, 0, &key)) + { + throw std::runtime_error("Error during CryptImportKey"); + } +} + +Crypt::~Crypt() +{ + CryptDestroyKey(key); + CryptReleaseContext(context, 0); +} + +bool Crypt::verifySignatureBase64(std::string message, std::string signatureBase64, ALG_ID algorithm = CALG_SHA_256) +{ + // Check for a reasonable signature length before verifying + if (signatureBase64.length() > 4096) + { + return false; + } + + HCRYPTHASH hash; + + if (!CryptCreateHash(context, algorithm, NULL, 0, &hash)) + { + return false; + } + + try + { + if (!CryptHashData(hash, (BYTE*)message.c_str(), message.size(), 0)) + { + return false; + } + + std::vector signature = Util::base64Decode(signatureBase64); + + /* + The native cryptography API uses little-endian byte order + while OpenSSL uses big-endian byte order. + + If you are verifying a signature generated by using a OpenSSL API + (or similar), you must swap the order of signature bytes before + calling the CryptVerifySignature function to verify the signature. + */ + + std::reverse(signature.begin(), signature.end()); + + BYTE* signatureData = new BYTE[signature.size()]; + std::copy(signature.begin(), signature.end(), signatureData); + + if (!CryptVerifySignature(hash, signatureData, signature.size(), key, NULL, 0)) + { + return false; + } + } + catch (...) + { + ::CryptDestroyHash(hash); + return false; + } + + ::CryptDestroyHash(hash); +} + Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64 = (Crypt__verifySignatureBase64_t)ADDRESS_CRYPT__VERIFYSIGNATUREBASE64; // Crypt::verifySignatureBase64(std::string message, std::string signatureBase64) @@ -35,65 +122,12 @@ void __fastcall Crypt__verifySignatureBase64_hook(HCRYPTPROV* _this, void*, int signatureBase64 = std::string(reinterpret_cast(v21), a14); - // Verify the signature - try + // Verify signature + if (!Crypt().verifySignatureBase64(message, signatureBase64, CALG_SHA_256)) { - // Read public key - EVP_PKEY* key = NULL; - BIO* bio = BIO_new_mem_buf((void*)Util::publicKey.c_str(), Util::publicKey.length()); - - if (bio == NULL) + if (!Crypt().verifySignatureBase64(message, signatureBase64, CALG_SHA1)) { throw std::runtime_error(""); } - - key = PEM_read_bio_PUBKEY(bio, NULL, NULL, NULL); - BIO_free(bio); - - // Create context - EVP_PKEY_CTX* ctx = EVP_PKEY_CTX_new(key, NULL); - - if (!ctx) - { - throw std::runtime_error(""); - } - - if (EVP_PKEY_verify_init(ctx) <= 0) - { - throw std::runtime_error(""); - } - - if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0) - { - throw std::runtime_error(""); - } - - if (EVP_PKEY_CTX_set_signature_md(ctx, EVP_sha1()) <= 0) - { - throw std::runtime_error(""); - } - - // Verify signature against the message - const char* signature = Util::base64Decode(signatureBase64).c_str(); - const char* data = message.c_str(); - - int result = EVP_PKEY_verify(ctx, (unsigned char*)signature, strlen(signature), (unsigned char*)data, strlen(data)); - - // Dispose objects - EVP_PKEY_free(key); - EVP_PKEY_CTX_free(ctx); - - delete signature; - delete data; - - // Check - if (result != 1) - { - // throw std::runtime_error(""); - } - } - catch (...) - { - throw std::runtime_error(""); } } \ No newline at end of file diff --git a/PolygonClientUtilities/Crypt.h b/PolygonClientUtilities/Crypt.h index 2f00a83..92dee27 100644 --- a/PolygonClientUtilities/Crypt.h +++ b/PolygonClientUtilities/Crypt.h @@ -1,11 +1,19 @@ #pragma once #include "Classes.h" -#include -#include -#include -#include +#include typedef void(__thiscall* Crypt__verifySignatureBase64_t)(HCRYPTPROV* _this, int a2, BYTE* pbData, int a4, int a5, int a6, DWORD dwDataLen, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15); void __fastcall Crypt__verifySignatureBase64_hook(HCRYPTPROV* _this, void*, int a2, BYTE* pbData, int a4, int a5, int a6, DWORD dwDataLen, int a8, int a9, int a10, int a11, int a12, int a13, int a14, int a15); -extern Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64; \ No newline at end of file +extern Crypt__verifySignatureBase64_t Crypt__verifySignatureBase64; + +class Crypt +{ + HCRYPTPROV context; + HCRYPTKEY key; + +public: + Crypt(); + ~Crypt(); + bool verifySignatureBase64(std::string message, std::string signatureBase64, ALG_ID algorithm); +}; \ No newline at end of file diff --git a/PolygonClientUtilities/PolygonClientUtilities.vcxproj b/PolygonClientUtilities/PolygonClientUtilities.vcxproj index 9cfc628..6b1a54a 100644 --- a/PolygonClientUtilities/PolygonClientUtilities.vcxproj +++ b/PolygonClientUtilities/PolygonClientUtilities.vcxproj @@ -73,7 +73,7 @@ true false %(AdditionalLibraryDirectories) - detours.lib;libssl.lib;libcrypto.lib;libcurl-d.lib;WS2_32.lib;crypt32.lib;zlibd.lib;%(AdditionalDependencies) + detours.lib;libcurl-d.lib;WS2_32.lib;crypt32.lib;zlibd.lib;%(AdditionalDependencies) LIBCMTD.lib @@ -103,7 +103,7 @@ true false %(AdditionalLibraryDirectories) - detours.lib;libssl.lib;libcrypto.lib;libcurl.lib;WS2_32.lib;crypt32.lib;zlib.lib;%(AdditionalDependencies) + detours.lib;libcurl.lib;WS2_32.lib;crypt32.lib;zlib.lib;%(AdditionalDependencies) LIBCMT.lib diff --git a/PolygonClientUtilities/Util.cpp b/PolygonClientUtilities/Util.cpp index a35f52e..cf7ddb0 100644 --- a/PolygonClientUtilities/Util.cpp +++ b/PolygonClientUtilities/Util.cpp @@ -2,13 +2,7 @@ #include "Util.h" #include -const std::string Util::publicKey = - "-----BEGIN PUBLIC KEY-----\n" - "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDLHOl7Qy+Pvvokqcvhc/n6D5i/\n" - "uW0m2jUHLMJADaJcskazc5r2NzKtO/EFDDJNyJHRKvh5Y/6kchjUfmlr2NRN18lC\n" - "C8qzveor1pMTl3+4I6eKB5nspH1aWD8yRPpbomd6dwCVknL3coBxBysG8Md4AU9l\n" - "D+ROFxoFcUObvayYAQIDAQAB\n" - "-----END PUBLIC KEY-----"; +const std::string Util::publicKey = "BgIAAACkAABSU0ExAAQAAAEAAQABmKy9m0NxBRoXTuQPZU8BeMfwBisHcYBy93KSlQB3emeiW/pEMj9YWn2k7JkHiqcjuH+XE5PWK+q9s8oLQsnXTdTYa2l+1BhypP5jefgq0ZHITTIMBfE7rTI39ppzs0ayXKINQMIsBzXaJm25v5gP+vlz4cupJPq+jy9De+kcyw=="; const std::vector Util::allowedHosts { @@ -21,6 +15,7 @@ const std::vector Util::allowedHosts "www.roblox.com", "api.roblox.com", "assetdelivery.roblox.com", + "assetgame.roblox.com", "rbxcdn.com", "www.rbxcdn.com", @@ -37,18 +32,6 @@ const std::vector Util::allowedHosts "t8.rbxcdn.com", "t9.rbxcdn.com", - "cr.rbxcdn.com", - "c0.rbxcdn.com", - "c1.rbxcdn.com", - "c2.rbxcdn.com", - "c3.rbxcdn.com", - "c4.rbxcdn.com", - "c5.rbxcdn.com", - "c6.rbxcdn.com", - "c7.rbxcdn.com", - "c8.rbxcdn.com", - "c9.rbxcdn.com", - "tadah.rocks", "www.tadah.rocks" }; @@ -108,7 +91,7 @@ std::string Util::toLower(std::string s) } // https://stackoverflow.com/a/44562527 -std::string Util::base64Decode(const std::string_view data) +std::vector Util::base64Decode(const std::string_view data) { // table from '+' to 'z' const uint8_t lookup[] = { @@ -121,7 +104,7 @@ std::string Util::base64Decode(const std::string_view data) static_assert(sizeof(lookup) == 'z' - '+' + 1); - std::string out; + std::vector out; int val = 0, valb = -8; for (uint8_t c : data) { @@ -129,7 +112,7 @@ std::string Util::base64Decode(const std::string_view data) { break; } - + c -= '+'; if (lookup[c] >= 64) { @@ -145,6 +128,6 @@ std::string Util::base64Decode(const std::string_view data) valb -= 8; } } - + return out; } \ No newline at end of file diff --git a/PolygonClientUtilities/Util.h b/PolygonClientUtilities/Util.h index d33bb70..b2aa6bf 100644 --- a/PolygonClientUtilities/Util.h +++ b/PolygonClientUtilities/Util.h @@ -13,5 +13,5 @@ public: static std::map parseArgs(std::string args); static bool isASCII(const std::string& s); static std::string toLower(std::string s); - static std::string base64Decode(const std::string_view data); + static std::vector base64Decode(const std::string_view data); }; \ No newline at end of file diff --git a/vcpkg.json b/vcpkg.json index 512b31c..932620d 100644 --- a/vcpkg.json +++ b/vcpkg.json @@ -5,7 +5,6 @@ "dependencies": [ "curl", "detours", - "openssl", "rapidjson" ] } \ No newline at end of file