mirror of
https://github.com/djhackersdev/bemanitools.git
synced 2026-08-08 03:13:57 -05:00
194 lines
5.8 KiB
C
194 lines
5.8 KiB
C
#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);
|
|
|
|
// when resolving URLs with net_str_parse
|
|
// it will default to NET_INVALID_PORT if no port is specified
|
|
// assume default 80 here as a good sanity check
|
|
if (eamuse_server_addr_resolved.ipv4.port == NET_INVALID_PORT) {
|
|
log_info("No port was specified, using port 80 as fallback");
|
|
eamuse_server_addr_resolved.ipv4.port = 80;
|
|
}
|
|
|
|
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.");
|
|
}
|
|
} |