From 8b6cac384d054ef25ff18fada3a16b1a3714f178 Mon Sep 17 00:00:00 2001 From: shunf4 Date: Wed, 4 Mar 2020 01:56:31 +0800 Subject: [PATCH] fix: improved stability; update to 0.4.7 --- README.md | 8 +++- cygwin_build/test/a.sh | 2 +- cygwin_build/test/b.sh | 2 +- cygwin_build/test/d.sh | 4 +- include/version.h | 2 +- src/dll/hook_installer.c | 38 ++++++++++-------- src/exe/args_and_config.c | 6 +-- src/exe/main.c | 81 +++++++++++++++++++++++++++++++-------- 8 files changed, 97 insertions(+), 46 deletions(-) diff --git a/README.md b/README.md index 91c870a..748b505 100644 --- a/README.md +++ b/README.md @@ -136,12 +136,16 @@ programs). See "To-do and Known Issues". Perhaps solution based on # To-do and Known Issues +(Development will be suspended for some time) + +- [ ] Try to fix hang when executing `git clone https://` and + `git submodule update --init --recursive` +- [ ] Try to fix frequent failure of `proxychains bash` under Cygwin + (Or maybe we should focus on Win32 ? Cygwin is quite a mess) - [ ] Remote DNS resolving based on UDP associate - [ ] Hook `sendto()`, coping with applications which do TCP fast open - [X] ~~Dynamic selection of 32-bit DLL and 64-bit DLL~~ ~~Fixed in 0.4~~ Finally fixed in ~~0.4.3~~ ~~0.4.4~~ 0.4.5 -- [ ] Try to fix hang when executing `git clone https://` and - `git submodule update --init --recursive` - [X] ~~Resolve race condition in `StdWprintf()`~~ Fixed in 0.4.5 # Licensing diff --git a/cygwin_build/test/a.sh b/cygwin_build/test/a.sh index ab19d20..c554807 100644 --- a/cygwin_build/test/a.sh +++ b/cygwin_build/test/a.sh @@ -1,3 +1,3 @@ #!/bin/sh echo this is a -./b.sh +$(dirname $0)/b.sh diff --git a/cygwin_build/test/b.sh b/cygwin_build/test/b.sh index 1f98511..12b41bc 100644 --- a/cygwin_build/test/b.sh +++ b/cygwin_build/test/b.sh @@ -1,3 +1,3 @@ #!/bin/sh echo this is b -./c.sh & ./d.sh +$(dirname $0)/c.sh & $(dirname $0)/d.sh diff --git a/cygwin_build/test/d.sh b/cygwin_build/test/d.sh index 57d4828..79ba3ac 100644 --- a/cygwin_build/test/d.sh +++ b/cygwin_build/test/d.sh @@ -1,4 +1,4 @@ #!/bin/sh echo this is d -./e.sh -./f.sh +$(dirname $0)/e.sh +$(dirname $0)/f.sh diff --git a/include/version.h b/include/version.h index b781070..2ea52b8 100644 --- a/include/version.h +++ b/include/version.h @@ -23,5 +23,5 @@ #define PXCH_VERSION_MINOR 4 #endif #ifndef PXCH_VERSION_PATCH -#define PXCH_VERSION_PATCH 6 +#define PXCH_VERSION_PATCH 7 #endif \ No newline at end of file diff --git a/src/dll/hook_installer.c b/src/dll/hook_installer.c index 525eb1b..4aae564 100644 --- a/src/dll/hook_installer.c +++ b/src/dll/hook_installer.c @@ -50,10 +50,6 @@ void Win32HookWs2_32(void) LoadLibraryW(L"ws2_32.dll"); if ((hWs2_32 = GetModuleHandleW(L"ws2_32.dll"))) { - int iReturn; - SOCKET DummySocket; - WSADATA DummyWsaData; - // orig_fpWs2_32_WSAStartup = (void*)GetProcAddress(hWs2_32, "WSAStartup"); orig_fpWs2_32_WSAConnect = (void*)GetProcAddress(hWs2_32, "WSAConnect"); orig_fpWs2_32_connect = (void*)GetProcAddress(hWs2_32, "connect"); @@ -110,23 +106,31 @@ void Win32HookWs2_32(void) if (orig_fpWs2_32_FreeAddrInfoExW == NULL) orig_fpWs2_32_FreeAddrInfoExW = orig_fpWs2_32_FreeAddrInfoEx; // Hook ConnectEx() - iReturn = WSAStartup(MAKEWORD(2, 2), &DummyWsaData); - - if (iReturn == 0) { - GUID GuidConnectEx = WSAID_CONNECTEX; - LPFN_CONNECTEX fpConnectEx = NULL; - DWORD cb; - - DummySocket = socket(AF_INET, SOCK_STREAM, 0); - if (DummySocket != INVALID_SOCKET) { - if (WSAIoctl(DummySocket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GUID), &fpConnectEx, sizeof(LPFN_CONNECTEX), &cb, NULL, NULL) == 0) { - if (fpConnectEx) { - CREATE_HOOK3_IFNOTNULL(Mswsock, ConnectEx, fpConnectEx); +#ifndef __CYGWIN__ + { + int iReturn; + SOCKET DummySocket; + WSADATA DummyWsaData; + + iReturn = WSAStartup(MAKEWORD(2, 2), &DummyWsaData); + + if (iReturn == 0) { + GUID GuidConnectEx = WSAID_CONNECTEX; + LPFN_CONNECTEX fpConnectEx = NULL; + DWORD cb; + + DummySocket = socket(AF_INET, SOCK_STREAM, 0); + if (DummySocket != INVALID_SOCKET) { + if (WSAIoctl(DummySocket, SIO_GET_EXTENSION_FUNCTION_POINTER, &GuidConnectEx, sizeof(GUID), &fpConnectEx, sizeof(LPFN_CONNECTEX), &cb, NULL, NULL) == 0) { + if (fpConnectEx) { + CREATE_HOOK3_IFNOTNULL(Mswsock, ConnectEx, fpConnectEx); + } } + closesocket(DummySocket); } - closesocket(DummySocket); } } +#endif } } diff --git a/src/exe/args_and_config.c b/src/exe/args_and_config.c index 32f848f..6d5dd1b 100644 --- a/src/exe/args_and_config.c +++ b/src/exe/args_and_config.c @@ -1126,17 +1126,13 @@ DWORD LoadConfiguration(PROXYCHAINS_CONFIG** ppPxchConfig, PROXYCHAINS_CONFIG* p ASSIGN_NATIVE_FUNC_ADDR(pPxchConfig, GetLastError ); ASSIGN_NATIVE_FUNC_ADDR(pPxchConfig, OutputDebugStringA ); -#if defined(_M_X64) || defined(__x86_64__) +#if (defined(_M_X64) || defined(__x86_64__)) && !defined(__CYGWIN__) { FILE* fHelperProcOut; fHelperProcOut = popen(szHelperX86CommandLine, "rt"); if (fHelperProcOut == NULL) { -#ifndef __CYGWIN__ LOGW(L"Warning: X86 Helper executable " WPRS L" not found. In this case proxychains.exe will not inject X86 descendant processes.", szHelperX86CommandLine); -#else - LOGD(L"Warning: X86 Helper executable " WPRS L" not found. In this case proxychains.exe will not inject X86 descendant processes.", szHelperX86CommandLine); -#endif } else { unsigned long long tmp; int i; diff --git a/src/exe/main.c b/src/exe/main.c index dbaa328..5e41426 100644 --- a/src/exe/main.c +++ b/src/exe/main.c @@ -41,6 +41,55 @@ HANDLE g_hIpcServerSemaphore; DWORD HandleMessage(int i, PXCH_IPC_INSTANCE* pipc); +void StdVwprintf_NotImported(DWORD dwStdHandle, const WCHAR* fmt, va_list args) +{ + HANDLE h; + STRSAFE_LPWSTR pEnd = g_szFwprintfWbuf; + int iBufSize; + DWORD cbWritten; + + g_szFwprintfWbuf[0] = L'\0'; + g_szFwprintfBuf[0] = '\0'; + +#ifdef __CYGWIN__ + pEnd = g_szFwprintfWbuf + newlib_vswprintf(g_szFwprintfWbuf, PXCH_MAX_FWPRINTF_BUFSIZE, fmt, args); +#else + StringCchVPrintfExW(g_szFwprintfWbuf, PXCH_MAX_FWPRINTF_BUFSIZE, &pEnd, NULL, 0, fmt, args); +#endif + + if (pEnd < g_szFwprintfWbuf) pEnd = g_szFwprintfWbuf; + + if (g_szFwprintfWbuf[PXCH_MAX_FWPRINTF_BUFSIZE - 2]) g_szFwprintfWbuf[PXCH_MAX_FWPRINTF_BUFSIZE - 2] = L'\n'; + g_szFwprintfWbuf[PXCH_MAX_FWPRINTF_BUFSIZE - 1] = L'\0'; + iBufSize = WideCharToMultiByte(CP_ACP, 0, g_szFwprintfWbuf, (int)(pEnd - g_szFwprintfWbuf), g_szFwprintfBuf, PXCH_MAX_FWPRINTF_BUFSIZE, NULL, NULL); + g_szFwprintfBuf[PXCH_MAX_FWPRINTF_BUFSIZE - 1] = '\0'; + + h = GetStdHandle(dwStdHandle); + if (h && h != INVALID_HANDLE_VALUE) WriteFile(h, g_szFwprintfBuf, iBufSize, &cbWritten, NULL); +} + + +void StdWprintf_NotImported(DWORD dwStdHandle, const WCHAR* fmt, ...) +{ + va_list args; + va_start(args, fmt); + StdVwprintf_NotImported(dwStdHandle, fmt, args); + va_end(args); +} + + +void StdFlush_NotImported(DWORD dwStdHandle) +{ + HANDLE h; + + h = GetStdHandle(dwStdHandle); + if (h && h != INVALID_HANDLE_VALUE) FlushFileBuffers(h); +} + +#define StdVwprintf StdVwprintf_NotImported +#define StdWprintf StdWprintf_NotImported +#define StdFlush StdFlush_NotImported + DWORD ConnectToNewClient(HANDLE hPipe, LPOVERLAPPED lpo) { BOOL bConnected; @@ -159,13 +208,13 @@ DWORD WINAPI ServerLoop(LPVOID lpVoid) #else dwWait = WaitForMultipleObjects(PXCH_IPC_INSTANCE_NUM, hEvents, FALSE, 100); if (dwWait == WAIT_TIMEOUT) { - // BOOL bChild = FALSE; - // int iChildPid = 0; - // while ((iChildPid = waitpid((pid_t)(-1), 0, WNOHANG)) > 0) { bChild = TRUE; } - // if (bChild) { - // LOGI(L"Cygwin child process %d exited (between WaitForMultipleObjects()). Master exiting", iChildPid); - // IF_CYGWIN_EXIT(0); - // } + BOOL bChild = FALSE; + int iChildPid = 0; + while ((iChildPid = waitpid((pid_t)(-1), 0, WNOHANG)) > 0) { bChild = TRUE; break; } + if (bChild) { + LOGI(L"Cygwin child process %d exited (between WaitForMultipleObjects()). Master exiting", iChildPid); + IF_CYGWIN_EXIT(0); + } continue; } #endif @@ -571,14 +620,6 @@ int main(int argc, char* const argv[], char* const envp[]) const void* ctx[2]; setvbuf(stderr, NULL, _IOFBF, 65536); - // WriteFile() executed inside StdWprintf() in DLL won't work??? This is a workaround. - { - DWORD cbWritten; - WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "", 0, &cbWritten, NULL); - FlushFileBuffers(GetStdHandle(STD_OUTPUT_HANDLE)); - WriteFile(GetStdHandle(STD_ERROR_HANDLE), "", 0, &cbWritten, NULL); - FlushFileBuffers(GetStdHandle(STD_ERROR_HANDLE)); - } for (i = 0; i < argc; i++) { int iNeededChars = MultiByteToWideChar(CP_UTF8, 0, argv[i], -1, NULL, 0); @@ -589,6 +630,14 @@ int main(int argc, char* const argv[], char* const envp[]) setvbuf(stderr, NULL, _IOFBF, 65536); szLocale = setlocale(LC_ALL, ""); (void)szLocale; + // WriteFile() executed inside StdWprintf() in DLL won't work??? This is a (deprecated) workaround. + if (0) { + DWORD cbWritten; + WriteFile(GetStdHandle(STD_OUTPUT_HANDLE), "", 0, &cbWritten, NULL); + FlushFileBuffers(GetStdHandle(STD_OUTPUT_HANDLE)); + WriteFile(GetStdHandle(STD_ERROR_HANDLE), "", 0, &cbWritten, NULL); + FlushFileBuffers(GetStdHandle(STD_ERROR_HANDLE)); + } LOGD(L"Locale: " WPRS, szLocale); if ((dwError = Init()) != NOERROR) goto err; @@ -647,8 +696,6 @@ int main(int argc, char* const argv[], char* const envp[]) signal(SIGINT, handle_sigint); signal(SIGCHLD, handle_sigchld); - SetConsoleCtrlHandler(CtrlHandler, TRUE); - while(1) pause(); #ifdef __CYGWIN_PXCH_FORK__