forked from Hay1tsme/segatools
Merge branch 'master' into develop
This commit is contained in:
commit
5ef0cf6181
252
hooklib/createprocess.c
Normal file
252
hooklib/createprocess.c
Normal file
@ -0,0 +1,252 @@
|
|||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include "hook/table.h"
|
||||||
|
|
||||||
|
#include "hooklib/createprocess.h"
|
||||||
|
|
||||||
|
#include "util/dprintf.h"
|
||||||
|
|
||||||
|
void createprocess_hook_init();
|
||||||
|
static BOOL WINAPI my_CreateProcessA(
|
||||||
|
LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOA lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
);
|
||||||
|
BOOL my_CreateProcessW(
|
||||||
|
LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOW lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
static BOOL (WINAPI *next_CreateProcessA)(
|
||||||
|
LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOA lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
static BOOL (WINAPI *next_CreateProcessW)(
|
||||||
|
LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOW lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
);
|
||||||
|
|
||||||
|
static const struct hook_symbol win32_hooks[] = {
|
||||||
|
{
|
||||||
|
.name = "CreateProcessA",
|
||||||
|
.patch = my_CreateProcessA,
|
||||||
|
.link = (void **) &next_CreateProcessA
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "CreateProcessW",
|
||||||
|
.patch = my_CreateProcessW,
|
||||||
|
.link = (void **) &next_CreateProcessW
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
static bool did_init = false;
|
||||||
|
|
||||||
|
static struct process_hook_sym_w *process_syms_w;
|
||||||
|
static struct process_hook_sym_a *process_syms_a;
|
||||||
|
|
||||||
|
static size_t process_nsyms_a = 0;
|
||||||
|
static size_t process_nsyms_w = 0;
|
||||||
|
|
||||||
|
static CRITICAL_SECTION createproc_lock;
|
||||||
|
|
||||||
|
HRESULT createprocess_push_hook_w(const wchar_t *name, const wchar_t *head, const wchar_t *tail) {
|
||||||
|
struct process_hook_sym_w *new_mem;
|
||||||
|
struct process_hook_sym_w *new_proc;
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
assert(name != NULL);
|
||||||
|
assert(head != NULL);
|
||||||
|
|
||||||
|
createprocess_hook_init();
|
||||||
|
EnterCriticalSection(&createproc_lock);
|
||||||
|
|
||||||
|
new_mem = realloc(
|
||||||
|
process_syms_w,
|
||||||
|
(process_nsyms_w + 1) * sizeof(struct process_hook_sym_w));
|
||||||
|
|
||||||
|
if (new_mem == NULL) {
|
||||||
|
|
||||||
|
LeaveCriticalSection(&createproc_lock);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_proc = &new_mem[process_nsyms_w];
|
||||||
|
memset(new_proc, 0, sizeof(*new_proc));
|
||||||
|
new_proc->name = name;
|
||||||
|
new_proc->head = head;
|
||||||
|
new_proc->tail = tail;
|
||||||
|
|
||||||
|
process_syms_w = new_mem;
|
||||||
|
process_nsyms_w++;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&createproc_lock);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
HRESULT createprocess_push_hook_a(const char *name, const char *head, const char *tail) {
|
||||||
|
struct process_hook_sym_a *new_mem;
|
||||||
|
struct process_hook_sym_a *new_proc;
|
||||||
|
|
||||||
|
assert(name != NULL);
|
||||||
|
assert(head != NULL);
|
||||||
|
|
||||||
|
createprocess_hook_init();
|
||||||
|
|
||||||
|
EnterCriticalSection(&createproc_lock);
|
||||||
|
|
||||||
|
new_mem = realloc(
|
||||||
|
process_syms_a,
|
||||||
|
(process_nsyms_a + 1) * sizeof(struct process_hook_sym_a));
|
||||||
|
|
||||||
|
if (new_mem == NULL) {
|
||||||
|
|
||||||
|
LeaveCriticalSection(&createproc_lock);
|
||||||
|
return E_OUTOFMEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
new_proc = &new_mem[process_nsyms_a];
|
||||||
|
memset(new_proc, 0, sizeof(*new_proc));
|
||||||
|
new_proc->name = name;
|
||||||
|
new_proc->head = head;
|
||||||
|
new_proc->tail = tail;
|
||||||
|
|
||||||
|
process_syms_a = new_mem;
|
||||||
|
process_nsyms_a++;
|
||||||
|
|
||||||
|
LeaveCriticalSection(&createproc_lock);
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
void createprocess_hook_init() {
|
||||||
|
if (did_init) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
did_init = true;
|
||||||
|
|
||||||
|
hook_table_apply(
|
||||||
|
NULL,
|
||||||
|
"kernel32.dll",
|
||||||
|
win32_hooks,
|
||||||
|
_countof(win32_hooks));
|
||||||
|
InitializeCriticalSection(&createproc_lock);
|
||||||
|
dprintf("CreateProcess: Init\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static BOOL WINAPI my_CreateProcessA(
|
||||||
|
LPCSTR lpApplicationName,
|
||||||
|
LPSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOA lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation
|
||||||
|
)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < process_nsyms_a; i++) {
|
||||||
|
if (strncmp(process_syms_a->name, lpCommandLine, strlen(process_syms_a->name))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
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 != 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,
|
||||||
|
lpProcessAttributes,
|
||||||
|
lpThreadAttributes,
|
||||||
|
bInheritHandles,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return next_CreateProcessA(
|
||||||
|
lpApplicationName,
|
||||||
|
lpCommandLine,
|
||||||
|
lpProcessAttributes,
|
||||||
|
lpThreadAttributes,
|
||||||
|
bInheritHandles,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL my_CreateProcessW(
|
||||||
|
LPCWSTR lpApplicationName,
|
||||||
|
LPWSTR lpCommandLine,
|
||||||
|
LPSECURITY_ATTRIBUTES lpProcessAttributes,
|
||||||
|
LPSECURITY_ATTRIBUTES lpThreadAttributes,
|
||||||
|
BOOL bInheritHandles,
|
||||||
|
DWORD dwCreationFlags,
|
||||||
|
LPVOID lpEnvironment,
|
||||||
|
LPCWSTR lpCurrentDirectory,
|
||||||
|
LPSTARTUPINFOW lpStartupInfo,
|
||||||
|
LPPROCESS_INFORMATION lpProcessInformation)
|
||||||
|
{
|
||||||
|
return next_CreateProcessW(
|
||||||
|
lpApplicationName,
|
||||||
|
lpCommandLine,
|
||||||
|
lpProcessAttributes,
|
||||||
|
lpThreadAttributes,
|
||||||
|
bInheritHandles,
|
||||||
|
dwCreationFlags,
|
||||||
|
lpEnvironment,
|
||||||
|
lpCurrentDirectory,
|
||||||
|
lpStartupInfo,
|
||||||
|
lpProcessInformation
|
||||||
|
);
|
||||||
|
}
|
24
hooklib/createprocess.h
Normal file
24
hooklib/createprocess.h
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <windows.h>
|
||||||
|
|
||||||
|
HRESULT createprocess_push_hook_w(const wchar_t *name, const wchar_t *head, const wchar_t *tail);
|
||||||
|
HRESULT createprocess_push_hook_a(const char *name, const char *head, const char *tail);
|
||||||
|
|
||||||
|
struct process_hook_sym_w {
|
||||||
|
const wchar_t *name;
|
||||||
|
size_t name_size;
|
||||||
|
const wchar_t *head;
|
||||||
|
size_t head_size;
|
||||||
|
const wchar_t *tail;
|
||||||
|
size_t tail_size;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct process_hook_sym_a {
|
||||||
|
const char *name;
|
||||||
|
size_t name_size;
|
||||||
|
const char *head;
|
||||||
|
size_t head_size;
|
||||||
|
const char *tail;
|
||||||
|
size_t tail_size;
|
||||||
|
};
|
@ -9,6 +9,8 @@ hooklib_lib = static_library(
|
|||||||
sources : [
|
sources : [
|
||||||
'config.c',
|
'config.c',
|
||||||
'config.h',
|
'config.h',
|
||||||
|
'createprocess.c',
|
||||||
|
'createprocess.h',
|
||||||
'dll.c',
|
'dll.c',
|
||||||
'dll.h',
|
'dll.h',
|
||||||
'dns.c',
|
'dns.c',
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
#include "platform/clock.h"
|
#include "platform/clock.h"
|
||||||
#include "platform/config.h"
|
#include "platform/config.h"
|
||||||
#include "platform/dns.h"
|
#include "platform/dns.h"
|
||||||
|
#include "platform/epay.h"
|
||||||
#include "platform/hwmon.h"
|
#include "platform/hwmon.h"
|
||||||
#include "platform/hwreset.h"
|
#include "platform/hwreset.h"
|
||||||
#include "platform/misc.h"
|
#include "platform/misc.h"
|
||||||
@ -31,6 +32,7 @@ void platform_config_load(struct platform_config *cfg, const wchar_t *filename)
|
|||||||
amvideo_config_load(&cfg->amvideo, filename);
|
amvideo_config_load(&cfg->amvideo, filename);
|
||||||
clock_config_load(&cfg->clock, filename);
|
clock_config_load(&cfg->clock, filename);
|
||||||
dns_config_load(&cfg->dns, filename);
|
dns_config_load(&cfg->dns, filename);
|
||||||
|
epay_config_load(&cfg->epay, filename);
|
||||||
hwmon_config_load(&cfg->hwmon, filename);
|
hwmon_config_load(&cfg->hwmon, filename);
|
||||||
hwreset_config_load(&cfg->hwreset, filename);
|
hwreset_config_load(&cfg->hwreset, filename);
|
||||||
misc_config_load(&cfg->misc, filename);
|
misc_config_load(&cfg->misc, filename);
|
||||||
|
@ -9,6 +9,7 @@
|
|||||||
#include "platform/amvideo.h"
|
#include "platform/amvideo.h"
|
||||||
#include "platform/clock.h"
|
#include "platform/clock.h"
|
||||||
#include "platform/dns.h"
|
#include "platform/dns.h"
|
||||||
|
#include "platform/epay.h"
|
||||||
#include "platform/hwmon.h"
|
#include "platform/hwmon.h"
|
||||||
#include "platform/hwreset.h"
|
#include "platform/hwreset.h"
|
||||||
#include "platform/misc.h"
|
#include "platform/misc.h"
|
||||||
@ -26,6 +27,7 @@ void platform_config_load(
|
|||||||
void amvideo_config_load(struct amvideo_config *cfg, const wchar_t *filename);
|
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 clock_config_load(struct clock_config *cfg, const wchar_t *filename);
|
||||||
void dns_config_load(struct dns_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 hwmon_config_load(struct hwmon_config *cfg, const wchar_t *filename);
|
||||||
void hwreset_config_load(struct hwreset_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);
|
void misc_config_load(struct misc_config *cfg, const wchar_t *filename);
|
||||||
|
335
platform/epay.c
Normal file
335
platform/epay.c
Normal 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
63
platform/epay.h
Normal 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);
|
@ -16,6 +16,8 @@ platform_lib = static_library(
|
|||||||
'config.h',
|
'config.h',
|
||||||
'dns.c',
|
'dns.c',
|
||||||
'dns.h',
|
'dns.h',
|
||||||
|
'epay.c',
|
||||||
|
'epay.h',
|
||||||
'hwmon.c',
|
'hwmon.c',
|
||||||
'hwmon.h',
|
'hwmon.h',
|
||||||
'hwreset.c',
|
'hwreset.c',
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "platform/amvideo.h"
|
#include "platform/amvideo.h"
|
||||||
#include "platform/clock.h"
|
#include "platform/clock.h"
|
||||||
#include "platform/dns.h"
|
#include "platform/dns.h"
|
||||||
|
#include "platform/epay.h"
|
||||||
#include "platform/hwmon.h"
|
#include "platform/hwmon.h"
|
||||||
#include "platform/misc.h"
|
#include "platform/misc.h"
|
||||||
#include "platform/netenv.h"
|
#include "platform/netenv.h"
|
||||||
@ -87,5 +88,11 @@ HRESULT platform_hook_init(
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = epay_hook_init(&cfg->epay);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include "platform/amvideo.h"
|
#include "platform/amvideo.h"
|
||||||
#include "platform/clock.h"
|
#include "platform/clock.h"
|
||||||
#include "platform/dns.h"
|
#include "platform/dns.h"
|
||||||
|
#include "platform/epay.h"
|
||||||
#include "platform/hwmon.h"
|
#include "platform/hwmon.h"
|
||||||
#include "platform/hwreset.h"
|
#include "platform/hwreset.h"
|
||||||
#include "platform/misc.h"
|
#include "platform/misc.h"
|
||||||
@ -18,6 +19,7 @@ struct platform_config {
|
|||||||
struct amvideo_config amvideo;
|
struct amvideo_config amvideo;
|
||||||
struct clock_config clock;
|
struct clock_config clock;
|
||||||
struct dns_config dns;
|
struct dns_config dns;
|
||||||
|
struct epay_config epay;
|
||||||
struct hwmon_config hwmon;
|
struct hwmon_config hwmon;
|
||||||
struct hwreset_config hwreset;
|
struct hwreset_config hwreset;
|
||||||
struct misc_config misc;
|
struct misc_config misc;
|
||||||
|
@ -20,6 +20,10 @@ static HRESULT vfs_path_hook_nthome(
|
|||||||
const wchar_t *src,
|
const wchar_t *src,
|
||||||
wchar_t *dest,
|
wchar_t *dest,
|
||||||
size_t *count);
|
size_t *count);
|
||||||
|
static HRESULT vfs_path_hook_w10home(
|
||||||
|
const wchar_t *src,
|
||||||
|
wchar_t *dest,
|
||||||
|
size_t *count);
|
||||||
static HRESULT vfs_path_hook_option(
|
static HRESULT vfs_path_hook_option(
|
||||||
const wchar_t *src,
|
const wchar_t *src,
|
||||||
wchar_t *dest,
|
wchar_t *dest,
|
||||||
@ -31,6 +35,9 @@ static wchar_t vfs_nthome_real[MAX_PATH];
|
|||||||
static const wchar_t vfs_nthome[] = L"C:\\Documents and Settings\\AppUser";
|
static const wchar_t vfs_nthome[] = L"C:\\Documents and Settings\\AppUser";
|
||||||
static const size_t vfs_nthome_len = _countof(vfs_nthome) - 1;
|
static const size_t vfs_nthome_len = _countof(vfs_nthome) - 1;
|
||||||
|
|
||||||
|
static const wchar_t vfs_w10home[] = L"C:\\Users\\AppUser";
|
||||||
|
static const size_t vfs_w10home_len = _countof(vfs_w10home) - 1;
|
||||||
|
|
||||||
static const wchar_t vfs_option[] = L"C:\\Mount\\Option";
|
static const wchar_t vfs_option[] = L"C:\\Mount\\Option";
|
||||||
static const size_t vfs_option_len = _countof(vfs_option) - 1;
|
static const size_t vfs_option_len = _countof(vfs_option) - 1;
|
||||||
|
|
||||||
@ -144,6 +151,12 @@ HRESULT vfs_hook_init(const struct vfs_config *config)
|
|||||||
return hr;
|
return hr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
hr = path_hook_push(vfs_path_hook_w10home);
|
||||||
|
|
||||||
|
if (FAILED(hr)) {
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
|
||||||
if (vfs_config.option[0] != L'\0') {
|
if (vfs_config.option[0] != L'\0') {
|
||||||
hr = path_hook_push(vfs_path_hook_option);
|
hr = path_hook_push(vfs_path_hook_option);
|
||||||
|
|
||||||
@ -357,6 +370,53 @@ static HRESULT vfs_path_hook_nthome(
|
|||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static HRESULT vfs_path_hook_w10home(
|
||||||
|
const wchar_t *src,
|
||||||
|
wchar_t *dest,
|
||||||
|
size_t *count)
|
||||||
|
{
|
||||||
|
size_t required;
|
||||||
|
size_t redir_len;
|
||||||
|
size_t shift;
|
||||||
|
|
||||||
|
assert(src != NULL);
|
||||||
|
assert(count != NULL);
|
||||||
|
|
||||||
|
/* Case-insensitive check to see if src starts with vfs_w10home */
|
||||||
|
|
||||||
|
if (path_compare_w(src, vfs_w10home, vfs_w10home_len) != 0) {
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Check if the character after vfs_w10home is a separator or the end of
|
||||||
|
the string */
|
||||||
|
|
||||||
|
if (!path_is_separator_w(src[vfs_w10home_len]) &&
|
||||||
|
src[vfs_w10home_len] != L'\0')
|
||||||
|
{
|
||||||
|
return S_FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Cut off the matched <prefix>\, add the replaced prefix, count NUL */
|
||||||
|
|
||||||
|
shift = path_is_separator_w(src[vfs_w10home_len]) ? 1 : 0;
|
||||||
|
redir_len = wcslen(vfs_nthome_real);
|
||||||
|
required = wcslen(src) - vfs_w10home_len - shift + redir_len + 1;
|
||||||
|
|
||||||
|
if (dest != NULL) {
|
||||||
|
if (required > *count) {
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_INSUFFICIENT_BUFFER);
|
||||||
|
}
|
||||||
|
|
||||||
|
wcscpy_s(dest, *count, vfs_nthome_real);
|
||||||
|
wcscpy_s(dest + redir_len, *count - redir_len, src + vfs_w10home_len + shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
*count = required;
|
||||||
|
|
||||||
|
return S_OK;
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT vfs_path_hook_option(
|
static HRESULT vfs_path_hook_option(
|
||||||
const wchar_t *src,
|
const wchar_t *src,
|
||||||
wchar_t *dest,
|
wchar_t *dest,
|
||||||
|
Loading…
Reference in New Issue
Block a user