From 0e47c921dd997adc8690c1e62964bacb66ef834c Mon Sep 17 00:00:00 2001 From: shunf4 Date: Sun, 14 Jun 2020 23:44:12 +0800 Subject: [PATCH] fix: imperfect name resolution hijack logic --- README.md | 13 +- README_zh-Hans.md | 2 +- include/defines_generic.h | 2 +- include/hookdll_util_win32.h | 2 +- include/version.h | 2 +- proxychains.conf | 3 +- src/dll/hook_connect_win32.c | 434 +++++++++++++++++++--------- src/dll/hook_createprocess_win32.c | 6 +- src/dll/ipc_client_and_child_data.c | 2 +- src/exe/args_and_config.c | 15 +- src/exe/ipc_proc_bookkeeping.c | 2 +- test/test.cpp | 6 +- 12 files changed, 328 insertions(+), 161 deletions(-) diff --git a/README.md b/README.md index 388f786..356e650 100644 --- a/README.md +++ b/README.md @@ -25,8 +25,7 @@ x64 SP1, Windows XP x86 SP3 and Cygwin 64-bit 3.1.2. Target OS should have [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/en-us/download/details.aspx?id=48145) installed. -**WARNING: DNS LEAK IS INEVITABLE IN CURRENT VERSION. DO NOT USE IF YOU -WANT ANONYMITY!** +**WARNING: ANONYMITY IS NOT GUARANTEED!** WARNING: this program works only on dynamically linked programs. Also both proxychains.exe and the program to call must be the same platform @@ -143,12 +142,18 @@ See [DevNotes](DEVNOTES.md). # To-do and Known Issues -- [ ] Add an option to totally prevent "DNS leak" ? (Do name lookup on -SOCKS5 server only) +[ConEmu](https://github.com/Maximus5/ConEmu) +[prevents](https://github.com/Maximus5/ConEmu/blob/9629fa82c8a4c817f3b6faa2161a0a9eec9285c4/src/ConEmuHk/hkProcess.cpp#L497) +its descendant processes to do `SetThreadContext()`. This means +proxychains.exe is in no way compatible with terminals based on ConEmu +(like cmder). + - [ ] Properly handle "fork-and-exit" child process ? (In this case the descendant processes' dns queries would never succeed) - [ ] Remote DNS resolving based on UDP associate - [ ] Hook `sendto()`, coping with applications which do TCP fast open +- [X] Add an option to totally prevent "DNS leak" ? (Do name lookup on +SOCKS5 server only) (fixed in 0.6.6) - [x] Connection closure should be correctly handled in `Ws2_32_LoopRecv` and `Ws2_32_LoopSend` (fixed in 0.6.5) - [x] A large part of socks5 server name possibly lost when parsing diff --git a/README_zh-Hans.md b/README_zh-Hans.md index f00bb69..ab5e61c 100644 --- a/README_zh-Hans.md +++ b/README_zh-Hans.md @@ -12,7 +12,7 @@ Proxychains.exe 是 [proxychains4](https://github.com/haad/proxychains) 或者 [ Proxychains.exe 在 Windows 10 x64 1909 (18363.418)、Windows 7 x64 SP1、Windows XP x86 SP3 和 Cygwin 64-bit 3.1.2 经过测试。注意目标操作系统需要安装 [Visual C++ Redistributable for Visual Studio 2015](https://www.microsoft.com/zh-cn/download/details.aspx?id=48145)。 -**警告:目前版本存在 DNS 泄露的问题。对匿名性有要求者目前请不要使用此工具!** +**警告:此工具不能保证匿名性!** 警告:此程序只对动态链接的程序有用。同时,Proxychains.exe 和需要运行的目标程序必须是同一架构和平台(用 proxychains_x86.exe 运行 x86 程序,用 proxychains_x64.exe 运行 x64 程序;用 Cygwin 下构建的版本来运行 Cygwin 程序)。 diff --git a/include/defines_generic.h b/include/defines_generic.h index d59df4e..d038e67 100644 --- a/include/defines_generic.h +++ b/include/defines_generic.h @@ -410,7 +410,7 @@ typedef struct _PROXYCHAINS_CONFIG { PXCH_UINT32 dwWillUseFakeIpWhenHostnameNotMatched; // usually exclusive with dwWillMapResolvedIpToHost PXCH_UINT32 dwWillMapResolvedIpToHost; PXCH_UINT32 dwWillLookupForHostByResolvedIp; - PXCH_UINT32 dwWillForceResolveByHostsFile; + PXCH_UINT32 dwWillResolveLocallyIfMatchHosts; PXCH_UINT32 dwWillGenFakeIpUsingHashedHostname; PXCH_UINT32 dwWillFirstTunnelUseIpv4; diff --git a/include/hookdll_util_win32.h b/include/hookdll_util_win32.h index a7295f6..eb8e643 100644 --- a/include/hookdll_util_win32.h +++ b/include/hookdll_util_win32.h @@ -27,7 +27,7 @@ PXCH_DLL_API void StdVwprintf(DWORD dwStdHandle, const WCHAR* fmt, va_list args) PXCH_DLL_API void StdFlush(DWORD dwStdHandle); DWORD IpcClientRegisterChildProcessAndBackupChildData(); -PXCH_UINT32 RestoreChildData(); +PXCH_UINT32 RestoreChildDataIfNecessary(); DWORD InjectTargetProcess(const PROCESS_INFORMATION* pPi, DWORD dwCreationFlags); diff --git a/include/version.h b/include/version.h index af7ef7a..9c9ef9d 100644 --- a/include/version.h +++ b/include/version.h @@ -23,5 +23,5 @@ #define PXCH_VERSION_MINOR 6 #endif #ifndef PXCH_VERSION_PATCH -#define PXCH_VERSION_PATCH 5 +#define PXCH_VERSION_PATCH 6 #endif \ No newline at end of file diff --git a/proxychains.conf b/proxychains.conf index 6b73c06..d2f538b 100644 --- a/proxychains.conf +++ b/proxychains.conf @@ -170,7 +170,8 @@ use_fake_ip_when_hostname_not_matched 1 map_resolved_ip_to_host 0 search_for_host_by_resolved_ip 0 -force_resolve_by_hosts_file 1 +# or force_resolve_by_hosts_file 1 +resolve_locally_if_match_hosts 1 # ===== Keep them as-is - end ===== diff --git a/src/dll/hook_connect_win32.c b/src/dll/hook_connect_win32.c index f054f48..1240418 100644 --- a/src/dll/hook_connect_win32.c +++ b/src/dll/hook_connect_win32.c @@ -123,7 +123,7 @@ static BOOL Ipv6MatchCidr(const struct sockaddr_in6* pIp, const struct sockaddr_ return memcmp(&MaskedIpv6, &MaskedCidr, sizeof(MaskedIpv6)) == 0; } -static PXCH_UINT32 GetTargetByRule(BOOL* pbMatchedHostnameRule, BOOL* pbMatchedIpRule, BOOL* pbMatchedPortRule, BOOL* pbMatchedFinalRule, const PXCH_HOST_PORT* pHostPort, PXCH_UINT32 dwDefault) +static PXCH_UINT32 GetTargetByRule(BOOL* pbHasMatchedHostnameRule, BOOL* pbMatchedIpRule, BOOL* pbMatchedPortRule, BOOL* pbMatchedFinalRule, const PXCH_HOST_PORT* pHostPort) { unsigned int i; PXCH_RULE* pRule; @@ -132,12 +132,12 @@ static PXCH_UINT32 GetTargetByRule(BOOL* pbMatchedHostnameRule, BOOL* pbMatchedI BOOL bDummyMatched3; BOOL bDummyMatched4; - if (pbMatchedHostnameRule == NULL) pbMatchedHostnameRule = &bDummyMatched1; + if (pbHasMatchedHostnameRule == NULL) pbHasMatchedHostnameRule = &bDummyMatched1; if (pbMatchedIpRule == NULL) pbMatchedIpRule = &bDummyMatched2; if (pbMatchedPortRule == NULL) pbMatchedPortRule = &bDummyMatched3; if (pbMatchedFinalRule == NULL) pbMatchedFinalRule = &bDummyMatched4; - *pbMatchedHostnameRule = FALSE; + *pbHasMatchedHostnameRule = FALSE; *pbMatchedIpRule = FALSE; *pbMatchedPortRule = FALSE; *pbMatchedFinalRule = FALSE; @@ -189,7 +189,7 @@ static PXCH_UINT32 GetTargetByRule(BOOL* pbMatchedHostnameRule, BOOL* pbMatchedI if (HostIsType(HOSTNAME, *pHostPort) && RuleIsType(DOMAIN, *pRule)) { if (StrCmpIW(pHostPort->HostnamePort.szValue, pRule->HostPort.HostnamePort.szValue) == 0) { // Match - *pbMatchedHostnameRule = TRUE; + *pbHasMatchedHostnameRule = TRUE; return pRule->dwTarget; } } @@ -203,7 +203,7 @@ static PXCH_UINT32 GetTargetByRule(BOOL* pbMatchedHostnameRule, BOOL* pbMatchedI if (cchRuleLength <= cchLength) { if (StrCmpIW(pHostPort->HostnamePort.szValue + (cchLength - cchRuleLength), pRule->HostPort.HostnamePort.szValue) == 0) { // Match - *pbMatchedHostnameRule = TRUE; + *pbHasMatchedHostnameRule = TRUE; return pRule->dwTarget; } } @@ -212,13 +212,13 @@ static PXCH_UINT32 GetTargetByRule(BOOL* pbMatchedHostnameRule, BOOL* pbMatchedI if (HostIsType(HOSTNAME, *pHostPort) && RuleIsType(DOMAIN_KEYWORD, *pRule)) { if (pRule->HostPort.HostnamePort.szValue[0] == L'\0' || StrStrIW(pHostPort->HostnamePort.szValue, pRule->HostPort.HostnamePort.szValue)) { // Match - *pbMatchedHostnameRule = TRUE; + *pbHasMatchedHostnameRule = TRUE; return pRule->dwTarget; } } } - return dwDefault; + return g_pPxchConfig->dwDefaultTarget; } PXCH_UINT32 ReverseLookupForHost(PXCH_HOSTNAME_PORT* pReverseLookedupHostnamePort, PXCH_IP_PORT* pReverseLookedupResolvedIpPort, const PXCH_IP_PORT** ppIpPortForDirectConnection, const PXCH_HOST_PORT** ppHostPortForProxiedConnection, PXCH_UINT32* pdwTarget, const PXCH_IP_PORT* pOriginalIpPort, int iOriginalAddrLen) @@ -271,20 +271,25 @@ PXCH_UINT32 ReverseLookupForHost(PXCH_HOSTNAME_PORT* pReverseLookedupHostnamePor break; } } - if (dw == dwRespIpNum) goto addr_not_supported_end; - *pReverseLookedupResolvedIpPort = RespIps[dw]; - pReverseLookedupResolvedIpPort->CommonHeader.wPort = pOriginalIpPort->CommonHeader.wPort; - *ppIpPortForDirectConnection = pReverseLookedupResolvedIpPort; + // if (dw == dwRespIpNum) goto addr_not_supported_end; + if (dw != dwRespIpNum) { + *pReverseLookedupResolvedIpPort = RespIps[dw]; + pReverseLookedupResolvedIpPort->CommonHeader.wPort = pOriginalIpPort->CommonHeader.wPort; + *ppIpPortForDirectConnection = pReverseLookedupResolvedIpPort; + } else { + ZeroMemory(pReverseLookedupResolvedIpPort, sizeof(PXCH_IP_PORT)); + *ppIpPortForDirectConnection = NULL; + } pReverseLookedupHostnamePort->wPort = pOriginalIpPort->CommonHeader.wPort; *ppHostPortForProxiedConnection = (const PXCH_HOST_PORT*)pReverseLookedupHostnamePort; // Case for entry not found if (pReverseLookedupHostnamePort->szValue[0] == L'\0') { - *pdwTarget = GetTargetByRule(NULL, NULL, NULL, NULL, (const PXCH_HOST_PORT*)*ppIpPortForDirectConnection, g_pPxchConfig->dwDefaultTarget); + *pdwTarget = GetTargetByRule(NULL, NULL, NULL, NULL, (const PXCH_HOST_PORT*)*ppIpPortForDirectConnection); } } else { - *pdwTarget = GetTargetByRule(NULL, NULL, NULL, NULL, (const PXCH_HOST_PORT*)pOriginalIpPort, g_pPxchConfig->dwDefaultTarget); + *pdwTarget = GetTargetByRule(NULL, NULL, NULL, NULL, (const PXCH_HOST_PORT*)pOriginalIpPort); } return NO_ERROR; @@ -888,7 +893,7 @@ PROXY_FUNC2(Ws2_32, connect) DWORD dw; - RestoreChildData(); + RestoreChildDataIfNecessary(); FUNCIPCLOGD(L"Ws2_32.dll connect(%d, %ls, %d) called", s, FormatHostPortToStr(name, namelen), namelen); @@ -992,7 +997,7 @@ PROXY_FUNC2(Mswsock, ConnectEx) DWORD dw; - RestoreChildData(); + RestoreChildDataIfNecessary(); FUNCIPCLOGD(L"Mswsock.dll (FP)ConnectEx(%d, %ls, %d) called", s, FormatHostPortToStr(name, namelen), namelen); @@ -1104,7 +1109,7 @@ PROXY_FUNC2(Ws2_32, WSAConnect) DWORD dw; - RestoreChildData(); + RestoreChildDataIfNecessary(); FUNCIPCLOGD(L"Ws2_32.dll WSAConnect(%d, %ls, %d) called", s, FormatHostPortToStr(name, namelen), namelen); @@ -1179,19 +1184,21 @@ PROXY_FUNC2(Ws2_32, WSAConnect) PROXY_FUNC2(Ws2_32, gethostbyname) { - struct hostent* orig_pHostent; - struct hostent* pReturnHostent; + struct hostent* pResolvedHostent = NULL; + struct hostent* pReturnHostent = NULL; + struct hostent* pNewHostentResult = NULL; int iWSALastError; DWORD dwLastError; ADDRINFOW RequeryAddrInfoHints; - ADDRINFOW* pRequeryAddrInfo; + ADDRINFOW* pRequeryAddrInfo = NULL; PXCH_HOSTNAME OriginalHostname; PXCH_HOSTNAME ResolvedHostname; - PXCH_UINT32 dwIpNum; + PXCH_IP_PORT IpPortResolvedByHosts; + PXCH_UINT32 dwIpNum = 0; PXCH_IP_ADDRESS Ips[PXCH_MAX_ARRAY_IP_NUM]; PXCH_UINT32 dwTarget; - BOOL bMatchedHostnameRule; + BOOL bHasMatchedHostnameRule; PXCH_IPC_MSGBUF chMessageBuf; PXCH_UINT32 cbMessageSize; @@ -1200,18 +1207,16 @@ PROXY_FUNC2(Ws2_32, gethostbyname) PXCH_IP_ADDRESS FakeIps[2]; PXCH_IP_ADDRESS* pFakeIps; - pRequeryAddrInfo = NULL; + BOOL bShouldReturnResolvedResult = FALSE; + BOOL bShouldUseResolvedResult = FALSE; + BOOL bShouldUseHostsResult = FALSE; + BOOL bShouldReturnHostsResult = FALSE; + BOOL bShouldReturnFakeIp = FALSE; + // Print DNS query FUNCIPCLOGD(L"Ws2_32.dll gethostbyname(" WPRS L") called", name); - orig_pHostent = orig_fpWs2_32_gethostbyname(name); - iWSALastError = WSAGetLastError(); - dwLastError = GetLastError(); - - if (name == NULL || name[0] == '\0' || orig_pHostent == NULL || orig_pHostent->h_length != sizeof(PXCH_UINT32)) goto orig; - - if (!g_pPxchConfig->dwWillUseFakeIpAsRemoteDns) goto orig; - + ZeroMemory(&IpPortResolvedByHosts, sizeof(IpPortResolvedByHosts)); ZeroMemory(&RequeryAddrInfoHints, sizeof(RequeryAddrInfoHints)); RequeryAddrInfoHints.ai_family = AF_UNSPEC; RequeryAddrInfoHints.ai_flags = AI_NUMERICHOST; @@ -1222,33 +1227,96 @@ PROXY_FUNC2(Ws2_32, gethostbyname) OriginalHostname.wPort = 0; OriginalHostname.wTag = PXCH_HOST_TYPE_HOSTNAME; StringCchPrintfW(OriginalHostname.szValue, _countof(OriginalHostname.szValue), L"%S", name); - HostentToHostnameAndIps(&ResolvedHostname, &dwIpNum, Ips, orig_pHostent); - if (dwIpNum == 0) goto orig; - if (orig_fpWs2_32_GetAddrInfoW(OriginalHostname.szValue, L"80", &RequeryAddrInfoHints, &pRequeryAddrInfo) != WSAHOST_NOT_FOUND) goto orig; + // Decide if we should use hosts entry + if (g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &OriginalHostname)) { + bShouldReturnHostsResult = TRUE; + bShouldUseHostsResult = TRUE; + } - if (pRequeryAddrInfo) orig_fpWs2_32_FreeAddrInfoW(pRequeryAddrInfo); + // Decide if we should use original result + if (!bShouldReturnHostsResult && !g_pPxchConfig->dwWillUseFakeIpAsRemoteDns) { + bShouldReturnResolvedResult = TRUE; + bShouldUseResolvedResult = TRUE; + } else if (!bShouldReturnHostsResult) { + ZeroMemory(&RequeryAddrInfoHints, sizeof(RequeryAddrInfoHints)); + RequeryAddrInfoHints.ai_family = AF_UNSPEC; + RequeryAddrInfoHints.ai_flags = AI_NUMERICHOST; + RequeryAddrInfoHints.ai_socktype = SOCK_STREAM; + RequeryAddrInfoHints.ai_protocol = IPPROTO_TCP; + + if (name == NULL + || name[0] == '\0' + || orig_fpWs2_32_GetAddrInfoW(OriginalHostname.szValue, L"80", &RequeryAddrInfoHints, &pRequeryAddrInfo) != WSAHOST_NOT_FOUND + ) { + FUNCIPCLOGD(L"conditons not satisfied; not hijacking name query"); + bShouldReturnResolvedResult = TRUE; + bShouldUseResolvedResult = TRUE; + } + } + + if (pRequeryAddrInfo) { + orig_fpWs2_32_FreeAddrInfoW(pRequeryAddrInfo); + pRequeryAddrInfo = NULL; + } + + if (!bShouldReturnHostsResult && !bShouldReturnResolvedResult) { + // Won't match port! + dwTarget = GetTargetByRule(&bHasMatchedHostnameRule, NULL, NULL, NULL, (PXCH_HOST_PORT*)&OriginalHostname); + bShouldReturnFakeIp = bHasMatchedHostnameRule || g_pPxchConfig->dwWillUseFakeIpWhenHostnameNotMatched; + bShouldReturnResolvedResult = !bShouldReturnFakeIp; + if (dwTarget == PXCH_RULE_TARGET_DIRECT) { + bShouldUseResolvedResult = TRUE; + } + } + + if (bShouldReturnResolvedResult) { + bShouldUseResolvedResult = TRUE; + } + + if (bShouldUseResolvedResult) { + if (!g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &OriginalHostname)) { + bShouldUseHostsResult = TRUE; + } + } + + if (bShouldUseResolvedResult && !bShouldUseHostsResult) { + pResolvedHostent = NULL; + pResolvedHostent = orig_fpWs2_32_gethostbyname(name); + iWSALastError = WSAGetLastError(); + dwLastError = GetLastError(); + + if (pResolvedHostent == NULL + || pResolvedHostent->h_length != sizeof(PXCH_UINT32) + ) { + bShouldReturnFakeIp = FALSE; + bShouldReturnResolvedResult = TRUE; + } + + HostentToHostnameAndIps(&ResolvedHostname, &dwIpNum, Ips, pResolvedHostent); + if (dwIpNum == 0) { + bShouldReturnFakeIp = FALSE; + bShouldReturnResolvedResult = TRUE; + } + } - if (g_pPxchConfig->dwWillForceResolveByHostsFile && ResolveByHostsFile(NULL, &OriginalHostname)) goto orig; + if (bShouldUseHostsResult) { + pResolvedHostent = NULL; - // Won't match port! - dwTarget = GetTargetByRule(&bMatchedHostnameRule, NULL, NULL, NULL, (PXCH_HOST_PORT*)&OriginalHostname, g_pPxchConfig->dwDefaultTarget); + HostnameAndIpsToHostent( + &pResolvedHostent, + (g_dwTlsIndex != TLS_OUT_OF_INDEXES) ? TlsGetValue(g_dwTlsIndex) : pHostentPseudoTls, + &OriginalHostname, + 1, + &IpPortResolvedByHosts + ); - if (bMatchedHostnameRule || g_pPxchConfig->dwWillUseFakeIpWhenHostnameNotMatched) { - struct hostent* pNewHostentResult; + iWSALastError = NO_ERROR; + dwLastError = NO_ERROR; + } + + if (bShouldReturnFakeIp) { int iIpFamilyAllowed; - // DWORD dw; - // BOOL bAnyResolvedIpv4 = FALSE; - // BOOL bAnyResolvedIpv6 = FALSE; - - // for (dw = 0; dw < dwIpNum; dw++) { - // if (Ips[dw].CommonHeader.wTag == PXCH_HOST_TYPE_IPV4) { - // bAnyResolvedIpv4 = TRUE; - // } - // if (Ips[dw].CommonHeader.wTag == PXCH_HOST_TYPE_IPV6) { - // bAnyResolvedIpv6 = TRUE; - // } - // } if ((dwLastError = HostnameAndIpsToMessage(chMessageBuf, &cbMessageSize, GetCurrentProcessId(), &OriginalHostname, g_pPxchConfig->dwWillMapResolvedIpToHost, dwIpNum, Ips, dwTarget)) != NO_ERROR) goto err; @@ -1259,30 +1327,33 @@ PROXY_FUNC2(Ws2_32, gethostbyname) iIpFamilyAllowed = 0; pFakeIps = FakeIps + 1; - if (g_pPxchConfig->dwWillFirstTunnelUseIpv4 /* && bAnyResolvedIpv4*/) { + if (g_pPxchConfig->dwWillFirstTunnelUseIpv4) { iIpFamilyAllowed++; pFakeIps--; } - if (g_pPxchConfig->dwWillFirstTunnelUseIpv6 /* && bAnyResolvedIpv6*/) { + if (g_pPxchConfig->dwWillFirstTunnelUseIpv6) { iIpFamilyAllowed++; } HostnameAndIpsToHostent(&pNewHostentResult, (g_dwTlsIndex != TLS_OUT_OF_INDEXES) ? TlsGetValue(g_dwTlsIndex) : pHostentPseudoTls, &OriginalHostname, iIpFamilyAllowed, pFakeIps); iWSALastError = NO_ERROR; dwLastError = NO_ERROR; - + pReturnHostent = pNewHostentResult; - } else { - pReturnHostent = orig_pHostent; } - WSASetLastError(iWSALastError); - SetLastError(dwLastError); - return pReturnHostent; + if (bShouldReturnResolvedResult) { + pReturnHostent = pResolvedHostent; + } + + if (bShouldReturnHostsResult) { + pReturnHostent = pResolvedHostent; + iWSALastError = NO_ERROR; + dwLastError = NO_ERROR; + } -orig: WSASetLastError(iWSALastError); SetLastError(dwLastError); - return orig_pHostent; + return pReturnHostent; err: WSASetLastError(iWSALastError); @@ -1397,7 +1468,7 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW) { const ADDRINFOW* pHintsCast; PADDRINFOW* ppResultCast = ppResult; - PADDRINFOW pOriginalResultCast; + PADDRINFOW pResolvedResultCast = NULL; int iReturn; DWORD dwLastError; int iWSALastError; @@ -1406,119 +1477,184 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW) PADDRINFOW pResultCast; PXCH_UINT32 dwTarget; - BOOL bMatchedHostnameRule; - - ADDRINFOW* pRequeryAddrInfo; + BOOL bHasMatchedHostnameRule; - // DWORD dw; + ADDRINFOW* pQueryPortAddrInfo = NULL; + ADDRINFOW* pRequeryAddrInfo = NULL; ADDRINFOW DefaultHints; WCHAR szAddrsBuf[1024]; + PXCH_IP_PORT IpPortResolvedByHosts; PXCH_HOST_PORT HostPort; PXCH_HOSTNAME Hostname; ADDRINFOW RequeryAddrInfoHints; + BOOL bShouldReturnResolvedResult = FALSE; + BOOL bShouldUseResolvedResult = FALSE; + BOOL bShouldUseHostsResult = FALSE; + BOOL bShouldReturnHostsResult = FALSE; + BOOL bShouldReturnFakeIp = FALSE; PXCH_IPC_MSGBUF chMessageBuf; PXCH_IPC_MSGBUF chRespMessageBuf; PXCH_IP_ADDRESS Ips[PXCH_MAX_ARRAY_IP_NUM]; PXCH_IP_PORT FakeIpPorts[2]; pHintsCast = pHints ? pHints : &DefaultHints; - pRequeryAddrInfo = NULL; + ZeroMemory(&IpPortResolvedByHosts, sizeof(IpPortResolvedByHosts)); ZeroMemory(&DefaultHints, sizeof(DefaultHints)); + // To distinguish case when pHints == NULL when printing DefaultHints.ai_family = -1; DefaultHints.ai_flags = -1; DefaultHints.ai_socktype = -1; DefaultHints.ai_protocol = -1; + // Print DNS query FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, AF%#010x, FL%#010x, ST%#010x, PT%#010x) called", pNodeName, pServiceName, pHintsCast->ai_family, pHintsCast->ai_flags, pHintsCast->ai_socktype, pHintsCast->ai_protocol); - *ppResultCast = pOriginalResultCast = NULL; - iReturn = orig_fpWs2_32_GetAddrInfoW(pNodeName, pServiceName, pHints, ppResultCast); + iReturn = orig_fpWs2_32_GetAddrInfoW(L"127.0.0.1", pServiceName, NULL, &pQueryPortAddrInfo); iWSALastError = WSAGetLastError(); dwLastError = GetLastError(); - pOriginalResultCast = *ppResultCast; - FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, AF%#010x, FL%#010x, ST%#010x, PT%#010x): orig_fpWs2_32_GetAddrInfoW ret: %d", pNodeName, pServiceName, pHintsCast->ai_family, pHintsCast->ai_flags, pHintsCast->ai_socktype, pHintsCast->ai_protocol, iReturn); + // Most probably WSATYPE_NOT_FOUND + if (iReturn != NO_ERROR || pQueryPortAddrInfo == NULL) goto err; - szAddrsBuf[0] = L'\0'; - pszAddrsBuf = szAddrsBuf; + ZeroMemory(&HostPort, sizeof(PXCH_HOST_PORT)); + SetHostType(HOSTNAME, HostPort); + HostPort.HostnamePort.wPort = ((PXCH_IP_PORT*)pQueryPortAddrInfo->ai_addr)->CommonHeader.wPort; + if (pQueryPortAddrInfo) { + orig_fpWs2_32_FreeAddrInfoW(pQueryPortAddrInfo); + pQueryPortAddrInfo = NULL; + } + StringCchCopyW(HostPort.HostnamePort.szValue, _countof(HostPort.HostnamePort.szValue), pNodeName); + + Hostname = HostPort.HostnamePort; + Hostname.wPort = 0; + + // Decide if we should use hosts entry + if (g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &Hostname)) { + bShouldReturnHostsResult = TRUE; + bShouldUseHostsResult = TRUE; + } - if (g_pPxchConfig->dwLogLevel >= PXCH_LOG_LEVEL_DEBUG) { - for (pResultCast = pOriginalResultCast; pResultCast; pResultCast = pResultCast->ai_next) { - StringCchPrintfExW(pszAddrsBuf, _countof(szAddrsBuf) - (pszAddrsBuf - szAddrsBuf), &pszAddrsBuf, NULL, 0, L"%ls%ls", pResultCast == pOriginalResultCast ? L"" : L", ", FormatHostPortToStr(pResultCast->ai_addr, (int)pResultCast->ai_addrlen)); + // Decide if we should use original result + if (!bShouldReturnHostsResult && !g_pPxchConfig->dwWillUseFakeIpAsRemoteDns) { + bShouldReturnResolvedResult = TRUE; + bShouldUseResolvedResult = TRUE; + } else if (!bShouldReturnHostsResult) { + DefaultHints.ai_family = AF_UNSPEC; + DefaultHints.ai_flags = 0; + DefaultHints.ai_socktype = SOCK_STREAM; + DefaultHints.ai_protocol = IPPROTO_TCP; + + ZeroMemory(&RequeryAddrInfoHints, sizeof(RequeryAddrInfoHints)); + RequeryAddrInfoHints.ai_family = AF_UNSPEC; + RequeryAddrInfoHints.ai_protocol = pHintsCast->ai_protocol; + RequeryAddrInfoHints.ai_socktype = pHintsCast->ai_socktype; + RequeryAddrInfoHints.ai_flags = AI_NUMERICHOST; + + // See if we should hijack this query(it needs to satisfy several conditions) + if (!( + pNodeName != NULL + && pNodeName[0] != L'\0' + && ( + pHintsCast->ai_family == AF_UNSPEC + || pHintsCast->ai_family == AF_INET + || pHintsCast->ai_family == AF_INET6) + && (pHintsCast->ai_protocol == IPPROTO_TCP + || pHintsCast->ai_protocol == IPPROTO_UDP + || pHintsCast->ai_protocol == 0) + && (pHintsCast->ai_socktype == SOCK_STREAM + || pHintsCast->ai_socktype == SOCK_DGRAM + || pHintsCast->ai_socktype == 0) + && ((pHintsCast->ai_flags & (AI_PASSIVE | AI_NUMERICHOST)) == 0) + && orig_fpWs2_32_GetAddrInfoW(pNodeName, pServiceName, &RequeryAddrInfoHints, &pRequeryAddrInfo) == WSAHOST_NOT_FOUND + )) { + FUNCIPCLOGD(L"conditons not satisfied; not hijacking name query"); + bShouldReturnResolvedResult = TRUE; + bShouldUseResolvedResult = TRUE; } - FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, ...) result %p: %ls", pNodeName, pServiceName, pOriginalResultCast, szAddrsBuf); } - if (!g_pPxchConfig->dwWillUseFakeIpAsRemoteDns) goto out; + if (pRequeryAddrInfo) { + orig_fpWs2_32_FreeAddrInfoW(pRequeryAddrInfo); + pRequeryAddrInfo = NULL; + } - DefaultHints.ai_family = AF_UNSPEC; - DefaultHints.ai_flags = 0; - DefaultHints.ai_socktype = SOCK_STREAM; - DefaultHints.ai_protocol = IPPROTO_TCP; + if (!bShouldReturnHostsResult && !bShouldReturnResolvedResult) { + dwTarget = GetTargetByRule(&bHasMatchedHostnameRule, NULL, NULL, NULL, &HostPort); + bShouldReturnFakeIp = bHasMatchedHostnameRule || g_pPxchConfig->dwWillUseFakeIpWhenHostnameNotMatched; + bShouldReturnResolvedResult = !bShouldReturnFakeIp; - ZeroMemory(&RequeryAddrInfoHints, sizeof(RequeryAddrInfoHints)); - RequeryAddrInfoHints.ai_family = AF_UNSPEC; - RequeryAddrInfoHints.ai_protocol = pHintsCast->ai_protocol; - RequeryAddrInfoHints.ai_socktype = pHintsCast->ai_socktype; - RequeryAddrInfoHints.ai_flags = AI_NUMERICHOST; + if (dwTarget == PXCH_RULE_TARGET_DIRECT) { + bShouldUseResolvedResult = TRUE; + } + } - if (!( - pNodeName != NULL - && pNodeName[0] != L'\0' - && ( - pHintsCast->ai_family == AF_UNSPEC - || pHintsCast->ai_family == AF_INET - || pHintsCast->ai_family == AF_INET6) - && (pHintsCast->ai_protocol == IPPROTO_TCP - || pHintsCast->ai_protocol == IPPROTO_UDP - || pHintsCast->ai_protocol == 0) - && (pHintsCast->ai_socktype == SOCK_STREAM - || pHintsCast->ai_socktype == SOCK_DGRAM - || pHintsCast->ai_socktype == 0) - && ((pHintsCast->ai_flags & (AI_PASSIVE | AI_NUMERICHOST)) == 0) - && orig_fpWs2_32_GetAddrInfoW(pNodeName, pServiceName, &RequeryAddrInfoHints, &pRequeryAddrInfo) == WSAHOST_NOT_FOUND - && pOriginalResultCast != NULL - )) { - FUNCIPCLOGD(L"goto out as-is"); - goto out; + if (bShouldReturnResolvedResult) { + bShouldUseResolvedResult = TRUE; } - if (pRequeryAddrInfo) orig_fpWs2_32_FreeAddrInfoW(pRequeryAddrInfo); + if (bShouldUseResolvedResult) { + if (!g_pPxchConfig->dwWillResolveLocallyIfMatchHosts && ResolveByHostsFile((PXCH_IP_ADDRESS*)&IpPortResolvedByHosts, &Hostname)) { + bShouldUseHostsResult = TRUE; + } + } - ZeroMemory(&HostPort, sizeof(PXCH_HOST_PORT)); - SetHostType(HOSTNAME, HostPort); - HostPort.HostnamePort.wPort = ((PXCH_IP_PORT*)pOriginalResultCast->ai_addr)->CommonHeader.wPort; - StringCchCopyW(HostPort.HostnamePort.szValue, _countof(HostPort.HostnamePort.szValue), pNodeName); + if (bShouldUseResolvedResult && !bShouldUseHostsResult) { + pResolvedResultCast = NULL; + + iReturn = orig_fpWs2_32_GetAddrInfoW(pNodeName, pServiceName, pHints, &pResolvedResultCast); + iWSALastError = WSAGetLastError(); + dwLastError = GetLastError(); - Hostname = HostPort.HostnamePort; - Hostname.wPort = 0; + FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, AF%#010x, FL%#010x, ST%#010x, PT%#010x): orig_fpWs2_32_GetAddrInfoW ret: %d", pNodeName, pServiceName, pHintsCast->ai_family, pHintsCast->ai_flags, pHintsCast->ai_socktype, pHintsCast->ai_protocol, iReturn); + + szAddrsBuf[0] = L'\0'; + pszAddrsBuf = szAddrsBuf; + + if (g_pPxchConfig->dwLogLevel >= PXCH_LOG_LEVEL_DEBUG) { + for (pResultCast = pResolvedResultCast; pResultCast; pResultCast = pResultCast->ai_next) { + StringCchPrintfExW(pszAddrsBuf, _countof(szAddrsBuf) - (pszAddrsBuf - szAddrsBuf), &pszAddrsBuf, NULL, 0, L"%ls%ls", pResultCast == pResolvedResultCast ? L"" : L", ", FormatHostPortToStr(pResultCast->ai_addr, (int)pResultCast->ai_addrlen)); + } + FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, ...) result %p: %ls", pNodeName, pServiceName, pResolvedResultCast, szAddrsBuf); + } - if (g_pPxchConfig->dwWillForceResolveByHostsFile && ResolveByHostsFile(NULL, &Hostname)) goto out; + if (pResolvedResultCast == NULL) { + bShouldReturnFakeIp = FALSE; + bShouldReturnResolvedResult = TRUE; + } + } - dwTarget = GetTargetByRule(&bMatchedHostnameRule, NULL, NULL, NULL, &HostPort, g_pPxchConfig->dwDefaultTarget); + if (bShouldUseHostsResult) { + pResolvedResultCast = NULL; + IpPortResolvedByHosts.CommonHeader.wPort = HostPort.CommonHeader.wPort; + + HostnameAndIpPortsToAddrInfo_WillAllocate( + &pResolvedResultCast, + &Hostname, + 1, + &IpPortResolvedByHosts, + !!(pHintsCast->ai_flags & AI_CANONNAME), + pHintsCast->ai_socktype, + pHintsCast->ai_protocol + ); + + FUNCIPCLOGD(L"Ws2_32.dll GetAddrInfoW(%ls, %ls, AF%#010x, FL%#010x, ST%#010x, PT%#010x): resolved by hosts: %ls", pNodeName, pServiceName, pHintsCast->ai_family, pHintsCast->ai_flags, pHintsCast->ai_socktype, pHintsCast->ai_protocol, FormatHostPortToStr(&IpPortResolvedByHosts, sizeof(IpPortResolvedByHosts))); - if (bMatchedHostnameRule || g_pPxchConfig->dwWillUseFakeIpWhenHostnameNotMatched) { + iWSALastError = NO_ERROR; + dwLastError = NO_ERROR; + iReturn = 0; + } + + if (bShouldReturnFakeIp) { PXCH_UINT32 cbMessageSize; PXCH_UINT32 cbRespMessageSize; PXCH_UINT32 dwIpNum; ADDRINFOW* pNewAddrInfoWResult; int iIpFamilyAllowed; PXCH_IP_PORT* pFakeIpPorts; - // BOOL bAnyResolvedIpv4 = FALSE; - // BOOL bAnyResolvedIpv6 = FALSE; - - AddrInfoToIps(&dwIpNum, Ips, pOriginalResultCast, TRUE); - // for (dw = 0; dw < dwIpNum; dw++) { - // if (Ips[dw].CommonHeader.wTag == PXCH_HOST_TYPE_IPV4) { - // bAnyResolvedIpv4 = TRUE; - // } - // if (Ips[dw].CommonHeader.wTag == PXCH_HOST_TYPE_IPV6) { - // bAnyResolvedIpv6 = TRUE; - // } - // } + AddrInfoToIps(&dwIpNum, Ips, pResolvedResultCast, TRUE); if ((dwLastError = HostnameAndIpsToMessage(chMessageBuf, &cbMessageSize, GetCurrentProcessId(), &Hostname, g_pPxchConfig->dwWillMapResolvedIpToHost, dwIpNum, Ips, dwTarget)) != NO_ERROR) goto err; @@ -1532,33 +1668,57 @@ PROXY_FUNC2(Ws2_32, GetAddrInfoW) iIpFamilyAllowed = 0; pFakeIpPorts = FakeIpPorts + 1; - if (g_pPxchConfig->dwWillFirstTunnelUseIpv4 /* && bAnyResolvedIpv4*/) { + if (g_pPxchConfig->dwWillFirstTunnelUseIpv4) { iIpFamilyAllowed++; pFakeIpPorts--; } - if (g_pPxchConfig->dwWillFirstTunnelUseIpv6 /* && bAnyResolvedIpv6*/) { + if (g_pPxchConfig->dwWillFirstTunnelUseIpv6) { iIpFamilyAllowed++; } - HostnameAndIpPortsToAddrInfo_WillAllocate(&pNewAddrInfoWResult, &Hostname, iIpFamilyAllowed, pFakeIpPorts, !!(pHintsCast->ai_flags & AI_CANONNAME), pOriginalResultCast->ai_socktype, pOriginalResultCast->ai_protocol); - iWSALastError = NO_ERROR; - dwLastError = NO_ERROR; - iReturn = 0; + HostnameAndIpPortsToAddrInfo_WillAllocate( + &pNewAddrInfoWResult, + &Hostname, + iIpFamilyAllowed, + pFakeIpPorts, + !!(pHintsCast->ai_flags & AI_CANONNAME), + pResolvedResultCast ? pResolvedResultCast->ai_socktype : pHintsCast->ai_socktype, + pResolvedResultCast ? pResolvedResultCast->ai_protocol : pHintsCast->ai_protocol + ); *ppResultCast = pNewAddrInfoWResult; if (*ppResultCast == NULL) { dwLastError = ERROR_NOT_FOUND; goto err; } - if (pOriginalResultCast) orig_fpWs2_32_FreeAddrInfoW(pOriginalResultCast); + if (pResolvedResultCast) { + ProxyWs2_32_FreeAddrInfoW(pResolvedResultCast); + pResolvedResultCast = NULL; + } + + iWSALastError = NO_ERROR; + dwLastError = NO_ERROR; + iReturn = 0; + } + + if (bShouldReturnResolvedResult) { + *ppResultCast = pResolvedResultCast; + } + + if (bShouldReturnHostsResult) { + *ppResultCast = pResolvedResultCast; + iWSALastError = NO_ERROR; + dwLastError = NO_ERROR; + iReturn = 0; } -out: WSASetLastError(iWSALastError); SetLastError(dwLastError); return iReturn; err: - if (pOriginalResultCast) orig_fpWs2_32_FreeAddrInfoW(pOriginalResultCast); + if (pResolvedResultCast) orig_fpWs2_32_FreeAddrInfoW(pResolvedResultCast); + if (pQueryPortAddrInfo) orig_fpWs2_32_FreeAddrInfoW(pQueryPortAddrInfo); + if (pRequeryAddrInfo) orig_fpWs2_32_FreeAddrInfoW(pRequeryAddrInfo); WSASetLastError(WSAHOST_NOT_FOUND); SetLastError(dwLastError); return WSAHOST_NOT_FOUND; diff --git a/src/dll/hook_createprocess_win32.c b/src/dll/hook_createprocess_win32.c index fd6bb13..6bc73f1 100644 --- a/src/dll/hook_createprocess_win32.c +++ b/src/dll/hook_createprocess_win32.c @@ -37,7 +37,7 @@ BOOL bRet; g_bCurrentlyInWinapiCall = TRUE; // For cygwin: cygwin fork() will duplicate the data in child process, including pointer g_*. - RestoreChildData(); + RestoreChildDataIfNecessary(); IPCLOGD(L"(In CreateProcessA) g_pRemoteData->dwDebugDepth = " WPRDW, g_pRemoteData ? g_pRemoteData->dwDebugDepth : -1); @@ -96,7 +96,7 @@ PROXY_FUNC(CreateProcessW) g_bCurrentlyInWinapiCall = TRUE; // For cygwin: cygwin fork() will duplicate the data in child process, including pointer g_*. - RestoreChildData(); + RestoreChildDataIfNecessary(); IPCLOGD(L"(In CreateProcessW) g_pRemoteData->dwDebugDepth = " WPRDW, g_pRemoteData ? g_pRemoteData->dwDebugDepth : -1); @@ -155,7 +155,7 @@ PROXY_FUNC(CreateProcessAsUserW) g_bCurrentlyInWinapiCall = TRUE; // For cygwin: cygwin fork() will duplicate the data in child process, including pointer g_*. - RestoreChildData(); + RestoreChildDataIfNecessary(); IPCLOGD(L"(In CreateProcessAsUserW) g_pRemoteData->dwDebugDepth = " WPRDW, g_pRemoteData ? g_pRemoteData->dwDebugDepth : -1); diff --git a/src/dll/ipc_client_and_child_data.c b/src/dll/ipc_client_and_child_data.c index 2eb06b8..770980f 100644 --- a/src/dll/ipc_client_and_child_data.c +++ b/src/dll/ipc_client_and_child_data.c @@ -183,7 +183,7 @@ DWORD IpcClientRegisterChildProcessAndBackupChildData() } -PXCH_UINT32 RestoreChildData() +PXCH_UINT32 RestoreChildDataIfNecessary() { // Restore child process essential data overwritten by Cygwin fork(). diff --git a/src/exe/args_and_config.c b/src/exe/args_and_config.c index 2afdbac..35c6635 100644 --- a/src/exe/args_and_config.c +++ b/src/exe/args_and_config.c @@ -62,12 +62,12 @@ #define wcsncasecmp _wcsnicmp #endif -#define WSTR_EQUAL(str, strend, literal) ((wcsncmp(str, literal, _countof(literal) - 1) == 0) ? (strend == str + _countof(literal) - 1) : FALSE) -#define WSTR_EQUAL_I(str, strend, literal) ((wcsncasecmp(str, literal, _countof(literal) - 1) == 0) ? (strend == str + _countof(literal) - 1) : FALSE) +#define WSTR_EQUAL(str, strend, strLiteral) ((wcsncmp(str, strLiteral, _countof(strLiteral) - 1) == 0) ? (strend == str + _countof(strLiteral) - 1) : FALSE) +#define WSTR_EQUAL_I(str, strend, strLiteral) ((wcsncasecmp(str, strLiteral, _countof(strLiteral) - 1) == 0) ? (strend == str + _countof(strLiteral) - 1) : FALSE) static const WCHAR* pszParseErrorMessage; -// stdlib_config_reader.c +// impl: stdlib_config_reader.c PXCH_UINT32 OpenConfigurationFile(PROXYCHAINS_CONFIG* pPxchConfig); PXCH_UINT32 OpenHostsFile(const WCHAR* szHostsFilePath); PXCH_UINT32 ConfigurationFileReadLine(unsigned long long* pullLineNum, wchar_t* chBuf, size_t cbBufSize); @@ -485,7 +485,7 @@ void PrintConfiguration(PROXYCHAINS_CONFIG* pPxchConfig) LOGD(L"WillUseFakeIpWhenHostnameNotMatched: " WPRDW, pPxchConfig->dwWillUseFakeIpWhenHostnameNotMatched); LOGD(L"WillMapResolvedIpToHost: " WPRDW, pPxchConfig->dwWillMapResolvedIpToHost); LOGD(L"WillLookupForHostByResolvedIp: " WPRDW, pPxchConfig->dwWillLookupForHostByResolvedIp); - LOGD(L"WillForceResolveByHostsFile: " WPRDW, pPxchConfig->dwWillForceResolveByHostsFile); + LOGD(L"WillResolveLocallyIfMatchHosts: " WPRDW, pPxchConfig->dwWillResolveLocallyIfMatchHosts); LOGD(L"WillFirstTunnelUseIpv4: " WPRDW, pPxchConfig->dwWillFirstTunnelUseIpv4); LOGD(L"WillFirstTunnelUseIpv6: " WPRDW, pPxchConfig->dwWillFirstTunnelUseIpv6); LOGD(L"WillGenFakeIpUsingHashedHostname: " WPRDW, pPxchConfig->dwWillGenFakeIpUsingHashedHostname); @@ -649,7 +649,7 @@ DWORD LoadConfiguration(PROXYCHAINS_CONFIG** ppPxchConfig, PROXYCHAINS_CONFIG* p pPxchConfig->dwWillUseFakeIpWhenHostnameNotMatched = TRUE; pPxchConfig->dwWillMapResolvedIpToHost = FALSE; pPxchConfig->dwWillLookupForHostByResolvedIp = FALSE; - pPxchConfig->dwWillForceResolveByHostsFile = TRUE; + pPxchConfig->dwWillResolveLocallyIfMatchHosts = TRUE; pPxchConfig->dwWillUseUdpAssociateAsRemoteDns = FALSE; pPxchConfig->dwWillUseFakeIpAsRemoteDns = FALSE; pPxchConfig->dwWillGenFakeIpUsingHashedHostname = TRUE; @@ -765,9 +765,10 @@ DWORD LoadConfiguration(PROXYCHAINS_CONFIG** ppPxchConfig, PROXYCHAINS_CONFIG* p } else if (WSTR_EQUAL(sOption, sOptionNameEnd, L"search_for_host_by_resolved_ip")) { if (OptionGetNumberValueAfterOptionName(&lValue, sOptionNameEnd, NULL, 0, 1) == -1) goto err_invalid_config_with_msg; pPxchConfig->dwWillLookupForHostByResolvedIp = lValue; - } else if (WSTR_EQUAL(sOption, sOptionNameEnd, L"force_resolve_by_hosts_file")) { + } else if (WSTR_EQUAL(sOption, sOptionNameEnd, L"resolve_locally_if_match_hosts") + || WSTR_EQUAL(sOption, sOptionNameEnd, L"force_resolve_by_hosts_file")) { if (OptionGetNumberValueAfterOptionName(&lValue, sOptionNameEnd, NULL, 0, 1) == -1) goto err_invalid_config_with_msg; - pPxchConfig->dwWillForceResolveByHostsFile = lValue; + pPxchConfig->dwWillResolveLocallyIfMatchHosts = lValue; } else if (WSTR_EQUAL(sOption, sOptionNameEnd, L"first_tunnel_uses_ipv4")) { if (OptionGetNumberValueAfterOptionName(&lValue, sOptionNameEnd, NULL, 0, 1) == -1) goto err_invalid_config_with_msg; pPxchConfig->dwWillFirstTunnelUseIpv4 = lValue; diff --git a/src/exe/ipc_proc_bookkeeping.c b/src/exe/ipc_proc_bookkeeping.c index 05fe6c3..82db46d 100644 --- a/src/exe/ipc_proc_bookkeeping.c +++ b/src/exe/ipc_proc_bookkeeping.c @@ -492,7 +492,7 @@ DWORD GetMsgHostnameAndResolvedIpsFromMsgIp(PXCH_IPC_MSGBUF chMessageBuf, PXCH_U LOGI(L"NotRegisteredIp %ls, return it As-is", FormatHostPortToStr(PXCH_IPC_IP_ARR(pMsgIp), sizeof(PXCH_IP_ADDRESS))); PrintTablePerProcess(); - dwLastError = HostnameAndIpsToMessage(chMessageBuf, pcbMessageSize, pMsgIp->dwPid, &EmptyHostname, FALSE /*ignored*/, 1, &AsKey.Ip, PXCH_RULE_TARGET_DIRECT); + dwLastError = HostnameAndIpsToMessage(chMessageBuf, pcbMessageSize, pMsgIp->dwPid, &EmptyHostname, FALSE /*ignored*/, 1, &AsKey.Ip, PXCH_RULE_TARGET_DIRECT /*ignored*/); if (dwLastError != NO_ERROR) goto error; return NO_ERROR; diff --git a/test/test.cpp b/test/test.cpp index 61b91c5..c233d3a 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -49,9 +49,9 @@ void GetAndPrintAddrInfo(PCWSTR pNodeName, PCWSTR pServiceName, const ADDRINFOW* fwprintf(stderr, L"getaddrinfo failed: %d\n", iReturn); } - dwLen = _countof(szIpStrWBuf); i = 0; for (ADDRINFOW* pAddrInfoW = arrAddrResults; pAddrInfoW; pAddrInfoW = pAddrInfoW->ai_next, i++) { + dwLen = _countof(szIpStrWBuf); WSAAddressToStringW(pAddrInfoW->ai_addr, (DWORD)pAddrInfoW->ai_addrlen, NULL, szIpStrWBuf, &dwLen); wprintf(L"addrs[%d]\naddr: %ls\naddrlen: %u\ncanonname: %ls\nfamily: %d\nflags: %d\nprotocol: %d\nsocktype: %d\n\n", i, szIpStrWBuf, (unsigned)pAddrInfoW->ai_addrlen, pAddrInfoW->ai_canonname, pAddrInfoW->ai_family, pAddrInfoW->ai_flags, pAddrInfoW->ai_protocol, pAddrInfoW->ai_socktype); @@ -111,7 +111,7 @@ int main() wprintf(L"%S\n", szIpStrNarrowBuf2); } - if (0) + if (1) { // Test Hostent PrintHostent(gethostbyname("www.baidu.com")); @@ -122,7 +122,7 @@ int main() if (1) { // Test GetAddrInfo - GetAndPrintAddrInfo(L"ip.sb", L"80", NULL); + GetAndPrintAddrInfo(L"t.cn", L"443", NULL); GetAndPrintAddrInfo(L"openwrt.reserved", L"80", NULL); //GetAndPrintAddrInfo(L"registry.npmjs.org", L"80", NULL); }