Add automatically apply OpenSSL patch for Intel Gen 10+ CPUs #43

Open
kagaminehaku wants to merge 5 commits from kagaminehaku/segatools:develop into develop
7 changed files with 137 additions and 0 deletions

View File

@ -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,16 @@ 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)
{
assert(cfg != NULL);
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(
L"openssl",
L"enable",
1,
filename
);
}

View File

@ -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);

View File

@ -36,5 +36,7 @@ platform_lib = static_library(
'vfs.h',
'system.c',
'system.h',
'opensslpatch.c',
'opensslpatch.h',
],
)

103
platform/opensslpatch.c Normal file
View File

@ -0,0 +1,103 @@
#include <windows.h>
#include <stdio.h>
#include <string.h>
#include "util/dprintf.h"
#include "platform/opensslpatch.h"
static char* get_cpu_name() {
kagaminehaku marked this conversation as resolved Outdated

Please use snake_case instead of camelCase for the function names.

Please use snake_case instead of camelCase for the function names.

Still camelCase.

Still camelCase.
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);
kagaminehaku marked this conversation as resolved
Review

To make it clear where the printed message in the console came from, prefix every string with "OpenSSL Patch:" or similar.

To make it clear where the printed message in the console came from, prefix every string with "OpenSSL Patch:" or similar.
if (fgets(buffer, sizeof(buffer), fp) != NULL) {
kagaminehaku marked this conversation as resolved
Review

Please remove that, as this will just clutter the output.

Please remove that, as this will just clutter the output.
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;
}
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;
}
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("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("OpenSSL Patch: Intel Gen 10+ CPU Detected: %s\n", cpuname);
return 1;
}
}
part = strtok(NULL, " ");
}
}
return 0;
}
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);
kagaminehaku marked this conversation as resolved Outdated

Either remove the space before " :" or remove it all together as it's redundant in my opinion.

Either remove the space before " :" or remove it all together as it's redundant in my opinion.
} else {
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("OpenSSL Patch: Error: Failed to open the user environment registry key.\n");
}
}
HRESULT openssl_patch_apply(const struct openssl_patch_config *cfg) {
HRESULT hr;
assert(cfg != NULL);
if (!cfg->enable) {
return S_FALSE;
}
kagaminehaku marked this conversation as resolved Outdated

I would only keep this print, change it to add that the patch applied successfully and remove the

dprintf("OpenSSL Patch applied successfully.\n");
I would only keep this print, change it to add that the patch applied successfully and remove the ```c dprintf("OpenSSL Patch applied successfully.\n"); ```
char* cpuname = get_cpu_name();
if (cpuname == NULL) {
dprintf("OpenSSL Patch: Error: Unable to detect CPU.\n");
return S_FALSE;
}
if (check_cpu(cpuname)) {
openssl_patch();
}
free(cpuname);
return S_OK;
}

7
platform/opensslpatch.h Normal file
View File

@ -0,0 +1,7 @@
#pragma once
struct openssl_patch_config {
int enable;
};
kagaminehaku marked this conversation as resolved Outdated

Only add the function you need to access from outside so in your case only ChecknPatch(). All other functions can be static.

Only add the function you need to access from outside so in your case only `ChecknPatch()`. All other functions can be static.
HRESULT openssl_patch_apply(const struct openssl_patch_config *cfg);

View File

@ -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,12 @@ HRESULT platform_hook_init(
assert(platform_id != NULL);
assert(redir_mod != NULL);
hr = openssl_patch_apply(&cfg->openssl);
kagaminehaku marked this conversation as resolved Outdated

I would rename it to something more descriptive, like openssl_patch_apply().

I would rename it to something more descriptive, like `openssl_patch_apply()`.
if (FAILED(hr)) {
return hr;
}
hr = amvideo_hook_init(&cfg->amvideo, redir_mod);
if (FAILED(hr)) {

View File

@ -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;
@ -28,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(