forked from Dniel97/segatools
Modify host header in HTTP requests to bypass domain censorship in China.
This commit is contained in:
parent
c827b4c212
commit
97b8b373b5
@ -14,6 +14,7 @@
|
||||
#include "hook/table.h"
|
||||
|
||||
#include "util/dprintf.h"
|
||||
#include "util/get_function_ordinal.h"
|
||||
|
||||
#include "hooklib/dns.h"
|
||||
|
||||
@ -81,6 +82,12 @@ static bool WINAPI hook_WinHttpCrackUrl(
|
||||
DWORD dwFlags,
|
||||
LPURL_COMPONENTS lpUrlComponents);
|
||||
|
||||
static DWORD WINAPI hook_send(
|
||||
SOCKET s,
|
||||
const char* buf,
|
||||
int len,
|
||||
int flags);
|
||||
|
||||
/* Link pointers */
|
||||
|
||||
static DNS_STATUS (WINAPI *next_DnsQuery_A)(
|
||||
@ -122,6 +129,12 @@ static bool (WINAPI *next_WinHttpCrackUrl)(
|
||||
DWORD dwFlags,
|
||||
LPURL_COMPONENTS lpUrlComponents);
|
||||
|
||||
static DWORD (WINAPI *next_send)(
|
||||
SOCKET s,
|
||||
const char* buf,
|
||||
int len,
|
||||
int flags);
|
||||
|
||||
static const struct hook_symbol dns_hook_syms_dnsapi[] = {
|
||||
{
|
||||
.name = "DnsQuery_A",
|
||||
@ -138,13 +151,17 @@ static const struct hook_symbol dns_hook_syms_dnsapi[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct hook_symbol dns_hook_syms_ws2[] = {
|
||||
static struct hook_symbol dns_hook_syms_ws2[] = {
|
||||
{
|
||||
.name = "getaddrinfo",
|
||||
.ordinal = 176,
|
||||
.patch = hook_getaddrinfo,
|
||||
.link = (void **) &next_getaddrinfo,
|
||||
}
|
||||
}, {
|
||||
.name = "send",
|
||||
.patch = hook_send,
|
||||
.link = (void **) &next_send
|
||||
},
|
||||
};
|
||||
|
||||
static const struct hook_symbol dns_hook_syms_winhttp[] = {
|
||||
@ -175,6 +192,10 @@ static void dns_hook_init(void)
|
||||
dns_hook_initted = true;
|
||||
InitializeCriticalSection(&dns_hook_lock);
|
||||
|
||||
for (size_t i = 0; i < _countof(dns_hook_syms_ws2); ++i) {
|
||||
dns_hook_syms_ws2[i].ordinal = get_function_ordinal("ws2_32.dll", dns_hook_syms_ws2[i].name);
|
||||
}
|
||||
|
||||
hook_table_apply(
|
||||
NULL,
|
||||
"dnsapi.dll",
|
||||
@ -618,3 +639,49 @@ static bool WINAPI hook_WinHttpCrackUrl(
|
||||
lpUrlComponents
|
||||
);
|
||||
}
|
||||
|
||||
DWORD WINAPI hook_send(SOCKET s, const char* buf, int len, int flags) {
|
||||
if (strstr(buf, "HTTP/") != NULL) {
|
||||
char *new_buf = malloc(len + 1);
|
||||
if (new_buf == NULL) return SOCKET_ERROR;
|
||||
|
||||
memcpy(new_buf, buf, len);
|
||||
new_buf[len] = '\0';
|
||||
|
||||
char *host_start = strstr(new_buf, "Host: ");
|
||||
if (host_start != NULL) {
|
||||
char *host_end = strstr(host_start, "\r\n");
|
||||
if (host_end != NULL) {
|
||||
host_end += 2;
|
||||
int host_len = host_end - host_start;
|
||||
|
||||
char *host_value_start = host_start + 6;
|
||||
char *host_value_end = strstr(host_value_start, "\r\n");
|
||||
if (host_value_end != NULL) {
|
||||
int value_len = host_value_end - host_value_start;
|
||||
char host_value[value_len + 1];
|
||||
strncpy(host_value, host_value_start, value_len);
|
||||
host_value[value_len] = '\0';
|
||||
|
||||
for (struct dns_hook_entry *entry = dns_hook_entries; entry && entry->from; entry++) {
|
||||
char from_value[256];
|
||||
wcstombs(from_value, entry->from, sizeof(from_value));
|
||||
|
||||
if (strcmp(host_value, from_value) == 0) {
|
||||
char to_value[256];
|
||||
wcstombs(to_value, entry->to, sizeof(to_value));
|
||||
snprintf(host_start, len - (host_start - new_buf), "Host: %s\r\n", to_value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
len = (int)strlen(new_buf);
|
||||
}
|
||||
}
|
||||
DWORD result = next_send(s, new_buf, len, flags);
|
||||
free(new_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
return next_send(s, buf, len, flags);
|
||||
}
|
@ -81,6 +81,7 @@ dinput8_lib = cc.find_library('dinput8')
|
||||
dxguid_lib = cc.find_library('dxguid')
|
||||
xinput_lib = cc.find_library('xinput')
|
||||
pathcch_lib = cc.find_library('pathcch')
|
||||
imagehlp_lib = cc.find_library('imagehlp')
|
||||
|
||||
inc = include_directories('.')
|
||||
capnhook = subproject('capnhook')
|
||||
|
34
util/get_function_ordinal.c
Normal file
34
util/get_function_ordinal.c
Normal file
@ -0,0 +1,34 @@
|
||||
#include "get_function_ordinal.h"
|
||||
|
||||
DWORD get_function_ordinal(const char* dllName, const char* functionName) {
|
||||
HMODULE hModule = LoadLibraryA(dllName);
|
||||
if (!hModule) {
|
||||
dprintf("Failed to load DLL: %s\n", dllName);
|
||||
return 0;
|
||||
}
|
||||
|
||||
ULONG size;
|
||||
PIMAGE_EXPORT_DIRECTORY exportDir = (PIMAGE_EXPORT_DIRECTORY)ImageDirectoryEntryToData(
|
||||
hModule, TRUE, IMAGE_DIRECTORY_ENTRY_EXPORT, &size);
|
||||
if (!exportDir) {
|
||||
dprintf("Failed to get export table\n");
|
||||
FreeLibrary(hModule);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DWORD* functionNames = (DWORD*)((BYTE*)hModule + exportDir->AddressOfNames);
|
||||
WORD* ordinals = (WORD*)((BYTE*)hModule + exportDir->AddressOfNameOrdinals);
|
||||
|
||||
for (DWORD i = 0; i < exportDir->NumberOfNames; ++i) {
|
||||
char* name = (char*)((BYTE*)hModule + functionNames[i]);
|
||||
if (strcmp(name, functionName) == 0) {
|
||||
DWORD ordinal = ordinals[i] + exportDir->Base;
|
||||
FreeLibrary(hModule);
|
||||
return ordinal;
|
||||
}
|
||||
}
|
||||
|
||||
dprintf("Function not found: %s\n", functionName);
|
||||
FreeLibrary(hModule);
|
||||
return 0;
|
||||
}
|
6
util/get_function_ordinal.h
Normal file
6
util/get_function_ordinal.h
Normal file
@ -0,0 +1,6 @@
|
||||
#pragma once
|
||||
|
||||
#include <dbghelp.h>
|
||||
#include "dprintf.h"
|
||||
|
||||
DWORD get_function_ordinal(const char* dllName, const char* functionName);
|
@ -5,6 +5,7 @@ util_lib = static_library(
|
||||
c_pch : '../precompiled.h',
|
||||
dependencies : [
|
||||
capnhook.get_variable('hook_dep'),
|
||||
imagehlp_lib,
|
||||
],
|
||||
sources : [
|
||||
'async.c',
|
||||
@ -17,6 +18,8 @@ util_lib = static_library(
|
||||
'dprintf.h',
|
||||
'dump.c',
|
||||
'dump.h',
|
||||
'get_function_ordinal.c',
|
||||
'get_function_ordinal.h',
|
||||
'lib.c',
|
||||
'lib.h',
|
||||
'str.c',
|
||||
|
Loading…
Reference in New Issue
Block a user