3 Commits

9 changed files with 172 additions and 2 deletions

View File

@ -23,6 +23,8 @@
#include "platform/platform.h"
#include "platform/vfs.h"
#include "platform/system.h"
#include "platform/openssl.h"
void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
{
@ -41,6 +43,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_config_load(&cfg->openssl, filename);
}
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename)
@ -362,3 +365,12 @@ void epay_config_load(struct epay_config *cfg, const wchar_t *filename)
cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename);
cfg->hook = GetPrivateProfileIntW(L"epay", L"hook", 1, filename);
}
void openssl_config_load(struct openssl_config *cfg, const wchar_t *filename)
{
assert(cfg != NULL);
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(L"openssl", L"enable", 1, filename);
cfg->override = GetPrivateProfileIntW(L"openssl", L"override", 0, filename);
}

View File

@ -19,6 +19,7 @@
#include "platform/platform.h"
#include "platform/vfs.h"
#include "platform/system.h"
#include "platform/openssl.h"
void platform_config_load(
struct platform_config *cfg,
@ -36,3 +37,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_config_load(struct openssl_config *cfg, const wchar_t *filename);

View File

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

116
common/platform/openssl.c Normal file
View File

@ -0,0 +1,116 @@
#include <windows.h>
#include <assert.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <intrin.h>
#include "hook/table.h"
#include "hooklib/config.h"
#include "platform/openssl.h"
#include "util/dprintf.h"
/* API hooks */
static char * __cdecl hook_getenv(const char *name);
/* Link pointers */
static char * (__cdecl *next_getenv)(const char *name);
static bool openssl_hook_initted;
static struct openssl_config openssl_config;
static const struct hook_symbol openssl_hooks[] = {
{
.name = "getenv",
.patch = hook_getenv,
.link = (void **) &next_getenv
},
};
static int check_intel_sha_extension() {
int n_ids;
int is_intel;
char vendor[0x20] = {0};
int cpui[4] = {0};
/* OpenSSL 1.0.2 beta to 1.0.2k contain bugs that crash "AM Daemon" due to
bad SHA values on processors with the SHA extensions, such as Intel 10th
gen CPUs or higher.
Credits: kagaminehaku */
__cpuid(cpui, 0);
n_ids = cpui[0];
*((int *) vendor) = cpui[1];
*((int *) (vendor + 4)) = cpui[3];
*((int *) (vendor + 8)) = cpui[2];
/* Check that the CPU vendor is Intel */
is_intel = (strcmp(vendor, "GenuineIntel") == 0);
if (is_intel && n_ids >= 7) {
__cpuidex(cpui, 7, 0);
/* SHA extensions supported */
return (cpui[1] & (1 << 29)) != 0;
}
return 0;
}
HRESULT openssl_hook_init(const struct openssl_config *cfg)
{
assert(cfg != NULL);
if (!cfg->enable) {
return S_FALSE;
}
if (openssl_hook_initted) {
return S_FALSE;
}
if (cfg->override) {
dprintf("OpenSSL: hook enabled.\n");
} else if (check_intel_sha_extension()) {
dprintf("OpenSSL: Intel CPU SHA extension detected, hook enabled.\n");
} else {
return S_FALSE;
}
openssl_hook_initted = true;
memcpy(&openssl_config, cfg, sizeof(*cfg));
hook_table_apply(
NULL,
"msvcr110.dll",
openssl_hooks,
_countof(openssl_hooks)
);
return S_OK;
}
static char * __cdecl hook_getenv(const char *name)
{
/* Overrides OpenSSL's Intel CPU identification. This disables the OpenSSL
code check for SHA extensions. */
if (name && strcmp(name, "OPENSSL_ia32cap") == 0) {
static char override[] = "~0x20000000";
dprintf("OpenSSL: Overriding OPENSSL_ia32cap -> %s\n", override);
return override;
}
char *real_val = next_getenv(name);
return real_val;
}

12
common/platform/openssl.h Normal file
View File

@ -0,0 +1,12 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
struct openssl_config {
bool enable;
bool override;
};
HRESULT openssl_hook_init(const struct openssl_config *cfg);

View File

@ -14,6 +14,7 @@
#include "platform/platform.h"
#include "platform/vfs.h"
#include "platform/system.h"
#include "platform/openssl.h"
HRESULT platform_hook_init(
const struct platform_config *cfg,
@ -94,5 +95,11 @@ HRESULT platform_hook_init(
return hr;
}
hr = openssl_hook_init(&cfg->openssl);
if (FAILED(hr)) {
return hr;
}
return S_OK;
}

View File

@ -14,6 +14,7 @@
#include "platform/pcbid.h"
#include "platform/vfs.h"
#include "platform/system.h"
#include "platform/openssl.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_config openssl;
};
HRESULT platform_hook_init(

View File

@ -663,4 +663,21 @@ Enables the Thinca emulation. This will allow you to enable E-Money on compatibl
Default: `1`
Enables hooking of respective Thinca DLL functions to emulate the existence of E-Money. This cannot be used with a real E-Money server.
Enables hooking of respective Thinca DLL functions to emulate the existence of E-Money. This cannot be used with a real E-Money server.
## `[openssl]`
Configure the OpenSSL SHA extension bug hook.
### `enable`
Default: `1`
Enables the OpenSSL hook to fix the SHA extension bug on Intel CPUs.
### `override`
Default: `0`
Enables the override to always hook the OpenSSL env variable. By default the
hook is only applied to Intel CPUs with the SHA extension present.

View File

@ -1,4 +1,4 @@
[wrap-git]
directory = capnhook
url = https://gitea.tendokyu.moe/TeamTofuShop/capnhook
revision = dafd0aa336ab80ba87a82370a9dc95a3389ef5e5
revision = 252465b23f51f36206e614190496663425f4ee5d