Add ea3_boot hook for legacy IIDX #300

Merged
gar6a9e merged 3 commits from legacy-iidx-network into master 2024-03-25 16:16:47 +03:00
7 changed files with 212 additions and 40 deletions
+1 -1
View File
@@ -292,7 +292,7 @@ $(zipdir)/iidx-13.zip: \
$(V)zip -j $@ $^
$(zipdir)/iidx-14-to-17.zip: \
build/bin/avs2_0-32/iidxhook3.dll \
build/bin/avs2_803-32/iidxhook3.dll \
build/bin/indep-32/config.exe \
build/bin/indep-32/eamio.dll \
build/bin/indep-32/geninput.dll \
+5 -32
View File
@@ -18,12 +18,10 @@
/* ------------------------------------------------------------------------- */
static unsigned long STDCALL my_inet_addr(const char *cp);
static int STDCALL
my_connect(SOCKET s, const struct sockaddr *addr, int addrlen);
static struct hostent FAR *STDCALL my_gethostbyname(const char *nameB);
static unsigned long(STDCALL *real_inet_addr)(const char *cp);
static int(STDCALL *real_connect)(
SOCKET s, const struct sockaddr *addr, int addrlen);
static struct hostent FAR *(STDCALL *real_gethostbyname)(const char *nameB);
@@ -33,10 +31,6 @@ static const struct hook_symbol eamuse_hook_syms[] = {
/* WS2_32.DLL's SDK import lib generates ordinal imports, so these
ordinals are a frozen aspect of the Win32 ABI. */
{.name = "inet_addr",
.ordinal = 11,
.patch = my_inet_addr,
.link = (void **) &real_inet_addr},
{.name = "connect",
.ordinal = 4,
.patch = my_connect,
@@ -54,26 +48,6 @@ static struct net_addr eamuse_server_addr_resolved;
/* ------------------------------------------------------------------------- */
static unsigned long STDCALL my_inet_addr(const char *cp)
{
char *tmp;
/* for a stock machine connected to the eamuse router,
the game wants to connect to the standard domain
services.konami.eamuse.fun
depending on the router you got, it will be services.hostname.my.router
so we catch that and turn it into any ip we want */
/* bugfix win10: don't just catch services.konami... because
win10 is doing some weird stuff and this call also contains
various IP addresses. Always return the server address */
tmp = net_addr_to_str(&eamuse_server_addr_resolved);
log_misc("my_inet_addr: '%s' -> %s", cp, tmp);
free(tmp);
return eamuse_server_addr_resolved.ipv4.addr;
}
static int STDCALL
my_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
{
@@ -102,14 +76,13 @@ my_connect(SOCKET s, const struct sockaddr *addr, int addrlen)
static struct hostent FAR *STDCALL my_gethostbyname(const char *name)
{
// IIDX 9-13 use the `services` domain (not `services.eamuse.konami.fun`).
if (strcmp(name, "services") != 0) {
return real_gethostbyname(name);
}
char *tmp;
/* for doc, checkout the other detour of inetaddr above
this call is used starting GOLD (not used on pre GOLD) */
/* bugfix win10: don't just catch services.konami... because
win10 is doing some weird stuff and this call also contains
various IP addresses. Always return the server address */
tmp = net_addr_to_str(&eamuse_server_addr_resolved);
log_misc("my_gethostbyname: '%s' to ip %s", name, tmp);
free(tmp);
+1 -1
View File
@@ -5,7 +5,7 @@
/**
* Hook various calls resolving the service address to connect to
* the eamuse server for the old IIDX games (9th to Sirius)
* the eamuse server for the old IIDX games (9th to DistorteD)
*/
void eamuse_hook_init(void);
+4
View File
@@ -4,6 +4,9 @@ ldflags_iidxhook3 := \
-lws2_32 \
-liphlpapi \
deplibs_iidxhook3 := \
avs \
libs_iidxhook3 := \
iidxhook-util \
ezusb-emu \
@@ -22,4 +25,5 @@ libs_iidxhook3 := \
ezusb \
src_iidxhook3 := \
avs-boot.c \
dllmain.c \
+178
View File
@@ -0,0 +1,178 @@
#define LOG_MODULE "avs-boot"
#include <stdint.h>
#include <string.h>
#include "hook/table.h"
#include "imports/avs.h"
#include "iidxhook3/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_ea3_boot_avs)(struct property_node *config);
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_ea3_boot_avs(struct property_node *config);
static int my_ea3_boot(struct property_node *config);
static struct net_addr iidxhook3_avs_boot_eamuse_server_addr;
static const struct hook_symbol iidxhook3_avs_hook_syms[] = {
{.name = "avs_boot",
.patch = my_avs_boot,
.link = (void **) &real_avs_boot},
{.name = "ea3_boot",
.patch = my_ea3_boot_avs,
.link = (void **) &real_ea3_boot_avs},
};
static const struct hook_symbol iidxhook3_ea3_hook_syms[] = {
{.name = "ea3_boot",
.patch = my_ea3_boot,
.link = (void **) &real_ea3_boot},
};
icex2 commented 2024-03-19 20:43:25 +03:00 (Migrated from github.com)
Review

question: Why are there twoea3_boot functions?

question: Why are there two`ea3_boot` functions?
gar6a9e commented 2024-03-19 22:09:40 +03:00 (Migrated from github.com)
Review

It's because the implementation of the ea3_boot function varies by game version.

https://github.com/gar6a9e/bemanitools/blob/legacy-iidx-network/src/main/iidxhook3/avs-boot.c#L148

It's because the implementation of the `ea3_boot` function varies by game version. https://github.com/gar6a9e/bemanitools/blob/legacy-iidx-network/src/main/iidxhook3/avs-boot.c#L148
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, PROPERTY_TYPE_STR, name, val);
if (tmp) {
property_node_datasize(tmp);
} else {
log_fatal("Could not avs_boot_replace_property_str(%s, %s)", name, val);
}
}
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);
icex2 commented 2024-03-19 20:40:00 +03:00 (Migrated from github.com)
Review

suggestion: Can you adjust the log level to align with what's configured for the hook? That would ensure that the log level can be controlled properly, i.e. to reduce output on normal/production operation.

suggestion: Can you adjust the log level to align with what's configured for the hook? That would ensure that the log level can be controlled properly, i.e. to reduce output on normal/production operation.
gar6a9e commented 2024-03-19 22:21:35 +03:00 (Migrated from github.com)
Review

What specific steps should be taken?
For example, making it configurable via conf file?

The reason for hardcoding the log level was to follow the existing implementation.

https://github.com/djhackersdev/bemanitools/blob/master/src/main/jbhook1/avs-boot.c#L118
https://github.com/djhackersdev/bemanitools/blob/master/src/main/iidxhook4-cn/avs-boot.c#L81

What specific steps should be taken? For example, making it configurable via conf file? The reason for hardcoding the log level was to follow the existing implementation. https://github.com/djhackersdev/bemanitools/blob/master/src/main/jbhook1/avs-boot.c#L118 https://github.com/djhackersdev/bemanitools/blob/master/src/main/iidxhook4-cn/avs-boot.c#L81
icex2 commented 2024-03-25 16:14:25 +03:00 (Migrated from github.com)
Review

I see, that's in general an issue that the current setup with logging does not allow for centralized log level management on the older games. I believe this requires more effort to be re-worked properly. Thus, I consider your approach valid and reasonable. Thanks for clarifying.

I see, that's in general an issue that the current setup with logging does not allow for centralized log level management on the older games. I believe this requires more effort to be re-worked properly. Thus, I consider your approach valid and reasonable. Thanks for clarifying.
real_avs_boot(
config,
std_heap,
sz_std_heap,
avs_heap,
sz_avs_heap,
log_writer_debug,
NULL);
}
static void insert_eamuse_addr(struct property_node *config)
{
char *server_addr;
if (iidxhook3_avs_boot_eamuse_server_addr.type != NET_ADDR_TYPE_INVALID) {
log_misc("Injecting network server address");
server_addr = net_addr_to_str(&iidxhook3_avs_boot_eamuse_server_addr);
// Remove protocol to avoid errors during ea3_boot.
if (!strncmp(server_addr, "http://", strlen("http://"))) {
server_addr += strlen("http://");
} else if (!strncmp(server_addr, "https://", strlen("https://"))) {
server_addr += strlen("https://");
}
avs_boot_replace_property_str(config, "network/services", server_addr);
free(server_addr);
}
}
static int my_ea3_boot_avs(struct property_node *config)
{
log_info("Called my_ea3_boot_avs");
insert_eamuse_addr(config);
icex2 commented 2024-03-19 20:42:39 +03:00 (Migrated from github.com)
Review

question: Why are you inserting the eamuse addr on avs boot? AVS should not have to deal with ea3 related stuff.

question: Why are you inserting the eamuse addr on avs boot? AVS should not have to deal with ea3 related stuff.
gar6a9e commented 2024-03-19 22:06:25 +03:00 (Migrated from github.com)
Review

It's because it was modeled after the implementation of popnhook.

https://github.com/djhackersdev/bemanitools/blob/master/src/main/popnhook1/avs-boot.c#L72

It's because it was modeled after the implementation of popnhook. https://github.com/djhackersdev/bemanitools/blob/master/src/main/popnhook1/avs-boot.c#L72
return real_ea3_boot_avs(config);
}
static int my_ea3_boot(struct property_node *config)
{
log_info("Called my_ea3_boot");
insert_eamuse_addr(config);
return real_ea3_boot(config);
}
void iidxhook3_avs_boot_init()
{
// IIDX 14 and 15 have the ea3_boot in libavs-win32.dll.
hook_table_apply(
NULL,
"libavs-win32.dll",
iidxhook3_avs_hook_syms,
lengthof(iidxhook3_avs_hook_syms));
hook_table_apply(
NULL,
"libavs-win32-ea3.dll",
iidxhook3_ea3_hook_syms,
lengthof(iidxhook3_ea3_hook_syms));
memset(&iidxhook3_avs_boot_eamuse_server_addr, 0, sizeof(struct net_addr));
log_info("Inserted avs log hooks");
}
void iidxhook3_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(
&iidxhook3_avs_boot_eamuse_server_addr,
server_addr,
sizeof(struct net_addr));
}
+19
View File
@@ -0,0 +1,19 @@
#ifndef IIDXHOOK3_AVS_BOOT_H
#define IIDXHOOK3_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 iidxhook3_avs_boot_init();
/**
* Set the target eamuse server address.
*
* @param server_addr Address to target eamuse server.
*/
void iidxhook3_avs_boot_set_eamuse_addr(const struct net_addr *server_addr);
#endif
+4 -6
View File
@@ -27,6 +27,8 @@
#include "hooklib/rs232.h"
#include "hooklib/setupapi.h"
#include "iidxhook3/avs-boot.h"
#include "iidxhook-util/acio.h"
#include "iidxhook-util/chart-patch.h"
#include "iidxhook-util/clock.h"
@@ -35,7 +37,6 @@
#include "iidxhook-util/config-misc.h"
#include "iidxhook-util/config-sec.h"
#include "iidxhook-util/d3d9.h"
#include "iidxhook-util/eamuse.h"
#include "iidxhook-util/settings.h"
#include "security/rp-sign-key.h"
@@ -176,10 +177,8 @@ my_OpenProcess(DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId)
ezusb_iidx_emu_node_security_plug_set_pcbid(&config_eamuse.pcbid);
ezusb_iidx_emu_node_security_plug_set_eamid(&config_eamuse.eamid);
/* eAmusement server IP */
eamuse_set_addr(&config_eamuse.server);
eamuse_check_connection();
iidxhook3_avs_boot_init();
iidxhook3_avs_boot_set_eamuse_addr(&config_eamuse.server);
/* Settings paths */
@@ -259,7 +258,6 @@ BOOL WINAPI DllMain(HMODULE mod, DWORD reason, void *ctx)
acp_hook_init();
adapter_hook_init();
eamuse_hook_init();
settings_hook_init();
}