diff --git a/dist/siva/start.bat b/dist/siva/start.bat index e69de29..ab52031 100644 --- a/dist/siva/start.bat +++ b/dist/siva/start.bat @@ -0,0 +1,9 @@ +@echo off + +pushd %~dp0 + +inject.exe -d -k sivahook.dll game.exe + +echo. +echo The game process has terminated +pause diff --git a/dist/siva/taitools.ini b/dist/siva/taitools.ini index e69de29..fe5e484 100644 --- a/dist/siva/taitools.ini +++ b/dist/siva/taitools.ini @@ -0,0 +1,5 @@ +[vfs] +d_drive=d_drive + +[netenv] +enable=1 diff --git a/hooklib/dns.c b/hooklib/dns.c index aac90ce..f4aef96 100644 --- a/hooklib/dns.c +++ b/hooklib/dns.c @@ -2,6 +2,7 @@ #include #include +#include #include #include @@ -13,6 +14,7 @@ #include "hook/table.h" #include "hooklib/dns.h" +#include "util/dprintf.h" /* Latest w32headers does not include DnsQueryEx, so we'll have to "polyfill" its associated data types here for the time being. @@ -66,6 +68,12 @@ static int WSAAPI hook_getaddrinfo( const ADDRINFOA *pHints, ADDRINFOA **ppResult); +static WINHTTPAPI BOOL hook_WinHttpCrackUrl( + LPCWSTR pwszUrl, + DWORD dwUrlLength, + DWORD dwFlags, + LPURL_COMPONENTS lpUrlComponents); + /* Link pointers */ static DNS_STATUS (WINAPI *next_DnsQuery_A)( @@ -95,6 +103,12 @@ static int (WSAAPI *next_getaddrinfo)( const ADDRINFOA *pHints, ADDRINFOA **ppResult); +static WINHTTPAPI BOOL (*next_WinHttpCrackUrl)( + LPCWSTR pwszUrl, + DWORD dwUrlLength, + DWORD dwFlags, + LPURL_COMPONENTS lpUrlComponents); + static const struct hook_symbol dns_hook_syms_dnsapi[] = { { .name = "DnsQuery_A", @@ -120,6 +134,14 @@ static const struct hook_symbol dns_hook_syms_ws2[] = { } }; +static const struct hook_symbol dns_hook_syms_winhttp[] = { + { + .name = "WinHttpCrackUrl", + .patch = hook_WinHttpCrackUrl, + .link = (void **) &next_WinHttpCrackUrl, + } +}; + static bool dns_hook_initted; static CRITICAL_SECTION dns_hook_lock; static struct dns_hook_entry *dns_hook_entries; @@ -131,17 +153,26 @@ static void dns_hook_init(void) return; } + dns_hook_apply_hooks(NULL); dns_hook_initted = true; InitializeCriticalSection(&dns_hook_lock); +} +void dns_hook_apply_hooks(HMODULE target) { hook_table_apply( - NULL, + target, "dnsapi.dll", dns_hook_syms_dnsapi, _countof(dns_hook_syms_dnsapi)); hook_table_apply( - NULL, + target, + "winhttp.dll", + dns_hook_syms_winhttp, + _countof(dns_hook_syms_winhttp)); + + hook_table_apply( + target, "ws2_32.dll", dns_hook_syms_ws2, _countof(dns_hook_syms_ws2)); @@ -460,3 +491,42 @@ end: return result; } + +static WINHTTPAPI BOOL hook_WinHttpCrackUrl( + LPCWSTR pwszUrl, + DWORD dwUrlLength, + DWORD dwFlags, + LPURL_COMPONENTS lpUrlComponents) +{ + size_t i; + const struct dns_hook_entry *pos; + wchar_t bfr[1024] = {0}; + if (!next_WinHttpCrackUrl(pwszUrl, dwUrlLength, dwFlags, lpUrlComponents)) { + return false; + } + + dprintf("DNS: crack URL %S\n", lpUrlComponents->lpszHostName); + + EnterCriticalSection(&dns_hook_lock); + + for (i = 0 ; i < dns_hook_nentries ; i++) { + pos = &dns_hook_entries[i]; + if (_wcsnicmp(lpUrlComponents->lpszHostName, pos->from, wcslen(pos->from)) == 0) { + wchar_t *path = wcsstr(lpUrlComponents->lpszHostName, L"/"); + + if (path == NULL){ + lpUrlComponents->lpszHostName = pos->to; + lpUrlComponents->dwHostNameLength = wcslen(pos->to); + } else { + wcscat_s(bfr, _countof(bfr), pos->to); + wcscat_s(bfr, _countof(bfr), path); + lpUrlComponents->lpszHostName = bfr; + lpUrlComponents->dwHostNameLength = wcslen(bfr); + } + break; + } + } + + LeaveCriticalSection(&dns_hook_lock); + return true; +} \ No newline at end of file diff --git a/hooklib/dns.h b/hooklib/dns.h index 1f93b0f..39b1bad 100644 --- a/hooklib/dns.h +++ b/hooklib/dns.h @@ -7,3 +7,4 @@ // 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); +void dns_hook_apply_hooks(HMODULE target); diff --git a/platform/cert.c b/platform/cert.c index 500bfcf..2d10967 100644 --- a/platform/cert.c +++ b/platform/cert.c @@ -82,25 +82,38 @@ PCCERT_CONTEXT WINAPI hook_CertFindCertificateInStore( PCCERT_CONTEXT pPrevCertContext ) { - uint8_t bfr[4096] = {0}; + char bfr[4096] = {0}; + uint8_t bfr_decode[4096] = {0}; + DWORD pcbBinary = 4096; wchar_t cert_path[MAX_PATH] = {0}; DWORD num_read = 0; + PCCERT_CONTEXT cert_ctx = NULL; if (dwFindType == CERT_FIND_ISSUER_STR || dwFindType == CERT_FIND_SUBJECT_STR) { wcscat_s(cert_path, _countof(cert_path), path); wcscat_s(cert_path, _countof(cert_path), L"/"); wcscat_s(cert_path, _countof(cert_path), (wchar_t *)pvFindPara); // use the search string as a name + wcscat_s(cert_path, _countof(cert_path), L".cer"); dprintf("Cert: Look for override cert at %S\n", cert_path); - HANDLE f = CreateFileW((LPCWSTR)pvFindPara, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + HANDLE f = CreateFileW((LPCWSTR)cert_path, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (f != INVALID_HANDLE_VALUE) { + dprintf("Cert: Read file %S\n", cert_path); ReadFile(f, bfr, sizeof(bfr), &num_read, NULL); CloseHandle(f); if (bfr[0]) { - return CertCreateCertificateContext(X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, bfr, num_read); + dprintf("Cert: Override %S\n", cert_path); + if (CryptStringToBinary(bfr, 0, CRYPT_STRING_BASE64X509CRLHEADER, bfr_decode, &pcbBinary, NULL, NULL)) { + cert_ctx = CertCreateCertificateContext(X509_ASN_ENCODING, bfr_decode, num_read); + if (cert_ctx != NULL) { + return cert_ctx; + } + dprintf("Cert: Override FAIL %08X\n", (int)GetLastError()); + } + dprintf("Cert: CryptStringToBinary FAIL %08X\n", (int)GetLastError()); } } } diff --git a/platform/netenv.c b/platform/netenv.c index 4515b6b..f05f6a3 100644 --- a/platform/netenv.c +++ b/platform/netenv.c @@ -154,15 +154,18 @@ HRESULT netenv_hook_init( netenv_ip_router = kc_cfg->subnet | cfg->router_suffix; memcpy(netenv_mac_addr, cfg->mac_addr, sizeof(netenv_mac_addr)); - hook_table_apply( - NULL, - "iphlpapi.dll", - netenv_hook_syms, - _countof(netenv_hook_syms)); - + netenv_hook_apply(NULL); return S_OK; } +void netenv_hook_apply(HMODULE target) { + hook_table_apply( + target, + "iphlpapi.dll", + netenv_hook_syms, + _countof(netenv_hook_syms)); +} + static uint32_t WINAPI hook_GetAdaptersAddresses( uint32_t Family, uint32_t Flags, diff --git a/platform/netenv.h b/platform/netenv.h index 33bf56a..82d1fd0 100644 --- a/platform/netenv.h +++ b/platform/netenv.h @@ -17,4 +17,4 @@ struct netenv_config { HRESULT netenv_hook_init( const struct netenv_config *cfg, const struct ttxsec_config *kc_cfg); - +void netenv_hook_apply(HMODULE target); diff --git a/sivahook/unity.c b/sivahook/unity.c index d2145e0..31a54f5 100644 --- a/sivahook/unity.c +++ b/sivahook/unity.c @@ -9,10 +9,12 @@ #include "hooklib/path.h" #include "hooklib/serial.h" #include "hooklib/createprocess.h" +#include "hooklib/dns.h" #include "hooklib/reg.h" #include "hook/procaddr.h" #include "platform/cert.h" +#include "platform/netenv.h" #include "util/dprintf.h" @@ -109,6 +111,8 @@ static HMODULE WINAPI my_LoadLibraryW(const wchar_t *name) proc_addr_insert_hooks(result); cert_hook_insert_hooks(result); createprocess_hook_insert_hook(result); + dns_hook_apply_hooks(result); + netenv_hook_apply(result); } for (size_t i = 0; i < dep_hooks_len; i++) {