Bemanitools v5.26 release
This commit is contained in:
@@ -0,0 +1,190 @@
|
||||
#define LOG_MODULE "eamuse-hook"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winsock2.h>
|
||||
#include <ws2tcpip.h>
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "iidxhook-util/eamuse.h"
|
||||
|
||||
#include "util/defs.h"
|
||||
#include "util/log.h"
|
||||
#include "util/str.h"
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
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);
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
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,
|
||||
.link = (void **) &real_connect
|
||||
},
|
||||
{
|
||||
.name = "gethostbyname",
|
||||
.ordinal = 52,
|
||||
.patch = my_gethostbyname,
|
||||
.link = (void **) &real_gethostbyname
|
||||
},
|
||||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static struct net_addr eamuse_server_addr;
|
||||
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)
|
||||
{
|
||||
char* tmp;
|
||||
|
||||
if (addr->sa_family == AF_INET) {
|
||||
/* check if we got our server's address */
|
||||
struct sockaddr_in* addr_in = (struct sockaddr_in*) addr;
|
||||
|
||||
if (addr_in->sin_addr.S_un.S_addr ==
|
||||
eamuse_server_addr_resolved.ipv4.addr) {
|
||||
tmp = net_addr_to_str(&eamuse_server_addr_resolved);
|
||||
log_misc("Patching port '%d' of %s to %d", ntohs(addr_in->sin_port),
|
||||
tmp, eamuse_server_addr_resolved.ipv4.port);
|
||||
free(tmp);
|
||||
|
||||
addr_in->sin_port = htons(eamuse_server_addr_resolved.ipv4.port);
|
||||
}
|
||||
}
|
||||
|
||||
return real_connect(s, addr, addrlen);
|
||||
}
|
||||
|
||||
static struct hostent FAR* STDCALL my_gethostbyname(const char* 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);
|
||||
|
||||
/* very ugly hack to get this working.
|
||||
don't bother with dynamic allocations and have stuff staticly alloc'd
|
||||
just populate what's touched by the game */
|
||||
static struct hostent ret;
|
||||
static uint32_t addr;
|
||||
static char* arr[2];
|
||||
static bool first = true;
|
||||
|
||||
if (first) {
|
||||
ret.h_length = 4;
|
||||
ret.h_addr_list = (char**) &arr;
|
||||
ret.h_addr_list[0] = (char*) &addr;
|
||||
ret.h_addr_list[1] = NULL;
|
||||
ret.h_aliases = NULL;
|
||||
ret.h_name = NULL;
|
||||
}
|
||||
|
||||
addr = eamuse_server_addr_resolved.ipv4.addr;
|
||||
|
||||
return &ret;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
void eamuse_hook_init(void)
|
||||
{
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"ws2_32.dll",
|
||||
eamuse_hook_syms,
|
||||
lengthof(eamuse_hook_syms));
|
||||
|
||||
log_info("Inserted eamuse hooks");
|
||||
}
|
||||
|
||||
void eamuse_set_addr(const struct net_addr* addr)
|
||||
{
|
||||
char* tmp_str;
|
||||
char* tmp_str2;
|
||||
|
||||
log_assert(addr);
|
||||
|
||||
memcpy(&eamuse_server_addr, addr, sizeof(struct net_addr));
|
||||
|
||||
tmp_str = net_addr_to_str(&eamuse_server_addr);
|
||||
|
||||
eamuse_server_addr_resolved.type = NET_ADDR_TYPE_IPV4;
|
||||
|
||||
if (!net_resolve_hostname_net_addr(&eamuse_server_addr,
|
||||
&eamuse_server_addr_resolved.ipv4)) {
|
||||
log_fatal("Failed to resolve eamuse server address: %s", tmp_str);
|
||||
free(tmp_str);
|
||||
return;
|
||||
}
|
||||
|
||||
tmp_str2 = net_addr_to_str(&eamuse_server_addr_resolved);
|
||||
|
||||
log_info("Target eamuse server %s resolved to %s", tmp_str, tmp_str2);
|
||||
|
||||
free(tmp_str);
|
||||
free(tmp_str2);
|
||||
}
|
||||
|
||||
void eamuse_check_connection()
|
||||
{
|
||||
if (!net_check_remote_connection(&eamuse_server_addr_resolved, 5000)) {
|
||||
log_info("Target eamuse server reachable.");
|
||||
} else {
|
||||
log_warning("Target eamuse server is not reachable. Game might throw "
|
||||
"network errors/warnings if eamuse is enabled.");
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user