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() {
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);
} 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;
}
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;
};
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);
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(