dns: add port overriding support

pull/52/head
r0x5a 2024-12-12 02:28:02 +08:00
parent 6d8ffb46ef
commit d8202e1df4
7 changed files with 117 additions and 7 deletions

View File

@ -203,6 +203,24 @@ Default: `0`
Replace the HOST field in HTTP request headers with the settings above. This may help bypass network restrictions in some regions. Replace the HOST field in HTTP request headers with the settings above. This may help bypass network restrictions in some regions.
### `startupPort`
Default: `0` (i.e. no operation will perform)
Overrides the port of connections to the `startup` server. The current implementation affects every TCP connection to the port 80.
### `billingPort`
Default: `0` (i.e. no operation will perform)
Overrides the port of connections to the `billing` server. The current implementation affects every TCP connection to the port 8443.
### `aimedbPort`
Default: `0` (i.e. no operation will perform)
Overrides the port of connections to the `aimedb` server. The current implementation affects every TCP connection to the port 22345.
## `[ds]` ## `[ds]`
Controls emulation of the "DS (Dallas Semiconductor) EEPROM" chip on the AMEX Controls emulation of the "DS (Dallas Semiconductor) EEPROM" chip on the AMEX

View File

@ -88,6 +88,11 @@ static DWORD WINAPI hook_send(
int len, int len,
int flags); int flags);
static int WINAPI hook_connect(
SOCKET s,
const struct sockaddr *name,
int namelen);
/* Link pointers */ /* Link pointers */
static DNS_STATUS (WINAPI *next_DnsQuery_A)( static DNS_STATUS (WINAPI *next_DnsQuery_A)(
@ -135,6 +140,11 @@ static DWORD (WINAPI *next_send)(
int len, int len,
int flags); int flags);
static int (__stdcall *next_connect)(
SOCKET s,
const struct sockaddr *name,
int namelen);
static const struct hook_symbol dns_hook_syms_dnsapi[] = { static const struct hook_symbol dns_hook_syms_dnsapi[] = {
{ {
.name = "DnsQuery_A", .name = "DnsQuery_A",
@ -180,11 +190,22 @@ static struct hook_symbol http_hook_syms_ws2[] = {
}, },
}; };
static struct hook_symbol port_hook_syms_ws2[] = {
{
.name = "connect",
.patch = hook_connect,
.link = (void **) &next_connect
},
};
static bool dns_hook_initted; static bool dns_hook_initted;
static CRITICAL_SECTION dns_hook_lock; static CRITICAL_SECTION dns_hook_lock;
static struct dns_hook_entry *dns_hook_entries; static struct dns_hook_entry *dns_hook_entries;
static size_t dns_hook_nentries; static size_t dns_hook_nentries;
static char received_title_url[255]; static char received_title_url[255];
static unsigned short startup_port;
static unsigned short billing_port;
static unsigned short aimedb_port;
static void dns_hook_init(void) static void dns_hook_init(void)
{ {
@ -226,6 +247,21 @@ void http_hook_init(){
_countof(http_hook_syms_ws2)); _countof(http_hook_syms_ws2));
} }
void port_hook_init(unsigned short _startup_port, unsigned short _billing_port, unsigned short _aimedb_port){
startup_port = _startup_port;
billing_port = _billing_port;
aimedb_port = _aimedb_port;
for (size_t i = 0; i < _countof(port_hook_syms_ws2); ++i) {
port_hook_syms_ws2[i].ordinal = get_function_ordinal("ws2_32.dll", port_hook_syms_ws2[i].name);
}
hook_table_apply(
NULL,
"ws2_32.dll",
port_hook_syms_ws2,
_countof(port_hook_syms_ws2));
}
// This function match domain and subdomains like *.naominet.jp. // This function match domain and subdomains like *.naominet.jp.
bool match_domain(const wchar_t* target, const wchar_t* pattern) { bool match_domain(const wchar_t* target, const wchar_t* pattern) {
if (_wcsicmp(pattern, target) == 0) { if (_wcsicmp(pattern, target) == 0) {
@ -651,6 +687,49 @@ static bool WINAPI hook_WinHttpCrackUrl(
); );
} }
int WINAPI hook_connect(SOCKET s, const struct sockaddr *name, int namelen) {
const struct sockaddr_in *n;
struct sockaddr_in new_name;
unsigned ip;
unsigned short port, new_port;
EnterCriticalSection(&dns_hook_lock);
n = (const struct sockaddr_in *)name;
ip = n->sin_addr.S_un.S_addr;
if (WSANtohs(s, n->sin_port, &port)) return SOCKET_ERROR;
if (port == 80 && startup_port) {
new_port = startup_port;
} else if (port == 8443 && billing_port) {
new_port = billing_port;
} else if (port == 22345 && aimedb_port) {
new_port = aimedb_port;
} else { // No match
dprintf("TCP Connect: %u.%u.%u.%u:%hu\n", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff, port);
LeaveCriticalSection(&dns_hook_lock);
return next_connect(
s,
name,
namelen
);
}
// matched
new_name = *n;
if (WSAHtons(s, new_port, &new_name.sin_port)) return SOCKET_ERROR;
dprintf("TCP Connect: %u.%u.%u.%u:%hu, mapped to port %hu\n", ip & 0xff, (ip >> 8) & 0xff, (ip >> 16) & 0xff, (ip >> 24) & 0xff, port, new_port);
LeaveCriticalSection(&dns_hook_lock);
return next_connect(
s,
(const struct sockaddr *)&new_name,
sizeof(new_name)
);
}
DWORD WINAPI hook_send(SOCKET s, const char* buf, int len, int flags) { DWORD WINAPI hook_send(SOCKET s, const char* buf, int len, int flags) {
if (strstr(buf, "HTTP/") != NULL) { if (strstr(buf, "HTTP/") != NULL) {
char *new_buf = malloc(len + 1); char *new_buf = malloc(len + 1);

View File

@ -4,6 +4,7 @@
#include <stddef.h> #include <stddef.h>
void http_hook_init(); void http_hook_init();
void port_hook_init(unsigned short _startup_port, unsigned short _billing_port, unsigned short _aimedb_port);
// if to_src is NULL, all lookups for from_src will fail // if to_src is NULL, all lookups for from_src will fail
HRESULT dns_hook_push(const wchar_t *from_src, const wchar_t *to_src); HRESULT dns_hook_push(const wchar_t *from_src, const wchar_t *to_src);

View File

@ -34,6 +34,7 @@ if cc.get_id() != 'msvc'
'-static-libgcc', '-static-libgcc',
# '-ggdb', # Add debug information # '-ggdb', # Add debug information
'-lcrypt32', # Bcrypt needed for prashook '-lcrypt32', # Bcrypt needed for prashook
'-lws2_32', # WSAHtons / WSANtohs needed for porthook
# '-Wl,-s', # Strip debug symbols # '-Wl,-s', # Strip debug symbols
language: 'c', language: 'c',
) )

View File

@ -123,6 +123,10 @@ void dns_config_load(struct dns_config *cfg, const wchar_t *filename)
filename); filename);
cfg->replaceHost = GetPrivateProfileIntW(L"dns", L"replaceHost", 0, filename); cfg->replaceHost = GetPrivateProfileIntW(L"dns", L"replaceHost", 0, filename);
cfg->startupPort = GetPrivateProfileIntW(L"dns", L"startupPort", 0, filename);
cfg->billingPort = GetPrivateProfileIntW(L"dns", L"billingPort", 0, filename);
cfg->aimedbPort = GetPrivateProfileIntW(L"dns", L"aimedbPort", 0, 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)

View File

@ -20,6 +20,10 @@ HRESULT dns_platform_hook_init(const struct dns_config *cfg)
http_hook_init(); http_hook_init();
} }
if(cfg->startupPort || cfg->billingPort || cfg->aimedbPort){
port_hook_init(cfg->startupPort, cfg->billingPort, cfg->aimedbPort);
}
hr = dns_hook_push(L"tenporouter.loc", cfg->router); hr = dns_hook_push(L"tenporouter.loc", cfg->router);
if (FAILED(hr)) { if (FAILED(hr)) {

View File

@ -13,6 +13,9 @@ struct dns_config {
wchar_t aimedb[128]; wchar_t aimedb[128];
wchar_t title[128]; wchar_t title[128];
bool replaceHost; bool replaceHost;
unsigned short startupPort;
unsigned short billingPort;
unsigned short aimedbPort;
}; };
HRESULT dns_platform_hook_init(const struct dns_config *cfg); HRESULT dns_platform_hook_init(const struct dns_config *cfg);