From 243bb778d1dca2e0fb0b61204466deeddb017581 Mon Sep 17 00:00:00 2001 From: Kagamine Haku Date: Wed, 16 Oct 2024 04:08:54 +0700 Subject: [PATCH 1/5] Add automatically apply OpenSSL patch for Intel Gen 10+ CPUs --- platform/meson.build | 2 + platform/opensslpatch.c | 101 ++++++++++++++++++++++++++++++++++++++++ platform/opensslpatch.h | 8 ++++ platform/platform.c | 3 ++ platform/platform.h | 1 + 5 files changed, 115 insertions(+) create mode 100644 platform/opensslpatch.c create mode 100644 platform/opensslpatch.h diff --git a/platform/meson.build b/platform/meson.build index aa0d362..a00df6b 100644 --- a/platform/meson.build +++ b/platform/meson.build @@ -36,5 +36,7 @@ platform_lib = static_library( 'vfs.h', 'system.c', 'system.h', + 'opensslpatch.c', + 'opensslpatch.h', ], ) diff --git a/platform/opensslpatch.c b/platform/opensslpatch.c new file mode 100644 index 0000000..c2ca13b --- /dev/null +++ b/platform/opensslpatch.c @@ -0,0 +1,101 @@ +#include +#include +#include +#include "util/dprintf.h" +#include "platform/opensslpatch.h" + +int ChecknPatch(void) { + char* cpuname = GetCpuName(); + if (cpuname == NULL) { + dprintf("Error: Unable to detect CPU.\n"); + return 1; + } + + //dprintf("CPU Detected: %s\n", cpuname); + + if (CheckCpu(cpuname)) { + OpenSSLPatch(); + dprintf("OpenSSL Patch applied successfully.\n"); + } else { + dprintf("Info: OpenSSL Patch is not required (AMD or Intel < 10th gen or older CPU detected).\n"); + } + + free(cpuname); + return 0; +} + +char* GetCpuName() { + FILE* fp; + char buffer[128]; + char* cpu_info = NULL; + + fp = _popen("wmic cpu get Name", "r"); + + if (fp == NULL) { + return NULL; + } + + fgets(buffer, sizeof(buffer), fp); + + if (fgets(buffer, sizeof(buffer), fp) != NULL) { + cpu_info = (char*)malloc(strlen(buffer) + 1); + strcpy(cpu_info, buffer); + } + _pclose(fp); + + if (cpu_info != NULL) { + cpu_info[strcspn(cpu_info, "\r\n")] = 0; + } + + return cpu_info; +} + +int CheckCpu(char* cpuname) { + if (strstr(cpuname, "Core 2 Duo") || strstr(cpuname, "Core 2 Quad") || + (strstr(cpuname, "Pentium") && !strstr(cpuname, "G")) || strstr(cpuname, "Celeron")) { + //dprintf("Trash detected. No patch needed.\n"); + return 0; + } + + if (strstr(cpuname, "Intel")) { + char* part = strtok(cpuname, " "); + while (part != NULL) { + if (part[0] == 'i' && strlen(part) >= 4) { + int gen = atoi(part + 1); + if (gen >= 10) { + dprintf("Intel Gen 10+ CPU Detected: %s\n", cpuname); + return 1; + } + } else if (part[0] == 'G' && strlen(part) >= 4) { + int pentium = atoi(part + 1); + if (pentium / 1000 >= 6) { + dprintf("Intel Gen 10+ CPU Detected: %s\n", cpuname); + return 1; + } + } + part = strtok(NULL, " "); + } + } + + return 0; +} + +void OpenSSLPatch(void) { + const char* variablename = "OPENSSL_ia32cap"; + const char* variablevalue = "~0x20000000"; + + HKEY hKey; + if (RegOpenKeyExA(HKEY_CURRENT_USER, "Environment", 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { + if (RegSetValueExA(hKey, variablename, 0, REG_SZ, (const BYTE*)variablevalue, strlen(variablevalue) + 1) == ERROR_SUCCESS) { + dprintf("Successfully set the user environment variable %s to %s\n", variablename, variablevalue); + } else { + dprintf("Error: Failed to set the user environment variable.\n"); + } + + RegCloseKey(hKey); + + SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, NULL); + } else { + dprintf("Error: Failed to open the user environment registry key.\n"); + } +} diff --git a/platform/opensslpatch.h b/platform/opensslpatch.h new file mode 100644 index 0000000..5def7d5 --- /dev/null +++ b/platform/opensslpatch.h @@ -0,0 +1,8 @@ +#pragma once + +#include + +int ChecknPatch(void); +void OpenSSLPatch(void); +char* GetCpuName(void); +int CheckCpu(char* cpuname); diff --git a/platform/platform.c b/platform/platform.c index a769c97..5dbebc7 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -14,6 +14,7 @@ #include "platform/platform.h" #include "platform/vfs.h" #include "platform/system.h" +#include "platform/opensslpatch.h" HRESULT platform_hook_init( const struct platform_config *cfg, @@ -28,6 +29,8 @@ HRESULT platform_hook_init( assert(platform_id != NULL); assert(redir_mod != NULL); + ChecknPatch(); + hr = amvideo_hook_init(&cfg->amvideo, redir_mod); if (FAILED(hr)) { diff --git a/platform/platform.h b/platform/platform.h index 0b69f12..b9bf7fd 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -14,6 +14,7 @@ #include "platform/pcbid.h" #include "platform/vfs.h" #include "platform/system.h" +#include "platform/opensslpatch.h" struct platform_config { struct amvideo_config amvideo; -- 2.39.2 From f39b9ce3a0fbb15d4e3e0c938c0f42c91b878bc8 Mon Sep 17 00:00:00 2001 From: Kagamine Haku Date: Wed, 16 Oct 2024 15:01:39 +0700 Subject: [PATCH 2/5] resolve dniel97 comments --- platform/opensslpatch.c | 51 ++++++++++++++++++----------------------- platform/opensslpatch.h | 7 +----- platform/platform.c | 2 +- 3 files changed, 24 insertions(+), 36 deletions(-) diff --git a/platform/opensslpatch.c b/platform/opensslpatch.c index c2ca13b..afb5fd6 100644 --- a/platform/opensslpatch.c +++ b/platform/opensslpatch.c @@ -4,27 +4,7 @@ #include "util/dprintf.h" #include "platform/opensslpatch.h" -int ChecknPatch(void) { - char* cpuname = GetCpuName(); - if (cpuname == NULL) { - dprintf("Error: Unable to detect CPU.\n"); - return 1; - } - - //dprintf("CPU Detected: %s\n", cpuname); - - if (CheckCpu(cpuname)) { - OpenSSLPatch(); - dprintf("OpenSSL Patch applied successfully.\n"); - } else { - dprintf("Info: OpenSSL Patch is not required (AMD or Intel < 10th gen or older CPU detected).\n"); - } - - free(cpuname); - return 0; -} - -char* GetCpuName() { +static char* GetCpuName() { FILE* fp; char buffer[128]; char* cpu_info = NULL; @@ -50,10 +30,9 @@ char* GetCpuName() { return cpu_info; } -int CheckCpu(char* cpuname) { +static int CheckCpu(char* cpuname) { if (strstr(cpuname, "Core 2 Duo") || strstr(cpuname, "Core 2 Quad") || (strstr(cpuname, "Pentium") && !strstr(cpuname, "G")) || strstr(cpuname, "Celeron")) { - //dprintf("Trash detected. No patch needed.\n"); return 0; } @@ -63,13 +42,13 @@ int CheckCpu(char* cpuname) { if (part[0] == 'i' && strlen(part) >= 4) { int gen = atoi(part + 1); if (gen >= 10) { - dprintf("Intel Gen 10+ CPU Detected: %s\n", cpuname); + dprintf("OpenSSL Patch: Intel Gen 10+ CPU Detected: %s\n", cpuname); return 1; } } else if (part[0] == 'G' && strlen(part) >= 4) { int pentium = atoi(part + 1); if (pentium / 1000 >= 6) { - dprintf("Intel Gen 10+ CPU Detected: %s\n", cpuname); + dprintf("OpenSSL Patch: Intel Gen 10+ CPU Detected: %s\n", cpuname); return 1; } } @@ -80,22 +59,36 @@ int CheckCpu(char* cpuname) { return 0; } -void OpenSSLPatch(void) { +static void OpenSSLPatch(void) { const char* variablename = "OPENSSL_ia32cap"; const char* variablevalue = "~0x20000000"; HKEY hKey; if (RegOpenKeyExA(HKEY_CURRENT_USER, "Environment", 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { if (RegSetValueExA(hKey, variablename, 0, REG_SZ, (const BYTE*)variablevalue, strlen(variablevalue) + 1) == ERROR_SUCCESS) { - dprintf("Successfully set the user environment variable %s to %s\n", variablename, variablevalue); + dprintf("OpenSSL Patch: Applied successfully : Set the user environment variable %s to %s\n", variablename, variablevalue); } else { - dprintf("Error: Failed to set the user environment variable.\n"); + dprintf("OpenSSL Patch: Error: Failed to set the user environment variable.\n"); } RegCloseKey(hKey); SendMessageTimeoutA(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)"Environment", SMTO_ABORTIFHUNG, 5000, NULL); } else { - dprintf("Error: Failed to open the user environment registry key.\n"); + dprintf("OpenSSL Patch: Error: Failed to open the user environment registry key.\n"); } } + +int openssl_patch_apply(void) { + char* cpuname = GetCpuName(); + if (cpuname == NULL) { + dprintf("OpenSSL Patch: Error: Unable to detect CPU.\n"); + return 1; + } + + if (CheckCpu(cpuname)) { + OpenSSLPatch(); + } + free(cpuname); + return 0; +} \ No newline at end of file diff --git a/platform/opensslpatch.h b/platform/opensslpatch.h index 5def7d5..fe665a5 100644 --- a/platform/opensslpatch.h +++ b/platform/opensslpatch.h @@ -1,8 +1,3 @@ #pragma once -#include - -int ChecknPatch(void); -void OpenSSLPatch(void); -char* GetCpuName(void); -int CheckCpu(char* cpuname); +int openssl_patch_apply(void); diff --git a/platform/platform.c b/platform/platform.c index 5dbebc7..4f663bc 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -29,7 +29,7 @@ HRESULT platform_hook_init( assert(platform_id != NULL); assert(redir_mod != NULL); - ChecknPatch(); + openssl_patch_apply(); hr = amvideo_hook_init(&cfg->amvideo, redir_mod); -- 2.39.2 From 97d2d6b9bc96072cb3726c0efc784c8902476e84 Mon Sep 17 00:00:00 2001 From: Kagamine Haku Date: Wed, 16 Oct 2024 15:53:52 +0700 Subject: [PATCH 3/5] resolved camelCase and the " :" problem --- platform/opensslpatch.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/platform/opensslpatch.c b/platform/opensslpatch.c index afb5fd6..4537195 100644 --- a/platform/opensslpatch.c +++ b/platform/opensslpatch.c @@ -4,7 +4,7 @@ #include "util/dprintf.h" #include "platform/opensslpatch.h" -static char* GetCpuName() { +static char* get_cpu_name() { FILE* fp; char buffer[128]; char* cpu_info = NULL; @@ -30,7 +30,7 @@ static char* GetCpuName() { return cpu_info; } -static int CheckCpu(char* cpuname) { +static int check_cpu(char* cpuname) { if (strstr(cpuname, "Core 2 Duo") || strstr(cpuname, "Core 2 Quad") || (strstr(cpuname, "Pentium") && !strstr(cpuname, "G")) || strstr(cpuname, "Celeron")) { return 0; @@ -59,14 +59,14 @@ static int CheckCpu(char* cpuname) { return 0; } -static void OpenSSLPatch(void) { +static void openssl_patch(void) { const char* variablename = "OPENSSL_ia32cap"; const char* variablevalue = "~0x20000000"; HKEY hKey; if (RegOpenKeyExA(HKEY_CURRENT_USER, "Environment", 0, KEY_SET_VALUE, &hKey) == ERROR_SUCCESS) { if (RegSetValueExA(hKey, variablename, 0, REG_SZ, (const BYTE*)variablevalue, strlen(variablevalue) + 1) == ERROR_SUCCESS) { - dprintf("OpenSSL Patch: Applied successfully : Set the user environment variable %s to %s\n", variablename, variablevalue); + dprintf("OpenSSL Patch: Applied successfully, set the user environment variable %s to %s\n", variablename, variablevalue); } else { dprintf("OpenSSL Patch: Error: Failed to set the user environment variable.\n"); } @@ -80,14 +80,14 @@ static void OpenSSLPatch(void) { } int openssl_patch_apply(void) { - char* cpuname = GetCpuName(); + char* cpuname = get_cpu_name(); if (cpuname == NULL) { dprintf("OpenSSL Patch: Error: Unable to detect CPU.\n"); return 1; } - if (CheckCpu(cpuname)) { - OpenSSLPatch(); + if (check_cpu(cpuname)) { + openssl_patch(); } free(cpuname); return 0; -- 2.39.2 From cef3406691891a0065f970d436e038ab9f9a380e Mon Sep 17 00:00:00 2001 From: Kagamine Haku Date: Fri, 18 Oct 2024 13:34:25 +0700 Subject: [PATCH 4/5] Add switch for openssl patch in segatools.ini --- platform/config.c | 17 +++++++++++++++++ platform/config.h | 1 + platform/opensslpatch.c | 15 ++++++++++++--- platform/opensslpatch.h | 6 +++++- platform/platform.c | 6 +++++- platform/platform.h | 1 + 6 files changed, 41 insertions(+), 5 deletions(-) diff --git a/platform/config.c b/platform/config.c index ad97905..98b67b6 100644 --- a/platform/config.c +++ b/platform/config.c @@ -23,6 +23,7 @@ #include "platform/platform.h" #include "platform/vfs.h" #include "platform/system.h" +#include "platform/opensslpatch.h" void platform_config_load(struct platform_config *cfg, const wchar_t *filename) { @@ -41,6 +42,7 @@ void platform_config_load(struct platform_config *cfg, const wchar_t *filename) nusec_config_load(&cfg->nusec, filename); vfs_config_load(&cfg->vfs, filename); system_config_load(&cfg->system, filename); + openssl_patch_config_load(&cfg->openssl, filename); } void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename) @@ -355,3 +357,18 @@ void epay_config_load(struct epay_config *cfg, const wchar_t *filename) cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename); } + +void openssl_patch_config_load(struct openssl_patch_config *cfg, const wchar_t *filename) +{ + // Ensure the config structure and filename are valid + assert(cfg != NULL); + assert(filename != NULL); + + // Read the "enable" key from the "[openssl]" section of the configuration file + cfg->enable = GetPrivateProfileIntW( + L"openssl", // Section name + L"enable", // Key name + 1, // Default value if the key is not found (disabled by default) + filename // INI file name + ); +} diff --git a/platform/config.h b/platform/config.h index e945378..9f1f7f4 100644 --- a/platform/config.h +++ b/platform/config.h @@ -36,3 +36,4 @@ void nusec_config_load(struct nusec_config *cfg, const wchar_t *filename); void pcbid_config_load(struct pcbid_config *cfg, const wchar_t *filename); void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename); void system_config_load(struct system_config *cfg, const wchar_t *filename); +void openssl_patch_config_load(struct openssl_patch_config *cfg, const wchar_t *filename); \ No newline at end of file diff --git a/platform/opensslpatch.c b/platform/opensslpatch.c index 4537195..bebbaf9 100644 --- a/platform/opensslpatch.c +++ b/platform/opensslpatch.c @@ -79,16 +79,25 @@ static void openssl_patch(void) { } } -int openssl_patch_apply(void) { +HRESULT openssl_patch_apply(const struct openssl_patch_config *cfg) { + HRESULT hr; + + assert(cfg != NULL); + + if (!cfg->enable) { + return S_FALSE; + } + char* cpuname = get_cpu_name(); if (cpuname == NULL) { dprintf("OpenSSL Patch: Error: Unable to detect CPU.\n"); - return 1; + return S_FALSE; } if (check_cpu(cpuname)) { openssl_patch(); } + free(cpuname); - return 0; + return S_OK; } \ No newline at end of file diff --git a/platform/opensslpatch.h b/platform/opensslpatch.h index fe665a5..f97d9b7 100644 --- a/platform/opensslpatch.h +++ b/platform/opensslpatch.h @@ -1,3 +1,7 @@ #pragma once -int openssl_patch_apply(void); +struct openssl_patch_config { + int enable; +}; + +HRESULT openssl_patch_apply(const struct openssl_patch_config *cfg); diff --git a/platform/platform.c b/platform/platform.c index 4f663bc..c61c031 100644 --- a/platform/platform.c +++ b/platform/platform.c @@ -29,7 +29,11 @@ HRESULT platform_hook_init( assert(platform_id != NULL); assert(redir_mod != NULL); - openssl_patch_apply(); + hr = openssl_patch_apply(&cfg->openssl); + + if (FAILED(hr)) { + return hr; + } hr = amvideo_hook_init(&cfg->amvideo, redir_mod); diff --git a/platform/platform.h b/platform/platform.h index b9bf7fd..4972bfe 100644 --- a/platform/platform.h +++ b/platform/platform.h @@ -29,6 +29,7 @@ struct platform_config { struct nusec_config nusec; struct vfs_config vfs; struct system_config system; + struct openssl_patch_config openssl; }; HRESULT platform_hook_init( -- 2.39.2 From b80b9fbc19673f63d49831ce69459cc23954c5d2 Mon Sep 17 00:00:00 2001 From: Kagamine Haku Date: Fri, 18 Oct 2024 13:44:47 +0700 Subject: [PATCH 5/5] Delete useless comment --- platform/config.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/platform/config.c b/platform/config.c index 98b67b6..f2eea12 100644 --- a/platform/config.c +++ b/platform/config.c @@ -360,15 +360,13 @@ void epay_config_load(struct epay_config *cfg, const wchar_t *filename) void openssl_patch_config_load(struct openssl_patch_config *cfg, const wchar_t *filename) { - // Ensure the config structure and filename are valid assert(cfg != NULL); assert(filename != NULL); - // Read the "enable" key from the "[openssl]" section of the configuration file cfg->enable = GetPrivateProfileIntW( - L"openssl", // Section name - L"enable", // Key name - 1, // Default value if the key is not found (disabled by default) - filename // INI file name + L"openssl", + L"enable", + 1, + filename ); } -- 2.39.2