platform: add epay hook

This commit is contained in:
Hay1tsme 2023-09-15 01:35:33 -04:00
parent 0d83977073
commit 157f52da4c
9 changed files with 426 additions and 3 deletions

View File

@ -188,15 +188,16 @@ static BOOL WINAPI my_CreateProcessA(
continue;
}
dprintf("CreateProcess: Hooking child process %s\n", lpCommandLine);
char new_cmd[MAX_PATH];
dprintf("CreateProcess: Hooking child process %s %s\n", lpApplicationName, lpCommandLine);
char new_cmd[MAX_PATH] = {0};
strcat_s(new_cmd, MAX_PATH, process_syms_a->head);
strcat_s(new_cmd, MAX_PATH, lpCommandLine);
if (process_syms_a->tail[0]) {
if (process_syms_a->tail != NULL) {
strcat_s(new_cmd, MAX_PATH, process_syms_a->tail);
}
dprintf("CreateProcess: Replaced CreateProcessA %s\n", new_cmd);
return next_CreateProcessA(
lpApplicationName,
new_cmd,

View File

@ -1,3 +1,5 @@
#pragma once
#include <windows.h>
HRESULT createprocess_push_hook_w(const wchar_t *name, const wchar_t *head, const wchar_t *tail);

View File

@ -13,6 +13,7 @@
#include "platform/clock.h"
#include "platform/config.h"
#include "platform/dns.h"
#include "platform/epay.h"
#include "platform/hwmon.h"
#include "platform/hwreset.h"
#include "platform/misc.h"
@ -30,6 +31,7 @@ void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
amvideo_config_load(&cfg->amvideo, filename);
clock_config_load(&cfg->clock, filename);
dns_config_load(&cfg->dns, filename);
epay_config_load(&cfg->epay, filename);
hwmon_config_load(&cfg->hwmon, filename);
hwreset_config_load(&cfg->hwreset, filename);
misc_config_load(&cfg->misc, filename);
@ -317,3 +319,10 @@ void vfs_config_load(struct vfs_config *cfg, const wchar_t *filename)
filename);
}
void epay_config_load(struct epay_config *cfg, const wchar_t *filename)
{
assert(cfg != NULL);
assert(filename != NULL);
cfg->enable = GetPrivateProfileIntW(L"epay", L"enable", 1, filename);
}

View File

@ -9,6 +9,7 @@
#include "platform/amvideo.h"
#include "platform/clock.h"
#include "platform/dns.h"
#include "platform/epay.h"
#include "platform/hwmon.h"
#include "platform/hwreset.h"
#include "platform/misc.h"
@ -25,6 +26,7 @@ void platform_config_load(
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename);
void clock_config_load(struct clock_config *cfg, const wchar_t *filename);
void dns_config_load(struct dns_config *cfg, const wchar_t *filename);
void epay_config_load(struct epay_config *cfg, const wchar_t *filename);
void hwmon_config_load(struct hwmon_config *cfg, const wchar_t *filename);
void hwreset_config_load(struct hwreset_config *cfg, const wchar_t *filename);
void misc_config_load(struct misc_config *cfg, const wchar_t *filename);

335
platform/epay.c Normal file
View File

@ -0,0 +1,335 @@
#include <windows.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include "hook/table.h"
#include "hooklib/reg.h"
#include "platform/epay.h"
#include "util/dprintf.h"
static HRESULT misc_read_thinca_adapter(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_ca_loc(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_ca_client_loc(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_network_timeout(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_pattern0(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_network_timeout0(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_pattern1(void *bytes, uint32_t *nbytes);
static HRESULT misc_read_network_timeout1(void *bytes, uint32_t *nbytes);
static uint64_t thinca_initialize(struct thinca_impl * self, uint64_t val);
static uint64_t thinca_dispose(struct thinca_impl * self);
static uint64_t thinca_set_resource(struct thinca_impl * self, char * res);
static uint64_t thinca_set_pay_log(struct thinca_impl * self, uint64_t val, char * log, uint64_t val2, const char * size_lim);
static uint64_t thinca_set_client_log(struct thinca_impl * self, uint64_t val, char * log);
static uint64_t thinca_set_client_cfg(struct thinca_impl * self, char * log, uint64_t val);
static uint64_t thinca_set_goods_code(struct thinca_impl * self, char * code);
static uint64_t thinca_set_evt_handler(struct thinca_impl * self, void* handler);
static uint64_t thinca_set_cert(struct thinca_impl * self, char * cert, uint64_t val);
static uint64_t thinca_set_serial(struct thinca_impl * self, char * cert);
static uint64_t thinca_check_deal(struct thinca_impl * self, void* deal);
static uint64_t thinca_cancel(struct thinca_impl * self);
static uint64_t thinca_select(struct thinca_impl * self);
static uint64_t thinca_unk(struct thinca_impl * self, uint64_t val);
static void thinca_unk8(struct thinca_impl * self);
static uint64_t my_ThincaPaymentGetVersion();
static uint64_t (*next_ThincaPaymentGetVersion)();
static struct thinca_main* my_ThincaPaymentGetInstance(uint64_t ver);
static struct thinca_main* (*next_ThincaPaymentGetInstance)(uint64_t ver);
static struct thinca_main* thinca_stub;
static const struct reg_hook_val epay_adapter_keys[] = {
{
.name = L"TfpsAimeRwAdapter",
.read = misc_read_thinca_adapter,
.type = REG_SZ,
}
};
static const struct reg_hook_val epay_tcap_keys[] = {
{
.name = L"CaLocation",
.read = misc_read_ca_loc,
.type = REG_SZ,
},
{
.name = L"ThincaTcapClientPath",
.read = misc_read_ca_client_loc,
.type = REG_SZ,
},
{
.name = L"ClientNetworkTimeout",
.read = misc_read_network_timeout,
.type = REG_DWORD,
}
};
static const struct reg_hook_val epay_tcap_url0_keys[] = {
{
.name = L"Pattern",
.read = misc_read_pattern0,
.type = REG_SZ,
},
{
.name = L"ClientNetworkTimeout",
.read = misc_read_network_timeout0,
.type = REG_DWORD,
}
};
static const struct reg_hook_val epay_tcap_url1_keys[] = {
{
.name = L"Pattern",
.read = misc_read_pattern1,
.type = REG_SZ,
},
{
.name = L"ClientNetworkTimeout",
.read = misc_read_network_timeout1,
.type = REG_DWORD,
}
};
static const struct hook_symbol epay_syms[] = {
{
.name = "ThincaPaymentGetVersion",
.patch = my_ThincaPaymentGetVersion,
.link = (void **) &next_ThincaPaymentGetVersion,
.ordinal = 1,
},
{
.name = "__imp_ThincaPaymentGetInstance",
.patch = my_ThincaPaymentGetInstance,
.link = (void **) &next_ThincaPaymentGetInstance,
.ordinal = 2,
},
{
.name = "ThincaPaymentGetInstance",
.patch = my_ThincaPaymentGetInstance,
.link = (void **) &next_ThincaPaymentGetInstance,
.ordinal = 2,
}
};
HRESULT epay_hook_init(const struct epay_config *cfg) {
HRESULT hr;
assert(cfg != NULL);
if (!cfg->enable) {
return S_FALSE;
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\TFPaymentService\\ThincaRwAdapter",
epay_adapter_keys,
_countof(epay_adapter_keys));
if (FAILED(hr)) {
return hr;
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\TFPaymentService\\ThincaTcapClient",
epay_tcap_keys,
_countof(epay_tcap_keys));
if (FAILED(hr)) {
return hr;
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\TFPaymentService\\ThincaTcapClient\\URL0",
epay_tcap_url0_keys,
_countof(epay_tcap_url0_keys));
if (FAILED(hr)) {
return hr;
}
hr = reg_hook_push_key(
HKEY_LOCAL_MACHINE,
L"SOFTWARE\\TFPaymentService\\ThincaTcapClient\\URL1",
epay_tcap_url1_keys,
_countof(epay_tcap_url1_keys));
hook_table_apply(
NULL,
"ThincaPayment.dll",
epay_syms,
_countof(epay_syms));
thinca_stub = (struct thinca_main *)malloc(sizeof(struct thinca_main));
thinca_stub->impl1 = (struct thinca_impl *)malloc(sizeof(struct thinca_impl));
thinca_stub->impl1->unk8 = thinca_unk8;
thinca_stub->impl1->initialize = thinca_initialize;
thinca_stub->impl1->dispose = thinca_dispose;
thinca_stub->impl1->setResource = thinca_set_resource;
thinca_stub->impl1->setThincaPaymentLog = thinca_set_pay_log;
thinca_stub->impl1->setThincaEventInterface = thinca_set_evt_handler;
thinca_stub->impl1->setIcasClientLog = thinca_set_client_log;
thinca_stub->impl1->setIcasClientConfig = thinca_set_client_cfg;
thinca_stub->impl1->setGoodsCode = thinca_set_goods_code;
thinca_stub->impl1->setTerminalSerial = thinca_set_serial;
thinca_stub->impl1->setClientCertificate = thinca_set_cert;
thinca_stub->impl1->checkDeal = thinca_check_deal;
thinca_stub->impl1->cancelRequest = thinca_cancel;
thinca_stub->impl1->selectButton = thinca_select;
thinca_stub->impl1->unk220 = thinca_unk;
thinca_stub->impl1->unk228 = thinca_unk;
dprintf("Epay: Init\n");
return hr;
}
static HRESULT misc_read_thinca_adapter(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"aime_rw_adapterMD.dll");
}
static HRESULT misc_read_ca_loc(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"ca.pem");
}
static HRESULT misc_read_ca_client_loc(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L"thincatcapclient.dll");
}
static HRESULT misc_read_network_timeout(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 20000);
}
static HRESULT misc_read_pattern0(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L".*\\.jsp");
}
static HRESULT misc_read_network_timeout0(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 5000);
}
static HRESULT misc_read_pattern1(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_wstr(bytes, nbytes, L".*(closing|remove).*");
}
static HRESULT misc_read_network_timeout1(void *bytes, uint32_t *nbytes)
{
return reg_hook_read_u32(bytes, nbytes, 60000);
}
static uint64_t thinca_initialize(struct thinca_impl * self, uint64_t val)
{
dprintf("Epay: Thinca Initialize %lld\n", val);
return 0;
}
static uint64_t thinca_dispose(struct thinca_impl * self)
{
dprintf("Epay: Thinca Dispose\n");
return 0;
}
static uint64_t thinca_set_resource(struct thinca_impl * self, char * res)
{
dprintf("Epay: Thinca Set Resource %s\n", res);
return 0;
}
static uint64_t thinca_set_pay_log(struct thinca_impl * self, uint64_t val, char * log, uint64_t val2, const char * size_lim)
{
dprintf("Epay: Thinca Set Paylog %lld | %s | %lld | %s\n", val, log, val2, size_lim);
return 0;
}
static uint64_t thinca_set_client_log(struct thinca_impl * self, uint64_t val, char * log)
{
dprintf("Epay: Thinca Set ICAS Client log %lld | %s\n", val, log);
return 0;
}
static uint64_t thinca_set_client_cfg(struct thinca_impl * self, char * log, uint64_t val)
{
dprintf("Epay: Thinca Set ICAS Client Config %s | %lld\n", log, val);
return 0;
}
static uint64_t thinca_set_goods_code(struct thinca_impl * self, char * code)
{
dprintf("Epay: Thinca Set Goods Code %s\n", code);
return 0;
}
static uint64_t thinca_set_evt_handler(struct thinca_impl * self, void* handler)
{
dprintf("Epay: Thinca Set Event Handler %p\n", handler);
return 0;
}
static uint64_t thinca_set_cert(struct thinca_impl * self, char * cert, uint64_t val)
{
dprintf("Epay: Thinca Set Client Cert %s | %lld\n", cert, val);
return 0;
}
static uint64_t thinca_set_serial(struct thinca_impl * self, char * cert)
{
dprintf("Epay: Thinca Set Terminal Serial %s\n", cert);
return 0;
}
static uint64_t thinca_check_deal(struct thinca_impl * self, void* deal)
{
dprintf("Epay: Thinca Check Deal %p\n", deal);
return 0;
}
static uint64_t thinca_cancel(struct thinca_impl * self)
{
dprintf("Epay: Thinca Cancel\n");
return 0;
}
static uint64_t thinca_select(struct thinca_impl * self)
{
dprintf("Epay: Thinca Select\n");
return 0;
}
static uint64_t thinca_unk(struct thinca_impl * self, uint64_t val)
{
dprintf("Epay: Thinca Unknown 220/228 %lld\n", val);
return 0;
}
static void thinca_unk8(struct thinca_impl * self)
{
dprintf("Epay: Thinca Unknown 8\n");
}
static uint64_t my_ThincaPaymentGetVersion()
{
return 0x1040B00;
}
static struct thinca_main* my_ThincaPaymentGetInstance(uint64_t ver)
{
dprintf("Epay: my_ThincaPaymentGetInstance hit!\n");
return thinca_stub;
}

63
platform/epay.h Normal file
View File

@ -0,0 +1,63 @@
#pragma once
#include <windows.h>
#include <stdbool.h>
#pragma pack(push,1)
struct epay_config {
bool enable;
};
/* The functions in these structs are how clients like amdaemon interface
* with thinca. We can simply replace these functions with our own stubs
* to bypass errors and such. Currently this DOES NOT allow for epay, and
* trying to do so will most likely just lead to misery. My goal isn't to
* reimplement epay, just to give amdaemon SOMETHING so we can boot properly.
*/
struct thinca_impl {
uint64_t* unk0;
void (*unk8)(struct thinca_impl *);
uint64_t (*initialize)(struct thinca_impl *, uint64_t);
uint64_t (*dispose)(struct thinca_impl *);
uint64_t (*setResource)(struct thinca_impl *, char *);
uint64_t (*setThincaPaymentLog)(struct thinca_impl *, uint64_t, char *, uint64_t, const char *);
uint64_t (*setIcasClientLog)(struct thinca_impl *, uint64_t, char *);
uint64_t (*setIcasClientConfig)(struct thinca_impl *, char *, uint64_t);
uint64_t* unk40;
uint64_t* unk48;
uint64_t (*setClientCertificate)(struct thinca_impl *, char *, uint64_t);
uint64_t (*setTerminalSerial)(struct thinca_impl *, char *);
uint64_t (*setGoodsCode)(struct thinca_impl *, char *);
uint64_t unk68;
uint64_t (*setThincaEventInterface)(struct thinca_impl *, void*); // probably a struct
uint64_t unkGap78[7];
uint64_t (*checkDeal)(struct thinca_impl *, void *); // probably a struct
uint64_t unkGapB8[41];
uint64_t (*cancelRequest)(struct thinca_impl *);
uint64_t (*selectButton)(struct thinca_impl *);
uint64_t unkGap210[2];
uint64_t (*unk220)(struct thinca_impl *, uint64_t);
uint64_t (*unk228)(struct thinca_impl *, uint64_t);
};
/* I believe the actual struct is 0x310 bytes, so for now I'm just
* implementing what I need and hoping the rest don't cause issues
* later. AMDaemon seems to only care about impl1 and deal_thing,
* at least from what I can tell
*/
struct thinca_main {
struct thinca_impl* impl1;
struct thinca_impl* impl2;
HANDLE* mutex1;
HANDLE* mutex2;
HANDLE* mutex3;
uint64_t* unk28;
uint64_t* unk30;
uint64_t* unk38;
uint64_t* unk40;
uint64_t* deal_thing;
uint64_t filler[88];
};
#pragma pack(pop)
HRESULT epay_hook_init(const struct epay_config *cfg);

View File

@ -16,6 +16,8 @@ platform_lib = static_library(
'config.h',
'dns.c',
'dns.h',
'epay.c',
'epay.h',
'hwmon.c',
'hwmon.h',
'hwreset.c',

View File

@ -5,6 +5,7 @@
#include "platform/amvideo.h"
#include "platform/clock.h"
#include "platform/dns.h"
#include "platform/epay.h"
#include "platform/hwmon.h"
#include "platform/misc.h"
#include "platform/netenv.h"
@ -80,5 +81,11 @@ HRESULT platform_hook_init(
return hr;
}
hr = epay_hook_init(&cfg->epay);
if (FAILED(hr)) {
return hr;
}
return S_OK;
}

View File

@ -5,6 +5,7 @@
#include "platform/amvideo.h"
#include "platform/clock.h"
#include "platform/dns.h"
#include "platform/epay.h"
#include "platform/hwmon.h"
#include "platform/hwreset.h"
#include "platform/misc.h"
@ -17,6 +18,7 @@ struct platform_config {
struct amvideo_config amvideo;
struct clock_config clock;
struct dns_config dns;
struct epay_config epay;
struct hwmon_config hwmon;
struct hwreset_config hwreset;
struct misc_config misc;