From 631c20bd04c2380b6dcad0d96d8eca813592730b Mon Sep 17 00:00:00 2001 From: Rosalie Wanders Date: Thu, 7 Nov 2024 21:29:46 +0100 Subject: [PATCH] SporeMods: fix mod by not using a custom OpenSSL version --- .../SporeServer/{OpenSSL.cpp => Network.cpp} | 159 ++++-------------- .../SporeServer/{OpenSSL.hpp => Network.hpp} | 8 +- SporeMods/SporeServer/RedirectTraffic.cpp | 1 - SporeMods/SporeServer/SporeServer.vcxproj | 12 +- .../SporeServer/SporeServer.vcxproj.filters | 4 +- SporeMods/SporeServer/dllmain.cpp | 6 +- SporeServer/appsettings.json | 2 +- 7 files changed, 50 insertions(+), 142 deletions(-) rename SporeMods/SporeServer/{OpenSSL.cpp => Network.cpp} (62%) rename SporeMods/SporeServer/{OpenSSL.hpp => Network.hpp} (82%) diff --git a/SporeMods/SporeServer/OpenSSL.cpp b/SporeMods/SporeServer/Network.cpp similarity index 62% rename from SporeMods/SporeServer/OpenSSL.cpp rename to SporeMods/SporeServer/Network.cpp index 43f3e03..a079266 100644 --- a/SporeMods/SporeServer/OpenSSL.cpp +++ b/SporeMods/SporeServer/Network.cpp @@ -7,22 +7,17 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // -// dllmain.cpp : Defines the entry point for the DLL application. // // Includes // #include "stdafx.h" -#include "OpenSSL.hpp" +#include "Network.hpp" // needed for connect #include -// needed for SSL_connect, SSL_read, SSL_write -#include -#include - // needed for mutex lock #include @@ -40,13 +35,9 @@ // Global variables // -static SSL* OpenSSL_SSL = nullptr; -static SSL_CTX* OpenSSL_CTX = nullptr; -static std::mutex OpenSSL_MTX; -static int OpenSSL_ThreadId = -1; -static bool SporeServerPortOverride = false; -static uint16_t SporeServerPort; -static bool SporeServerSslVerification = true; +static bool SporeServerPortOverride = false; +static uint16_t SporeServerPort; +static bool SporeServerSslVerification = true; // // Detour functions @@ -65,104 +56,23 @@ static int WINAPI connect_detour(SOCKET s, const sockaddr* name, int namelen) ((sockaddr_in*)name)->sin_port = htons(SporeServerPort); } - int ret = connect_real(s, name, namelen); - - // we don't need openssl things - // when it can't connect or if it's HTTP - if (ret != 0 || !https) - { - return ret; - } - - // does the game use this function? - if (SSL_set_fd(OpenSSL_SSL, s) != 1) - { - return -1; - } - - return 0; + return connect_real(s, name, namelen); } -static int (WINAPI* closesocket_real)(SOCKET) = closesocket; -static int WINAPI closesocket_detour(SOCKET s) +static_detour(SSL_CTX_set_verify, void(void*, int, void*)) { - // unlock the mutex here, - // the game always calls closesocket - if (OpenSSL_ThreadId == GetCurrentThreadId()) - { - OpenSSL_ThreadId = -1; - OpenSSL_MTX.unlock(); - } - - return closesocket_real(s); -} - -static_detour(SSLCtxNewDetour, void* (void*)) { - void* detoured(void* meth) - { - OpenSSL_CTX = SSL_CTX_new(TLS_method()); - if (OpenSSL_CTX == nullptr) - { - return nullptr; - } - - return original_function(meth); - } -}; - -static_detour(SSLNewDetour, void* (void*)) { - void* detoured(void* ssl_ctx) - { - // TODO, figure out what kinda locking the game uses - OpenSSL_MTX.lock(); - OpenSSL_ThreadId = GetCurrentThreadId(); - - OpenSSL_SSL = SSL_new(OpenSSL_CTX); - if (OpenSSL_SSL == nullptr) - { - return nullptr; - } - - return original_function(ssl_ctx); - } -}; - -static_detour(SSLClearDetour, int(void*)) { - int detoured(void* ssl) - { - if (SSL_clear(OpenSSL_SSL) != 1) - { - return 0; - } - - return original_function(ssl); - } -}; - -static_detour(SSLConnectDetour, int(void*)) { - int detoured(void* ssl) - { - return SSL_connect(OpenSSL_SSL); - } -}; - -static_detour(SSLReadDetour, int(void*, void*, int)) { - int detoured(void* ssl, void* buffer, int num) - { - return SSL_read(OpenSSL_SSL, buffer, num); - } -}; - - -static_detour(SSLWriteDetour, int(void*, const void*, int)) { - int detoured(void* ssl, const void* buffer, int num) + void detoured(void* ssl, int mode, void* callback) { - return SSL_write(OpenSSL_SSL, buffer, num); + // force SSL_VERIFY_NONE to disable verifying CA chain, + // this isn't that insecure because we force a hash match + // in NetSSLVerifyConnection anyways + // TODO: figure out how Spore sets the CA certificates + return original_function(ssl, 0x00, callback); } }; -static_detour(GameValidateCertificate, int(int, char*)) { - int detoured(int arg1, char* servername) +static_detour(NetSSLVerifyConnection, int(void*, char*)) { + int detoured(void* ssl, char* servername) { // return success when verification is disabled if (!SporeServerSslVerification) @@ -185,14 +95,16 @@ static_detour(GameValidateCertificate, int(int, char*)) { BOOL ret = false; // retrieve current certificate - X509* x509_cert = SSL_get_peer_certificate(OpenSSL_SSL); + // X509* x509_cert = SSL_get_peer_certificate(ssl); + void* x509_cert = STATIC_CALL(Address(ModAPI::ChooseAddress(0x0117db60, 0x0117b3e0)), void*, void*, ssl); if (x509_cert == nullptr) { goto out; } // extract encoded x509 - x509_cert_len = i2d_X509(x509_cert, &x509_cert_buf); + // x509_cert_len = i2d_X509(x509_cert, &x509_cert_buf); + x509_cert_len = STATIC_CALL(Address(ModAPI::ChooseAddress(0x0117f700, 0x0117cf80)), int, Args(void*, unsigned char**), Args(x509_cert, &x509_cert_buf)); if (x509_cert_len < 0) { goto out; @@ -227,16 +139,18 @@ static_detour(GameValidateCertificate, int(int, char*)) { BYTE ignoredCertsHashes[][20] = { { // pollinator.spore.com - 0xc8, 0xb2, 0x8f, 0xb, 0xd6, - 0x63, 0x2, 0x1d, 0x9b, 0x9c, - 0x36, 0x98, 0x82, 0xc, 0x76, - 0x74, 0xc7, 0xa7, 0x15, 0xb3 + 0x26, 0x95, 0x77, 0x65, + 0x5C, 0xDD, 0x70, 0x98, + 0x74, 0x29, 0x72, 0x47, + 0x99, 0xFB, 0xFF, 0x57, + 0x38, 0xC7, 0x88, 0x74 }, { // community.spore.com - 0xe6, 0xc8, 0x63, 0xf8, 0x55, - 0xf1, 0xc3, 0x7b, 0x9b, 0x34, - 0x78, 0xe6, 0xed, 0xaa, 0x85, - 0x36, 0xb, 0x7, 0xf1, 0xc4 + 0xA9, 0x9B, 0xE0, 0xF2, + 0xED, 0xC0, 0x7D, 0xA0, + 0x7D, 0x9B, 0xC0, 0x84, + 0x20, 0xC6, 0x3D, 0xF0, + 0x3B, 0xD6, 0x9C, 0xC2 } }; @@ -285,7 +199,8 @@ static_detour(GameValidateCertificate, int(int, char*)) { out: if (x509_cert != nullptr) { - X509_free(x509_cert); + // X509_free(x509_cert); + STATIC_CALL(Address(ModAPI::ChooseAddress(0x0117f730, 0x0117cfb0)), void, void*, x509_cert); } if (cert_ctx != nullptr) { @@ -320,7 +235,7 @@ static_detour(GameUseHttpDetour, bool(unsigned int, unsigned int, char*)) { // Exported Functions // -void OpenSSL::Initialize(void) +void Network::Initialize(void) { if (Configuration::GetBoolValue(Configuration::Key::OverridePort)) { @@ -343,17 +258,11 @@ void OpenSSL::Initialize(void) SporeServerSslVerification = Configuration::GetBoolValue(Configuration::Key::SSLVerification); } -void OpenSSL::AttachDetours(void) +void Network::AttachDetours(void) { - SSLCtxNewDetour::attach(Address(ModAPI::ChooseAddress(0x0117f200, 0x0117ca80))); - SSLNewDetour::attach(Address(ModAPI::ChooseAddress(0x0117ed00, 0x0117c580))); - SSLClearDetour::attach(Address(ModAPI::ChooseAddress(0x0117ebe0, 0x0117c460))); - SSLConnectDetour::attach(Address(ModAPI::ChooseAddress(0x0117f5d0, 0x0117ce50))); - SSLReadDetour::attach(Address(ModAPI::ChooseAddress(0x0117dbb0, 0x0117b430))); - SSLWriteDetour::attach(Address(ModAPI::ChooseAddress(0x0117dc40, 0x0117b4c0))); - GameValidateCertificate::attach(Address(ModAPI::ChooseAddress(0x0094f080, 0x0094eb60))); + SSL_CTX_set_verify::attach(Address(ModAPI::ChooseAddress(0x0117e2b0, 0x0117bb30))); + NetSSLVerifyConnection::attach(Address(ModAPI::ChooseAddress(0x0094f080, 0x0094eb60))); GameUseHttpsDetour::attach(Address(ModAPI::ChooseAddress(0x00621740, 0x006216e0))); GameUseHttpDetour::attach(Address(ModAPI::ChooseAddress(0x00621800, 0x006217a0))); DetourAttach(&(PVOID&)connect_real, connect_detour); - DetourAttach(&(PVOID&)closesocket_real, closesocket_detour); } diff --git a/SporeMods/SporeServer/OpenSSL.hpp b/SporeMods/SporeServer/Network.hpp similarity index 82% rename from SporeMods/SporeServer/OpenSSL.hpp rename to SporeMods/SporeServer/Network.hpp index 523dec8..96d6104 100644 --- a/SporeMods/SporeServer/OpenSSL.hpp +++ b/SporeMods/SporeServer/Network.hpp @@ -7,14 +7,14 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // -#ifndef SPORENEWOPENSSL_HPP -#define SPORENEWOPENSSL_HPP +#ifndef SPORENETWORK_HPP +#define SPORENETWORK_HPP -namespace OpenSSL +namespace Network { void Initialize(void); void AttachDetours(void); } -#endif // SPORENEWOPENSSL_HPP +#endif // SPORENETWORK_HPP diff --git a/SporeMods/SporeServer/RedirectTraffic.cpp b/SporeMods/SporeServer/RedirectTraffic.cpp index 5a05617..4bd8e5e 100644 --- a/SporeMods/SporeServer/RedirectTraffic.cpp +++ b/SporeMods/SporeServer/RedirectTraffic.cpp @@ -7,7 +7,6 @@ // You should have received a copy of the GNU Affero General Public License // along with this program. If not, see . // -// dllmain.cpp : Defines the entry point for the DLL application. // // Includes diff --git a/SporeMods/SporeServer/SporeServer.vcxproj b/SporeMods/SporeServer/SporeServer.vcxproj index a0a065f..f0fde39 100644 --- a/SporeMods/SporeServer/SporeServer.vcxproj +++ b/SporeMods/SporeServer/SporeServer.vcxproj @@ -44,7 +44,7 @@ true - C:\Program Files %28x86%29\OpenSSL-Win32\include;$(SporeSdkPath)Spore ModAPI;$(SporeSdkPath)EASTL-3.02.01\test\packages\EABase\include\Common;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAAssert\include;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAStdC\include;$(SporeSdkPath)EASTL-3.02.01\include;$(SporeSdkPath)Detours\include\;$(DXSDK_DIR)Include;$(IncludePath) + $(SporeSdkPath)Spore ModAPI;$(SporeSdkPath)EASTL-3.02.01\test\packages\EABase\include\Common;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAAssert\include;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAStdC\include;$(SporeSdkPath)EASTL-3.02.01\include;$(SporeSdkPath)Detours\include\;$(DXSDK_DIR)Include;$(IncludePath) C:\Program Files %28x86%29\OpenSSL-Win32\lib\VC\static;$(DXSDK_DIR)Lib\x86;$(SporeSdkPath)dll\$(Configuration);$(SporeSdkPath)Detours\lib.X86;$(SporeSdkPath)lib\Debug;$(SporeSdkPath)dll\Debug;$(LibraryPath) $(ProjectName) Bin\$(Configuration)\ @@ -55,7 +55,7 @@ false - C:\Program Files %28x86%29\OpenSSL-Win32\include;$(SporeSdkPath)Spore ModAPI;$(SporeSdkPath)EASTL-3.02.01\test\packages\EABase\include\Common;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAAssert\include;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAStdC\include;$(SporeSdkPath)EASTL-3.02.01\include;$(SporeSdkPath)Detours\include\;$(DXSDK_DIR)Include;$(IncludePath) + $(SporeSdkPath)Spore ModAPI;$(SporeSdkPath)EASTL-3.02.01\test\packages\EABase\include\Common;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAAssert\include;$(SporeSdkPath)EASTL-3.02.01\test\packages\EAStdC\include;$(SporeSdkPath)EASTL-3.02.01\include;$(SporeSdkPath)Detours\include\;$(DXSDK_DIR)Include;$(IncludePath) C:\Program Files %28x86%29\OpenSSL-Win32\lib\VC\static;$(DXSDK_DIR)Lib\x86;$(SporeSdkPath)dll\$(Configuration);$(SporeSdkPath)Detours\lib.X86;$(SporeSdkPath)lib\Release;$(SporeSdkPath)dll\Release;$(LibraryPath) $(ProjectName) Bin\$(Configuration)\ @@ -77,7 +77,7 @@ Windows true - detours.lib;SporeModAPIBase.lib;SporeModAPI.lib;libssl32MT.lib;libcrypto32MT.lib;crypt32.lib;ws2_32.lib;wsock32.lib;%(AdditionalDependencies) + detours.lib;SporeModAPIBase.lib;SporeModAPI.lib;crypt32.lib;ws2_32.lib;wsock32.lib;%(AdditionalDependencies) if NOT EXIST "$(SporeSdkPath)dll\$(Configuration)\SporeModAPI.lib" ( @@ -102,7 +102,7 @@ true true true - detours.lib;SporeModAPIBase.lib;SporeModAPI.lib;libssl32MT.lib;libcrypto32MT.lib;crypt32.lib;ws2_32.lib;wsock32.lib;%(AdditionalDependencies) + detours.lib;SporeModAPIBase.lib;SporeModAPI.lib;crypt32.lib;ws2_32.lib;wsock32.lib;%(AdditionalDependencies) if NOT EXIST "$(SporeSdkPath)dll\$(Configuration)\SporeModAPI.lib" ( @@ -112,7 +112,7 @@ - + @@ -127,7 +127,7 @@ - + Create diff --git a/SporeMods/SporeServer/SporeServer.vcxproj.filters b/SporeMods/SporeServer/SporeServer.vcxproj.filters index b3bf9d1..39cf81a 100644 --- a/SporeMods/SporeServer/SporeServer.vcxproj.filters +++ b/SporeMods/SporeServer/SporeServer.vcxproj.filters @@ -4,7 +4,7 @@ Source Files - + Source Files @@ -21,7 +21,7 @@ Header Files - + Header Files diff --git a/SporeMods/SporeServer/dllmain.cpp b/SporeMods/SporeServer/dllmain.cpp index a42c91e..41129a0 100644 --- a/SporeMods/SporeServer/dllmain.cpp +++ b/SporeMods/SporeServer/dllmain.cpp @@ -16,7 +16,7 @@ #include "stdafx.h" #include "Configuration.hpp" -#include "OpenSSL.hpp" +#include "Network.hpp" #include "RedirectTraffic.hpp" // @@ -30,7 +30,7 @@ void Initialize() MessageBoxA(nullptr, "Configuration::Initialize() Failed!", "SporeServer", MB_OK | MB_ICONERROR); return; } - OpenSSL::Initialize(); + Network::Initialize(); RedirectTraffic::Initialize(); } @@ -40,7 +40,7 @@ void Dispose() void AttachDetours() { - OpenSSL::AttachDetours(); + Network::AttachDetours(); RedirectTraffic::AttachDetours(); } diff --git a/SporeServer/appsettings.json b/SporeServer/appsettings.json index 48264ce..9b41240 100644 --- a/SporeServer/appsettings.json +++ b/SporeServer/appsettings.json @@ -9,7 +9,7 @@ }, "AllowedHosts": "*", "ConnectionStrings": { - "SporeServerContextConnection": "server=localhost;user=root;password=example;database=SporeServer" + "SporeServerContextConnection": "server=localhost;user=root;password=password;database=SporeServer" }, "AppSettings": { "EnableHTTPLogging": "0"