Bemanitools v5.26 release

This commit is contained in:
icex2
2019-09-27 22:36:50 +02:00
commit cbd7720349
718 changed files with 62731 additions and 0 deletions
+30
View File
@@ -0,0 +1,30 @@
avsdlls += jbhook1
deplibs_jbhook1 := \
avs \
ldflags_jbhook1 := \
-lws2_32 \
-liphlpapi \
libs_jbhook1 := \
acioemu \
cconfig \
eamio \
jbio \
p3ioemu \
p3io \
hook \
hooklib \
security \
util \
src_jbhook1 := \
acio.c \
avs-boot.c \
config-gfx.c \
config-eamuse.c \
config-security.c \
dllmain.c \
log-gftools.c \
p3io.c \
+95
View File
@@ -0,0 +1,95 @@
#include <windows.h>
#include <ntdef.h>
#include <devioctl.h>
#include <ntddser.h>
#include <stdbool.h>
#include <stdint.h>
#include <string.h>
#include <wchar.h>
#include "acioemu/addr.h"
#include "acioemu/emu.h"
#include "acioemu/h44b.h"
#include "acioemu/icca.h"
#include "hook/iohook.h"
#include "jbhook/acio.h"
#include "imports/avs.h"
#include "util/defs.h"
#include "util/hex.h"
#include "util/iobuf.h"
#include "util/log.h"
#include "util/str.h"
static struct ac_io_emu ac_io_emu;
static struct ac_io_emu_icca ac_io_emu_icca;
static struct ac_io_emu_h44b ac_io_emu_h44b;
void ac_io_port_init(void)
{
ac_io_emu_init(&ac_io_emu, L"COM1");
ac_io_emu_icca_init(&ac_io_emu_icca, &ac_io_emu, 0);
ac_io_emu_h44b_init(&ac_io_emu_h44b, &ac_io_emu, 1);
}
void ac_io_port_fini(void)
{
ac_io_emu_fini(&ac_io_emu);
}
HRESULT ac_io_port_dispatch_irp(struct irp *irp)
{
const struct ac_io_message *msg;
HRESULT hr;
log_assert(irp != NULL);
if (!ac_io_emu_match_irp(&ac_io_emu, irp)) {
return irp_invoke_next(irp);
}
for (;;) {
hr = ac_io_emu_dispatch_irp(&ac_io_emu, irp);
if (hr != S_OK) {
return hr;
}
msg = ac_io_emu_request_peek(&ac_io_emu);
switch (msg->addr) {
case 0:
ac_io_emu_cmd_assign_addrs(&ac_io_emu, msg, 2);
break;
case 1:
ac_io_emu_icca_dispatch_request(&ac_io_emu_icca, msg);
break;
case 2:
ac_io_emu_h44b_dispatch_request(&ac_io_emu_h44b, msg);
break;
case AC_IO_BROADCAST:
log_warning("Broadcast(?) message on jubeat ACIO bus?");
break;
default:
log_warning("ACIO message on unhandled bus address: %d",
msg->addr);
break;
}
ac_io_emu_request_pop(&ac_io_emu);
}
}
+22
View File
@@ -0,0 +1,22 @@
#ifndef JBHOOK1_ACIO_H
#define JBHOOK1_ACIO_H
#include "hook/iohook.h"
/**
* Initialize the ACIO backend for jubeat.
*/
void ac_io_port_init(void);
/**
* Shutdown the ACIO backend.
*/
void ac_io_port_fini(void);
/**
* ACIO backend dispatch irp function. This needs to be hooked up to the iohook
* module in order to receive system calls to dispatch for emulation.
*/
HRESULT ac_io_port_dispatch_irp(struct irp *irp);
#endif
+157
View File
@@ -0,0 +1,157 @@
#define LOG_MODULE "avs-boot"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "hook/table.h"
#include "imports/avs.h"
#include "jbhook1/avs-boot.h"
#include "util/log.h"
static void (*real_avs_boot)(
struct property_node *config, void *std_heap, size_t sz_std_heap,
void *avs_heap, size_t sz_avs_heap, avs_log_writer_t log_writer,
void *log_context);
static int (*real_log_change_level)(int level);
static int (*real_ea3_boot)(struct property_node *config);
static void my_avs_boot(
struct property_node *config, void *std_heap, size_t sz_std_heap,
void *avs_heap, size_t sz_avs_heap, avs_log_writer_t log_writer,
void *log_context);
static int my_log_change_level(int level);
static int my_ea3_boot(struct property_node *config);
static struct net_addr jbhook1_avs_boot_eamuse_server_addr;
static const struct hook_symbol jbhook1_log_gftools_hook_syms[] = {
{
.name = "avs_boot",
.patch = my_avs_boot,
.link = (void **) &real_avs_boot
},
{
.name = "log_change_level",
.patch = my_log_change_level,
.link = (void **) &real_log_change_level
},
};
static const struct hook_symbol jbhook1_log_gftools_hook_syms2[] = {
{
.name = "ea3_boot",
.patch = my_ea3_boot,
.link = (void **) &real_ea3_boot
},
};
static void avs_boot_replace_property_uint32(struct property_node* node,
const char* name, uint32_t val)
{
struct property_node* tmp;
tmp = property_search(NULL, node, name);
if (tmp) {
property_node_remove(tmp);
}
property_node_create(NULL, node, PSMAP_TYPE_U32, name, val);
}
static void avs_boot_replace_property_str(struct property_node* node,
const char* name, const char* val)
{
struct property_node* tmp;
tmp = property_search(NULL, node, name);
if (tmp) {
property_node_remove(tmp);
}
tmp = property_node_create(NULL, node, PSMAP_TYPE_STR_LEGACY, name, val);
if (tmp) {
property_node_datasize(tmp);
}
}
static void my_avs_boot(
struct property_node *config, void *std_heap, size_t sz_std_heap,
void *avs_heap, size_t sz_avs_heap, avs_log_writer_t log_writer,
void *log_context)
{
log_info("Called my_avs_boot");
avs_boot_replace_property_uint32(config, "log/level", 4);
avs_boot_replace_property_str(config, "/config/fs/nvram/device",
"./CONF/NVRAM");
avs_boot_replace_property_str(config, "/config/fs/raw/device",
"./CONF/RAW");
real_avs_boot(config, std_heap, sz_std_heap, avs_heap, sz_avs_heap,
log_writer_debug, NULL);
}
static int my_ea3_boot(struct property_node *config)
{
char* server_addr;
log_info("Called my_ea3_boot");
if (jbhook1_avs_boot_eamuse_server_addr.type != NET_ADDR_TYPE_INVALID) {
log_misc("Injecting network server address");
server_addr = net_addr_to_str(&jbhook1_avs_boot_eamuse_server_addr);
avs_boot_replace_property_str(config, "network/services", server_addr);
free(server_addr);
}
return real_ea3_boot(config);
}
static int my_log_change_level(int level)
{
log_misc("Log change level: %d", level);
return real_log_change_level(level);
}
void jbhook1_avs_boot_init()
{
hook_table_apply(
NULL,
"libavs-win32.dll",
jbhook1_log_gftools_hook_syms,
lengthof(jbhook1_log_gftools_hook_syms));
hook_table_apply(
NULL,
"libavs-win32-ea3.dll",
jbhook1_log_gftools_hook_syms2,
lengthof(jbhook1_log_gftools_hook_syms2));
memset(&jbhook1_avs_boot_eamuse_server_addr, 0, sizeof(struct net_addr));
log_info("Inserted avs log hooks");
}
void jbhook1_avs_boot_set_eamuse_addr(const struct net_addr* server_addr)
{
char* str;
str = net_addr_to_str(server_addr);
log_info("Setting eamuse server: %s", str);
free(str);
memcpy(&jbhook1_avs_boot_eamuse_server_addr, server_addr,
sizeof(struct net_addr));
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef JBHOOK1_AVS_BOOT_H
#define JBHOOK1_AVS_BOOT_H
#include "util/net.h"
/**
* Initialize hooking of avs_boot and ea3_boot. This re-enables avs logging
* and injects a few important settings.
*/
void jbhook1_avs_boot_init();
/**
* Set the target eamuse server address.
*
* @param server_addr Address to target eamuse server.
*/
void jbhook1_avs_boot_set_eamuse_addr(const struct net_addr* server_addr);
#endif
+111
View File
@@ -0,0 +1,111 @@
#include <string.h>
#include "cconfig/cconfig-util.h"
#include "jbhook1/config-eamuse.h"
#include "util/log.h"
#include "util/net.h"
#define JBHOOK1_CONFIG_EAMUSE_SERVER_KEY "eamuse.server"
#define JBHOOK1_CONFIG_EAMUSE_PCBID_KEY "eamuse.pcbid"
#define JBHOOK1_CONFIG_EAMUSE_EAMID_KEY "eamuse.eamid"
#define JBHOOK1_CONFIG_EAMUSE_DEFAULT_SERVER_VALUE "localhost:80"
#define JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE security_id_default
#define JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE_LEN sizeof(security_id_default)
#define JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE security_id_default
#define JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE_LEN sizeof(security_id_default)
const struct net_addr jbhook1_eamuse_default_server = {
.type = NET_ADDR_TYPE_HOSTNAME,
.hostname.host = "localhost",
.hostname.port = 80,
};
void jbhook1_config_eamuse_init(struct cconfig* config)
{
cconfig_util_set_str(config,
JBHOOK1_CONFIG_EAMUSE_SERVER_KEY,
JBHOOK1_CONFIG_EAMUSE_DEFAULT_SERVER_VALUE,
"URL (e.g. http://my.eamuse.server:80/whatever) or IPV4 "
"(e.g. 127.0.0.1:80) of the target eamuse server. The port is optional "
"but defaults to 80.");
cconfig_util_set_data(config, JBHOOK1_CONFIG_EAMUSE_PCBID_KEY,
(uint8_t*) &JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE,
JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE_LEN, "PCBID");
cconfig_util_set_data(config, JBHOOK1_CONFIG_EAMUSE_EAMID_KEY,
(uint8_t*) &JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE,
JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE_LEN, "EAMID");
}
void jbhook1_config_eamuse_get(struct jbhook1_config_eamuse* config_eamuse,
struct cconfig* config)
{
char server_url[1024];
char* tmp;
char* tmp2;
memset(config_eamuse, 0, sizeof(struct jbhook1_config_eamuse));
if (!cconfig_util_get_str(config, JBHOOK1_CONFIG_EAMUSE_SERVER_KEY,
server_url, sizeof(server_url),
JBHOOK1_CONFIG_EAMUSE_DEFAULT_SERVER_VALUE)) {
log_warning("Invalid value for key '%s' specified, fallback "
"to default '%s'", JBHOOK1_CONFIG_EAMUSE_SERVER_KEY,
JBHOOK1_CONFIG_EAMUSE_DEFAULT_SERVER_VALUE);
}
if (!net_str_parse(server_url, &config_eamuse->server)) {
memcpy(&config_eamuse->server, &jbhook1_eamuse_default_server,
sizeof(config_eamuse->server));
tmp = net_addr_to_str(&config_eamuse->server);
log_warning("Invalid value for key '%s' specified, fallback "
"to default", tmp);
free(tmp);
}
if (!cconfig_util_get_data(config, JBHOOK1_CONFIG_EAMUSE_PCBID_KEY,
(uint8_t*) &config_eamuse->pcbid,
JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE_LEN,
(uint8_t*) &JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE)) {
tmp = security_id_to_str(&JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE,
false);
log_warning("Invalid value for key '%s' specified, fallback "
"to default", tmp);
free(tmp);
}
if (!security_id_verify(&config_eamuse->pcbid)) {
tmp = security_id_to_str(&JBHOOK1_CONFIG_EAMUSE_DEFAULT_PCBID_VALUE,
false);
tmp2 = security_id_to_str(&config_eamuse->pcbid, false);
log_warning("PCBID verification of '%s' failed, fallback to default "
"PCBID '%s'", tmp2, tmp);
free(tmp);
free(tmp2);
}
if (!cconfig_util_get_data(config, JBHOOK1_CONFIG_EAMUSE_EAMID_KEY,
(uint8_t*) &config_eamuse->eamid,
JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE_LEN,
(uint8_t*) &JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE)) {
tmp = security_id_to_str(&JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE,
false);
log_warning("Invalid value for key '%s' specified, fallback "
"to default", tmp);
free(tmp);
}
if (!security_id_verify(&config_eamuse->eamid)) {
tmp = security_id_to_str(&JBHOOK1_CONFIG_EAMUSE_DEFAULT_EAMID_VALUE,
false);
tmp2 = security_id_to_str(&config_eamuse->eamid, false);
log_warning("EAMID verification of '%s' failed, fallback to default "
"EAMID '%s'", tmp2, tmp);
free(tmp);
free(tmp2);
}
}
+36
View File
@@ -0,0 +1,36 @@
#ifndef JBHOOK1_CONFIG_EAMUSE_H
#define JBHOOK1_CONFIG_EAMUSE_H
#include "cconfig/cconfig.h"
#include "security/id.h"
#include "util/net.h"
/**
* Struct holding configuration values for eamuse related items.
*/
struct jbhook1_config_eamuse {
struct net_addr server;
struct security_id pcbid;
struct security_id eamid;
};
/**
* Initialize a cconfig structure with the basic structure and default values
* of this configuration.
*/
void jbhook1_config_eamuse_init(struct cconfig* config);
/**
* Read the module specific config struct values from the provided cconfig
* struct.
*
* @param config_eamuse Target module specific struct to read configuration
* values to.
* @param config cconfig struct holding the intermediate data to read from.
*/
void jbhook1_config_eamuse_get(struct jbhook1_config_eamuse* config_eamuse,
struct cconfig* config);
#endif
+31
View File
@@ -0,0 +1,31 @@
#include <string.h>
#include "cconfig/cconfig-util.h"
#include "jbhook1/config-gfx.h"
#include "util/log.h"
#define JBHOOK1_CONFIG_GFX_WINDOWED_KEY "gfx.windowed"
#define JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE false
void jbhook1_config_gfx_init(struct cconfig* config)
{
cconfig_util_set_bool(config,
JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE,
"Run the game windowed");
}
void jbhook1_config_gfx_get(struct jbhook1_config_gfx* config_gfx,
struct cconfig* config)
{
if (!cconfig_util_get_bool(config, JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
&config_gfx->windowed,
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE)) {
log_warning("Invalid value for key '%s' specified, fallback "
"to default '%d'", JBHOOK1_CONFIG_GFX_WINDOWED_KEY,
JBHOOK1_CONFIG_GFX_DEFAULT_WINDOWED_VALUE);
}
}
+30
View File
@@ -0,0 +1,30 @@
#ifndef JBHOOK1_CONFIG_GFX_H
#define JBHOOK1_CONFIG_GFX_H
#include "cconfig/cconfig.h"
/**
* Struct holding configuration values for GFX related items.
*/
struct jbhook1_config_gfx {
bool windowed;
};
/**
* Initialize a cconfig structure with the basic structure and default values
* of this configuration.
*/
void jbhook1_config_gfx_init(struct cconfig* config);
/**
* Read the module specific config struct values from the provided cconfig
* struct.
*
* @param config_gfx Target module specific struct to read configuration
* values to.
* @param config cconfig struct holding the intermediate data to read from.
*/
void jbhook1_config_gfx_get(struct jbhook1_config_gfx* config_gfx,
struct cconfig* config);
#endif
+66
View File
@@ -0,0 +1,66 @@
#include <string.h>
#include "cconfig/cconfig-util.h"
#include "jbhook1/config-security.h"
#include "security/mcode.h"
#include "util/log.h"
#include "util/net.h"
#define JBHOOK1_CONFIG_SECURITY_MCODE_KEY "security.mcode"
#define JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE jbhook1_config_security_default_mcode
static const struct security_mcode jbhook1_config_security_default_mcode = {
.header = SECURITY_MCODE_HEADER,
.unkn = SECURITY_MCODE_UNKN_C,
.game = SECURITY_MCODE_GAME_JB_1,
.region = SECURITY_MCODE_REGION_JAPAN,
.cabinet = SECURITY_MCODE_CABINET_A,
.revision = SECURITY_MCODE_REVISION_B,
};
void jbhook1_config_security_init(struct cconfig* config)
{
char* tmp;
tmp = security_mcode_to_str(&JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE);
cconfig_util_set_str(config,
JBHOOK1_CONFIG_SECURITY_MCODE_KEY,
tmp,
"Mcode of the game to run.");
free(tmp);
}
void jbhook1_config_security_get(
struct jbhook1_config_security* config_security, struct cconfig* config)
{
char* tmp_default;
char mcode[9];
tmp_default =
security_mcode_to_str(&JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE);
if (!cconfig_util_get_str(config, JBHOOK1_CONFIG_SECURITY_MCODE_KEY,
mcode, sizeof(mcode) - 1, tmp_default)) {
log_warning("Invalid value for key '%s' specified, fallback "
"to default '%s'", JBHOOK1_CONFIG_SECURITY_MCODE_KEY, tmp_default);
}
mcode[8] = '\0';
if (!security_mcode_parse(mcode, &config_security->mcode)) {
log_warning("Invalid mcode '%s' specified, fallback to default '%s'",
mcode, tmp_default);
memcpy(&config_security->mcode,
&JBHOOK1_CONFIG_SECURITY_DEFAULT_MCODE_VALUE,
sizeof(struct security_mcode));
}
free(tmp_default);
}
+35
View File
@@ -0,0 +1,35 @@
#ifndef JBHOOK1_CONFIG_SECURITY_H
#define JBHOOK1_CONFIG_SECURITY_H
#include "cconfig/cconfig.h"
#include "security/mcode.h"
#include "util/net.h"
/**
* Struct holding configuration values for security related items.
*/
struct jbhook1_config_security {
struct security_mcode mcode;
};
/**
* Initialize a cconfig structure with the basic structure and default values
* of this configuration.
*/
void jbhook1_config_security_init(struct cconfig* config);
/**
* Read the module specific config struct values from the provided cconfig
* struct.
*
* @param config_security Target module specific struct to read configuration
* values to.
* @param config cconfig struct holding the intermediate data to read from.
*/
void jbhook1_config_security_get(
struct jbhook1_config_security* config_security,
struct cconfig* config);
#endif
+175
View File
@@ -0,0 +1,175 @@
#include <windows.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include "bemanitools/eamio.h"
#include "bemanitools/jbio.h"
#include "cconfig/cconfig-hook.h"
#include "hook/table.h"
#include "hooklib/adapter.h"
#include "hooklib/acp.h"
#include "hooklib/rs232.h"
#include "jbhook1/avs-boot.h"
#include "jbhook1/acio.h"
#include "jbhook1/config-gfx.h"
#include "jbhook1/config-eamuse.h"
#include "jbhook1/config-security.h"
#include "jbhook1/log-gftools.h"
#include "jbhook1/p3io.h"
#include "p3ioemu/devmgr.h"
#include "p3ioemu/emu.h"
#include "util/defs.h"
#include "util/log.h"
#include "util/thread.h"
#define JBHOOK1_INFO_HEADER \
"jbhook1 for jubeat" \
", build " __DATE__ " " __TIME__ ", gitrev " STRINGIFY(GITREV)
#define JBHOOK1_CMD_USAGE \
"Usage: inject.exe jbhook1.dll <jubeat.exe> [options...]"
static const irp_handler_t jbhook1_handlers[] = {
p3io_emu_dispatch_irp,
ac_io_port_dispatch_irp,
};
static HWND CDECL my_mwindow_create(HINSTANCE, void*, const char*, DWORD,
DWORD, BOOL);
static HWND (CDECL *real_mwindow_create)(HINSTANCE, void*, const char*, DWORD,
DWORD, BOOL);
static const struct hook_symbol init_hook_syms[] = {
{
.name = "mwindow_create",
.patch = my_mwindow_create,
.link = (void **) &real_mwindow_create,
},
};
/**
* This seems to be a good entry point to intercept before the game calls
* anything important (very close to the start of WinMain).
*/
static HWND CDECL my_mwindow_create(HINSTANCE hinstance, void* callback,
const char* window_title, DWORD window_width, DWORD window_height,
BOOL fullscreen)
{
struct cconfig* config;
struct jbhook1_config_gfx config_gfx;
struct jbhook1_config_eamuse config_eamuse;
struct jbhook1_config_security config_security;
log_info("-------------------------------------------------------------");
log_info("---------------- Begin jbhook mwindow_create ----------------");
log_info("-------------------------------------------------------------");
config = cconfig_init();
jbhook1_config_gfx_init(config);
jbhook1_config_eamuse_init(config);
jbhook1_config_security_init(config);
if (!cconfig_hook_config_init(config, JBHOOK1_INFO_HEADER "\n" JBHOOK1_CMD_USAGE, CCONFIG_CMD_USAGE_OUT_DBG)) {
cconfig_finit(config);
exit(EXIT_FAILURE);
}
jbhook1_config_gfx_get(&config_gfx, config);
jbhook1_config_eamuse_get(&config_eamuse, config);
jbhook1_config_security_get(&config_security, config);
cconfig_finit(config);
log_info(JBHOOK1_INFO_HEADER);
log_info("Initializing jbhook...");
jbhook1_avs_boot_init();
jbhook1_avs_boot_set_eamuse_addr(&config_eamuse.server);
jbhook1_log_gftools_init();
fullscreen = !config_gfx.windowed;
log_info("Starting up jubeat IO backend");
jb_io_set_loggers(log_impl_misc, log_impl_info, log_impl_warning,
log_impl_fatal);
if (!jb_io_init(thread_create, thread_join, thread_destroy)) {
log_fatal("Initializing jb IO backend failed");
}
log_info("Starting up card reader backend");
eam_io_set_loggers(log_impl_misc, log_impl_info, log_impl_warning,
log_impl_fatal);
if (!eam_io_init(thread_create, thread_join, thread_destroy)) {
log_fatal("Initializing card reader backend failed");
}
iohook_init(jbhook1_handlers, lengthof(jbhook1_handlers));
rs232_hook_init();
ac_io_port_init();
p3io_setupapi_insert_hooks(NULL);
jbhook1_p3io_init(&config_security.mcode, &config_eamuse.pcbid,
&config_eamuse.eamid);
log_info("-------------------------------------------------------------");
log_info("----------------- End jbhook mwindow_create -----------------");
log_info("-------------------------------------------------------------");
return real_mwindow_create(hinstance, callback, window_title, window_width,
window_height, fullscreen);
}
/**
* Hook library for jubeat (1)
*/
BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
{
if (reason == DLL_PROCESS_ATTACH) {
#ifdef DEBUG_HOOKING
FILE* file = fopen("jbhook.dllmain.log", "w+");
log_to_writer(log_writer_file, file);
#else
log_to_writer(log_writer_null, NULL);
#endif
/* Bootstrap hook for further init tasks (see above) */
hook_table_apply(
NULL,
"mwindow.dll",
init_hook_syms,
lengthof(init_hook_syms));
/* Actual hooks for game specific stuff */
acp_hook_init();
adapter_hook_init();
#ifdef DEBUG_HOOKING
fflush(file);
fclose(file);
#endif
/* Logging to file and other destinations is handled by inject */
log_to_writer(log_writer_debug, NULL);
}
return TRUE;
}
+4
View File
@@ -0,0 +1,4 @@
LIBRARY jbhook1
EXPORTS
DllMain@12 @1 NONAME
+43
View File
@@ -0,0 +1,43 @@
#define LOG_MODULE "log-gftools"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include "hook/table.h"
#include "util/log.h"
static int CDECL my_GFReportPuts(int level, const char* source_file, int a3,
const char* func, const char* msg);
static int (CDECL *real_GFReportPuts)(int level, const char* source_file,
int a3, const char* func, const char* msg);
static const struct hook_symbol jbhook1_log_gftools_hook_syms[] = {
{
.name = "GFReportPuts",
.patch = my_GFReportPuts,
.link = (void **) &real_GFReportPuts
},
};
static int CDECL my_GFReportPuts(int level, const char* source_file, int a3,
const char* func, const char* msg)
{
log_misc("[%d][%s][%d][%s]: %s", level, source_file, a3, func, msg);
return real_GFReportPuts(level, source_file, a3, func, msg);
}
void jbhook1_log_gftools_init(void)
{
hook_table_apply(
NULL,
"gftools.dll",
jbhook1_log_gftools_hook_syms,
lengthof(jbhook1_log_gftools_hook_syms));
log_info("Inserted gftools log hooks");
}
+10
View File
@@ -0,0 +1,10 @@
#ifndef JBHOOK1_LOG_GFTOOLS_H
#define JBHOOK1_LOG_GFTOOLS_H
/**
* Initialize the gftools hook module. This hooks a function which is used
* to report errors and redirects the output to our logger.
*/
void jbhook1_log_gftools_init(void);
#endif
+163
View File
@@ -0,0 +1,163 @@
#include <windows.h>
#include <stdbool.h>
#include <stdint.h>
#include "bemanitools/jbio.h"
#include "jbhook1/p3io.h"
#include "p3ioemu/emu.h"
#include "p3ioemu/uart.h"
#include "security/rp3.h"
#include "security/rp-sign-key.h"
#include "util/log.h"
static HRESULT jbhook1_p3io_read_jamma(void *ctx, uint32_t *state);
static HRESULT jbhook1_p3io_get_roundplug(void *ctx, uint8_t plug_id,
uint8_t* rom, uint8_t* eeprom);
/*
0:0 b13
0:1 -
0:2 b15
0:3 -
0:4 test
0:5 coin
0:6 service
0:7 -
1:0 -
1:1 b4
1:2 b8
1:3 b12
1:4 b16
1:5 b3
1:6 b7
1:7 b11
2:0 -
2:1 b2
2:2 b6
2:3 b10
2:4 b14
2:5 b1
2:6 b5
2:7 b9
3:0 -
3:1 -
3:2 -
3:3 -
3:4 -
3:5 -
3:6 -
3:7 -
*/
static const uint32_t jbhook1_p3io_panel_mappings[] = {
(1 << 21),
(1 << 17),
(1 << 13),
(1 << 9),
(1 << 22),
(1 << 18),
(1 << 14),
(1 << 10),
(1 << 23),
(1 << 19),
(1 << 15),
(1 << 11),
(1 << 0),
(1 << 20),
(1 << 2),
(1 << 12),
};
static const uint32_t jbhook1_p3io_sys_button_mappings[] = {
(1 << 4),
(1 << 6),
(1 << 5),
};
static struct security_mcode jbhook1_p3io_mcode;
static struct security_id jbhook1_p3io_pcbid;
static struct security_id jbhook1_p3io_eamid;
static const struct p3io_ops p3io_ddr_ops = {
.read_jamma = jbhook1_p3io_read_jamma,
.get_roundplug = jbhook1_p3io_get_roundplug,
};
void jbhook1_p3io_init(const struct security_mcode* mcode,
const struct security_id* pcbid, const struct security_id* eamid)
{
memcpy(&jbhook1_p3io_mcode, mcode, sizeof(struct security_mcode));
memcpy(&jbhook1_p3io_pcbid, pcbid, sizeof(struct security_id));
memcpy(&jbhook1_p3io_eamid, eamid, sizeof(struct security_id));
p3io_emu_init(&p3io_ddr_ops, NULL);
}
void jbhook1_p3io_finit(void)
{
p3io_emu_fini();
}
static HRESULT jbhook1_p3io_read_jamma(void *ctx, uint32_t *state)
{
uint16_t panels;
uint8_t buttons;
log_assert(state != NULL);
/* lower three bytes low active, highest byte high active */
*state = 0;
if (!jb_io_read_inputs()) {
log_warning("Reading inputs from jbio failed");
return E_FAIL;
}
panels = jb_io_get_panel_inputs();
buttons = jb_io_get_sys_inputs();
for (uint8_t i = 0; i < 16; i++) {
if (panels & (1 << i)) {
*state |= jbhook1_p3io_panel_mappings[i];
}
}
for (uint8_t i = 0; i < 2; i++) {
if (buttons & (1 << i)) {
*state |= jbhook1_p3io_sys_button_mappings[i];
}
}
return S_OK;
}
static HRESULT jbhook1_p3io_get_roundplug(void *ctx, uint8_t plug_id,
uint8_t* rom, uint8_t* eeprom)
{
struct security_rp3_eeprom eeprom_out;
if (plug_id == 0) {
/* black */
memcpy(rom, jbhook1_p3io_pcbid.id, sizeof(jbhook1_p3io_pcbid.id));
security_rp3_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_BLACK, &security_rp_sign_key_black_gfdmv4,
&jbhook1_p3io_mcode, &jbhook1_p3io_pcbid, &eeprom_out);
} else {
/* white */
memcpy(rom, jbhook1_p3io_eamid.id, sizeof(jbhook1_p3io_eamid.id));
security_rp3_generate_signed_eeprom_data(
SECURITY_RP_UTIL_RP_TYPE_WHITE, &security_rp_sign_key_white_eamuse,
&security_mcode_eamuse, &jbhook1_p3io_eamid, &eeprom_out);
}
memcpy(eeprom, &eeprom_out, sizeof(struct security_rp3_eeprom));
return S_OK;
}
+26
View File
@@ -0,0 +1,26 @@
#ifndef JBHOOK1_P3IO_H
#define JBHOOK1_P3IO_H
#include <windows.h>
#include "hook/iohook.h"
#include "security/id.h"
#include "security/mcode.h"
/**
* Initialize the jbhook1 specific p3io emulation backend.
*
* @param mcode Mcode of the target game to run. Required for dongle emulation.
* @param pcbid PCBDID
* @param eamid EAMID
*/
void jbhook1_p3io_init(const struct security_mcode* mcode,
const struct security_id* pcbid, const struct security_id* eamid);
/**
* Shutdown the p3io emulation backend.
*/
void jbhook1_p3io_fini(void);
#endif