diff --git a/Redirector/Based.cpp b/Redirector/Based.cpp new file mode 100644 index 00000000..fd5c433f --- /dev/null +++ b/Redirector/Based.cpp @@ -0,0 +1,15 @@ +#include "Based.h" + +BOOL filterLoopback = FALSE; +BOOL filterICMP = TRUE; +BOOL filterTCP = TRUE; +BOOL filterUDP = TRUE; +USHORT tcpPort = 0; +USHORT udpPort = 0; +vector handleList; +vector bypassList; + +mutex tcpLock; +mutex udpLock; +map tcpContext; +map udpContext; diff --git a/Redirector/Based.h b/Redirector/Based.h index 1be579dd..ab81e4e4 100644 --- a/Redirector/Based.h +++ b/Redirector/Based.h @@ -11,6 +11,7 @@ #include #include #include +#include #include #include @@ -20,4 +21,30 @@ #include using namespace std; + +typedef enum _AIO_TYPE { + AIO_FILTERLOOPBACK, + AIO_FILTERICMP, + AIO_FILTERTCP, + AIO_FILTERUDP, + + AIO_CLRNAME, + AIO_ADDNAME, + AIO_BYPNAME, + + AIO_TCPPORT, + AIO_UDPPORT +} AIO_TYPE; + +typedef struct _TCPINFO { + DWORD PID; + PBYTE Client[NF_MAX_ADDRESS_LENGTH]; + PBYTE Target[NF_MAX_ADDRESS_LENGTH]; +} TCPINFO, * PTCPINFO; + +typedef struct _UDPINFO { + DWORD PID; + SOCKET Socket; +} UDPINFO, * PUDPINFO; + #endif diff --git a/Redirector/DNSHandler.cpp b/Redirector/DNSHandler.cpp deleted file mode 100644 index bca337b4..00000000 --- a/Redirector/DNSHandler.cpp +++ /dev/null @@ -1,177 +0,0 @@ -#include "DNSHandler.h" - -#include "Utils.h" - -void dns_freePacket(PDNSPKT i) -{ - if (i) - { - if (i->Target) - { - delete[] i->Target; - } - - if (i->Buffer) - { - delete[] i->Buffer; - } - - if (i->Option) - { - delete i->Option; - } - - delete i; - } - - i = NULL; -} - -DNSHandler::DNSHandler(string dnsHost, USHORT dnsPort) -{ - this->dnsHost = dnsHost; - this->dnsPort = dnsPort; -} - -BOOL DNSHandler::init() -{ - this->Started = TRUE; - - WaitForSingleObject(this->dnsLock, INFINITE); - for (size_t i = 0; i < 4; i++) - { - this->dnsLoop[i] = thread(&DNSHandler::Thread, this); - } - ReleaseMutex(this->dnsLock); -} - -void DNSHandler::free() -{ - if (this->dnsLock) - { - WaitForSingleObject(this->dnsLock, INFINITE); - } - - this->Started = FALSE; - for (size_t i = 0; i < this->dnsLoop.size(); i++) - { - if (this->dnsLoop[i].joinable()) - { - this->dnsLoop[i].join(); - } - } - this->dnsLoop.clear(); - - auto size = this->dnsList.size(); - for (size_t i = 0; i < size; i++) - { - dns_freePacket(this->dnsList.front()); - } - - if (this->dnsLock) - { - CloseHandle(this->dnsLock); - this->dnsLock = NULL; - } -} - -void DNSHandler::Create(ENDPOINT_ID id, PBYTE target, ULONG targetLength, PCHAR buffer, ULONG bufferLength, PNF_UDP_OPTIONS option) -{ - if (!this->Started) - { - return; - } - - auto data = new DNSPKT(); - data->ID = id; - data->Target = new BYTE[targetLength](); - data->TargetLength = targetLength; - data->Buffer = new CHAR[bufferLength](); - data->BufferLength = bufferLength; - data->Option = new NF_UDP_OPTIONS(); - - memcpy(data->Target, target, targetLength); - memcpy(data->Buffer, buffer, bufferLength); - memcpy(data->Option, option, sizeof(NF_UDP_OPTIONS)); - - WaitForSingleObject(this->dnsLock, INFINITE); - this->dnsList.emplace(data); - ReleaseMutex(this->dnsLock); -} - -void DNSHandler::Thread() -{ - while (this->Started && this->dnsLock) - { - switch (WaitForSingleObject(this->dnsLock, 10)) - { - case WAIT_OBJECT_0: - this->Handle(); - break; - default: - continue; - } - } -} - -void DNSHandler::Handle() -{ - SOCKADDR_IN addr; - addr.sin_family = AF_INET; - addr.sin_port = htons(this->dnsPort); - if (!inet_pton(AF_INET, this->dnsHost.c_str(), &addr.sin_addr)) - { - ReleaseMutex(this->dnsLock); - return; - } - - auto data = this->dnsList.front(); - this->dnsList.pop(); - ReleaseMutex(this->dnsLock); - - auto client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); - if (!client) - { - dns_freePacket(data); - - printf("[Redirector][DNSHandler::Handle] Create socket failed: %d\n", WSAGetLastError()); - return; - } - - TIMEVAL tv; - tv.tv_sec = 4; - tv.tv_usec = 0; - - FD_SET fds; - FD_ZERO(&fds); - FD_SET(client, &fds); - - if (sendto(client, data->Buffer, data->BufferLength, 0, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN))) - { - if (select(0, &fds, 0, 0, &tv)) - { - CHAR buffer[1024]; - auto length = recvfrom(client, buffer, sizeof(buffer), 0, NULL, NULL); - - if (length) - { - nf_udpPostReceive(data->ID, data->Target, buffer, length, data->Option); - } - else - { - printf("[Redirector][DNSHandler::Handle] Receive failed: %d\n", WSAGetLastError()); - } - } - else - { - puts("[Redirector][DNSHandler::Handle] Receive timed out"); - } - } - else - { - printf("[Redirector][DNSHandler::Handle] Send failed: %d\n", WSAGetLastError()); - } - - closesocket(client); - dns_freePacket(data); -} diff --git a/Redirector/DNSHandler.h b/Redirector/DNSHandler.h deleted file mode 100644 index 0559faa7..00000000 --- a/Redirector/DNSHandler.h +++ /dev/null @@ -1,38 +0,0 @@ -#pragma once -#ifndef DNSHANDLER_H -#define DNSHANDLER_H -#include "Based.h" - -typedef struct _DNSPKT { - ENDPOINT_ID ID; - PBYTE Target; - ULONG TargetLength; - PCHAR Buffer; - ULONG BufferLength; - PNF_UDP_OPTIONS Option; -} DNSPKT, * PDNSPKT; - -typedef class DNSHandler -{ -public: - DNSHandler(string dnsHost, USHORT dnsPort); - - BOOL init(); - void free(); - - void Create(ENDPOINT_ID id, PBYTE target, ULONG targetLength, PCHAR buffer, ULONG bufferLength, PNF_UDP_OPTIONS options); -private: - void Thread(); - void Handle(); - - string dnsHost; - USHORT dnsPort = 0; - - HANDLE dnsLock; - queue dnsList; - vector dnsLoop; - - BOOL Started = FALSE; -} *PDNSHandler; - -#endif diff --git a/Redirector/EventHandler.cpp b/Redirector/EventHandler.cpp index 6bb2e662..8252442e 100644 --- a/Redirector/EventHandler.cpp +++ b/Redirector/EventHandler.cpp @@ -1,31 +1,36 @@ #include "EventHandler.h" -#include "DNSHandler.h" #include "TCPHandler.h" -#include "UDPHandler.h" -BOOL Started = FALSE; -BOOL filterLoop = FALSE; -BOOL filterICMP = TRUE; -BOOL filterTCP = TRUE; -BOOL filterUDP = TRUE; -BOOL dnsHook = FALSE; -string dnsHost = ""; -USHORT dnsPort = 0; -USHORT tcpLisn = 0; -USHORT udpLisn = 0; +extern BOOL filterTCP; +extern BOOL filterUDP; +extern USHORT udpPort; +extern vector handleList; +extern vector bypassList; -vector handleList; -vector bypassList; +extern mutex tcpLock; +extern mutex udpLock; +extern map tcpContext; +extern map udpContext; -mutex tcpLock; -mutex udpLock; -map tcpContext; -map udpContext; - -PDNSHandler dnsHandler = NULL; PTCPHandler tcpHandler = NULL; -PUDPHandler udpHandler = NULL; + +wstring getAddrString(PSOCKADDR addr) +{ + WCHAR buffer[MAX_PATH] = L""; + DWORD bufferLength = MAX_PATH; + + if (addr->sa_family == AF_INET) + { + WSAAddressToString(addr, sizeof(SOCKADDR_IN), NULL, buffer, &bufferLength); + } + else + { + WSAAddressToString(addr, sizeof(SOCKADDR_IN6), NULL, buffer, &bufferLength); + } + + return buffer; +} wstring getProcessName(DWORD id) { @@ -89,10 +94,7 @@ BOOL checkHandleName(DWORD id) BOOL eh_init() { - dnsHandler = new DNSHandler(dnsHost, dnsPort); - tcpHandler = new TCPHandler(tcpLisn); - udpHandler = new UDPHandler(); - + tcpHandler = new TCPHandler(); if (!tcpHandler->init()) { return FALSE; @@ -103,45 +105,40 @@ BOOL eh_init() void eh_free() { - lock_guard tlg(tcpLock); - lock_guard ulg(udpLock); - - for (auto& [k, v] : tcpContext) { - continue; - } - tcpContext.clear(); + lock_guard lg(tcpLock); - for (auto& [k, v] : udpContext) - { - if (v->Socket) + for (auto& [k, v] : tcpContext) { - closesocket(v->Socket); - v->Socket = NULL; + delete v; + continue; + } + tcpContext.clear(); + + if (tcpHandler) + { + tcpHandler->free(); + + delete tcpHandler; + tcpHandler = NULL; } } - udpContext.clear(); - - if (dnsHandler) + { - dnsHandler->free(); + lock_guard lg(udpLock); - delete dnsHandler; - dnsHandler = NULL; - } + for (auto& [k, v] : udpContext) + { + if (v->Socket) + { + closesocket(v->Socket); + v->Socket = NULL; + } - if (tcpHandler) - { - tcpHandler->free(); - - delete tcpHandler; - tcpHandler = NULL; - } - - if (udpHandler) - { - delete udpHandler; - udpHandler = NULL; + delete v; + continue; + } + udpContext.clear(); } } @@ -157,11 +154,19 @@ void threadEnd() void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info) { + if (!filterTCP) + { + nf_tcpDisableFiltering(id); + + wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!filterTCP] " << getProcessName(info->processId) << endl; + return; + } + if (checkBypassName(info->processId)) { nf_tcpDisableFiltering(id); - printf("[Redirector][EventHandler][tcpConnectRequest][%llu] this->checkBypassName\n", id); + wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][checkBypassName] " << getProcessName(info->processId) << endl; return; } @@ -169,16 +174,40 @@ void tcpConnectRequest(ENDPOINT_ID id, PNF_TCP_CONN_INFO info) { nf_tcpDisableFiltering(id); - printf("[Redirector][EventHandler][tcpConnectRequest][%llu] !this->checkHandleName\n", id); + wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!checkHandleName] " << getProcessName(info->processId) << endl; return; } + + if (info->ip_family != AF_INET && info->ip_family != AF_INET6) + { + nf_tcpDisableFiltering(id); + + wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][!IPv4 && !IPv6] " << getProcessName(info->processId) << endl; + return; + } + + tcpHandler->Create(id, info); + wcout << "[Redirector][EventHandler][tcpConnectRequest][" << id << "][" << info->processId << "][" << getAddrString((PSOCKADDR)info->remoteAddress) << "] " << getProcessName(info->processId) << endl; + + if (info->ip_family == AF_INET) + { + auto target = (PSOCKADDR_IN)info->remoteAddress; + target->sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); + target->sin_port = htons(tcpHandler->ListenIPv4); + } + + if (info->ip_family == AF_INET6) + { + auto target = (PSOCKADDR_IN6)info->remoteAddress; + memset(target->sin6_addr.u.Byte, 0, 16); + target->sin6_addr.u.Byte[15] = 0x01; + target->sin6_port = htons(tcpHandler->ListenIPv6); + } } void tcpConnected(ENDPOINT_ID id, PNF_TCP_CONN_INFO info) { - UNREFERENCED_PARAMETER(info); - - printf("[Redirector][EventHandler][tcpConnected][%llu]\n", id); + wcout << "[Redirector][EventHandler][tcpConnected][" << id << "][" << info->processId << "][" << getAddrString((PSOCKADDR)info->remoteAddress) << "] " << getProcessName(info->processId) << endl; } void tcpCanSend(ENDPOINT_ID id) @@ -203,12 +232,40 @@ void tcpReceive(ENDPOINT_ID id, const char* buffer, int length) void tcpClosed(ENDPOINT_ID id, PNF_TCP_CONN_INFO info) { - printf("[Redirector][EventHandler][tcpClosed][%llu]\n", id); + tcpHandler->Delete(id); + + printf("[Redirector][EventHandler][tcpClosed][%llu][%lu]\n", id, info->processId); } void udpCreated(ENDPOINT_ID id, PNF_UDP_CONN_INFO info) { - nf_udpDisableFiltering(id); + if (!filterUDP) + { + nf_udpDisableFiltering(id); + + wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!filterUDP] " << getProcessName(info->processId) << endl; + return; + } + + if (checkBypassName(info->processId)) + { + nf_udpDisableFiltering(id); + + wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][checkBypassName] " << getProcessName(info->processId) << endl; + return; + } + + if (!checkHandleName(info->processId)) + { + nf_udpDisableFiltering(id); + + wcout << "[Redirector][EventHandler][udpCreated][" << id << "][" << info->processId << "][!checkHandleName] " << getProcessName(info->processId) << endl; + return; + } + + lock_guard lg(udpLock); + udpContext[id] = new UDPINFO(); + udpContext[id]->PID = info->processId; } void udpConnectRequest(ENDPOINT_ID id, PNF_UDP_CONN_REQUEST info) @@ -224,7 +281,96 @@ void udpCanSend(ENDPOINT_ID id) void udpSend(ENDPOINT_ID id, const unsigned char* target, const char* buffer, int length, PNF_UDP_OPTIONS options) { - nf_udpPostSend(id, target, buffer, length, options); + lock_guard lg(udpLock); + if (udpContext.find(id) == udpContext.end()) + { + nf_udpPostSend(id, target, buffer, length, options); + return; + } + + if (!udpContext[id]->Socket) + { + auto client = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP); + if (!client) + { + printf("[Redirector][EventHandler][udpSend][%llu] Create socket failed: %d\n", id, WSAGetLastError()); + return; + } + + SOCKADDR_IN addr; + addr.sin_family = AF_INET; + addr.sin_addr.S_un.S_addr = INADDR_ANY; + addr.sin_port = 0; + + if (bind(client, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) + { + closesocket(client); + + printf("[Redirector][EventHandler][udpSend][%llu] Bind socket failed: %d\n", id, WSAGetLastError()); + return; + } + + addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); + addr.sin_port = htons(udpPort); + + if (sendto(client, (PCHAR)&udpContext[id]->PID, 4, 0, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) + { + closesocket(client); + + printf("[Redirector][EventHandler][udpSend][%llu] Send initial data failed: %d\n", id, WSAGetLastError()); + return; + } + udpContext[id]->Socket = client; + + auto data = new BYTE[sizeof(NF_UDP_OPTIONS) + options->optionsLength - 1](); + memcpy(data, options, sizeof(NF_UDP_OPTIONS) + options->optionsLength - 1); + thread(&udpBeginReceive, id, client, data).detach(); + } + + char* data = NULL; + int dataLength = 0; + if (((PSOCKADDR)target)->sa_family == AF_INET) + { + dataLength = length + 7; + data = new char[dataLength](); + data[0] = 0x01; + + auto addr = (PSOCKADDR_IN)target; + memcpy(data + 1, &addr->sin_addr, 4); + memcpy(data + 5, &addr->sin_port, 2); + memcpy(data + 7, buffer, length); + } + else if (((PSOCKADDR)target)->sa_family == AF_INET6) + { + dataLength = length + 19; + data = new char[dataLength](); + data[0] = 0x04; + + auto addr = (PSOCKADDR_IN6)target; + memcpy(data + 1, &addr->sin6_addr, 16); + memcpy(data + 17, &addr->sin6_port, 2); + memcpy(data + 19, buffer, length); + } + else + { + nf_udpPostSend(id, target, buffer, length, options); + return; + } + + if (data) + { + SOCKADDR_IN remote; + remote.sin_family = AF_INET; + remote.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); + remote.sin_port = htons(udpPort); + + if (sendto(udpContext[id]->Socket, data, dataLength, 0, (PSOCKADDR)&remote, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) + { + printf("[Redirector][EventHandler][udpSend][%llu] Send data failed: %d\n", id, WSAGetLastError()); + } + + delete[] data; + } } void udpCanReceive(ENDPOINT_ID id) @@ -239,11 +385,74 @@ void udpReceive(ENDPOINT_ID id, const unsigned char* target, const char* buffer, void udpClosed(ENDPOINT_ID id, PNF_UDP_CONN_INFO info) { - printf("[Redirector][EventHandler][udpClosed][%llu]\n", id); + UNREFERENCED_PARAMETER(info); lock_guard lg(udpLock); if (udpContext.find(id) != udpContext.end()) { + if (udpContext[id]->Socket != NULL) + { + closesocket(udpContext[id]->Socket); + udpContext[id]->Socket = NULL; + } + udpContext.erase(id); } + + printf("[Redirector][EventHandler][udpClosed][%llu]\n", id); +} + +void udpBeginReceive(ENDPOINT_ID id, SOCKET client, PBYTE data) +{ + auto buffer = new char[65535](); + + while (true) + { + SOCKADDR_IN remote; + int remoteLength = sizeof(SOCKADDR_IN); + + int length = recvfrom(client, buffer, sizeof(buffer), 0, (PSOCKADDR)&remote, &remoteLength); + if (length == 0) + { + break; + } + + if (length == SOCKET_ERROR) + { + int last = WSAGetLastError(); + if (last == 10004) + { + continue; + } + else if (last == 10038) + { + break; + } + + printf("[Redirector][udpBeginReceive][%llu] Receive failed: %d\n", id, last); + break; + } + + if (buffer[0] == 0x01 && length > 7) + { + SOCKADDR_IN target; + target.sin_family = AF_INET; + memcpy(&target.sin_addr, buffer + 1, 4); + memcpy(&target.sin_port, buffer + 5, 2); + + nf_udpPostReceive(id, (PBYTE)&target, buffer + 7, length - 7, (PNF_UDP_OPTIONS)data); + } + else if (buffer[0] == 0x04 && length > 19) + { + SOCKADDR_IN6 target; + target.sin6_family = AF_INET6; + memcpy(&target.sin6_addr, buffer + 1, 16); + memcpy(&target.sin6_port, buffer + 17, 2); + + nf_udpPostReceive(id, (PBYTE)&target, buffer + 19, length - 19, (PNF_UDP_OPTIONS)data); + } + } + + delete[] data; + delete[] buffer; } diff --git a/Redirector/EventHandler.h b/Redirector/EventHandler.h index c37c167e..c2185223 100644 --- a/Redirector/EventHandler.h +++ b/Redirector/EventHandler.h @@ -22,5 +22,6 @@ void udpSend(ENDPOINT_ID id, const unsigned char* target, const char* buffer, in void udpCanReceive(ENDPOINT_ID id); void udpReceive(ENDPOINT_ID id, const unsigned char* target, const char* buffer, int length, PNF_UDP_OPTIONS options); void udpClosed(ENDPOINT_ID id, PNF_UDP_CONN_INFO info); +void udpBeginReceive(ENDPOINT_ID id, SOCKET client, PBYTE data); #endif diff --git a/Redirector/IPEventHandler.cpp b/Redirector/IPEventHandler.cpp index b11f9839..b2bc6d81 100644 --- a/Redirector/IPEventHandler.cpp +++ b/Redirector/IPEventHandler.cpp @@ -1,7 +1,5 @@ #include "IPEventHandler.h" -#include "Utils.h" - USHORT IPv4Checksum(PBYTE buffer, ULONG64 size) { UINT32 sum = 0; @@ -53,14 +51,7 @@ void ipSend(const char* buffer, int length, PNF_IP_PACKET_OPTIONS options) return; } - auto data = (PBYTE)malloc(length); - if (!data) - { - puts("[Redirector][IPEventHandler][ipSend] Unable to allocate memory"); - - UNREFERENCED_PARAMETER(nf_ipPostSend(buffer, length, options)); - return; - } + auto data = new BYTE[length](); memcpy(data, buffer, length); { @@ -85,10 +76,10 @@ void ipSend(const char* buffer, int length, PNF_IP_PACKET_OPTIONS options) data[options->ipHeaderSize + 2] = icmpsum & 0xff; data[options->ipHeaderSize + 3] = (icmpsum >> 8); - printf("[Redirector][ipSend] Fake ICMP response for %d.%d.%d.%d\n", data[12], data[13], data[14], data[15]); + printf("[Redirector][IPEventHandler][ipSend] Fake ICMP response for %d.%d.%d.%d\n", data[12], data[13], data[14], data[15]); nf_ipPostReceive((PCHAR)data, length, options); - free(data); + delete[] data; } void ipReceive(const char* buffer, int length, PNF_IP_PACKET_OPTIONS options) diff --git a/Redirector/PROTOCOL.txt b/Redirector/PROTOCOL.txt index 0d3ef084..eeaf565e 100644 --- a/Redirector/PROTOCOL.txt +++ b/Redirector/PROTOCOL.txt @@ -1,27 +1,12 @@ All address use SOCKS5 format -/* DNS */ -Send -+------+ -| Data | -+------+ -| ???? | -+------+ - -Receive -+------+ -| Data | -+------+ -| ???? | -+------+ - /* TCP */ First Packet -+-----+--------+ -| PID | Target | -+-----+--------+ -| 4 | ?????? | -+-----+--------+ ++--------+-----+ +| Target | PID | ++--------+-----+ +| ?????? | 4 | ++--------+-----+ Send +------+ diff --git a/Redirector/Redirector.cpp b/Redirector/Redirector.cpp index ae797b53..a164aa22 100644 --- a/Redirector/Redirector.cpp +++ b/Redirector/Redirector.cpp @@ -1,36 +1,13 @@ #include "Based.h" - -#include "Utils.h" #include "EventHandler.h" #include "IPEventHandler.h" -typedef enum _AIO_TYPE { - AIO_FILTERLOOP, - AIO_FILTERICMP, - AIO_FILTERTCP, - AIO_FILTERUDP, - - AIO_CLRNAME, - AIO_ADDNAME, - AIO_BYPNAME, - - AIO_DNSHOOK, - AIO_DNSHOST, - AIO_DNSPORT, - - AIO_TCPPORT, - AIO_UDPPORT -} AIO_TYPE; - -extern BOOL filterLoop; +extern BOOL filterLoopback; extern BOOL filterICMP; extern BOOL filterTCP; extern BOOL filterUDP; -extern BOOL dnsHook; -extern string dnsHost; -extern USHORT dnsPort; -extern USHORT tcpLisn; -extern USHORT udpLisn; +extern USHORT tcpPort; +extern USHORT udpPort; extern vector handleList; extern vector bypassList; @@ -58,10 +35,10 @@ NF_IPEventHandler IPEventHandler = { ipSend }; -BOOL APIENTRY DllMain(HMODULE hModule, DWORD ul_reason_for_call, LPVOID lpReserved) +BOOL APIENTRY DllMain(HMODULE hModule, DWORD dwReason, LPVOID lpReserved) { UNREFERENCED_PARAMETER(hModule); - UNREFERENCED_PARAMETER(ul_reason_for_call); + UNREFERENCED_PARAMETER(dwReason); UNREFERENCED_PARAMETER(lpReserved); return TRUE; @@ -75,7 +52,7 @@ extern "C" { switch (name) { - case AIO_FILTERLOOP: + case AIO_FILTERLOOPBACK: break; case AIO_FILTERICMP: break; @@ -83,11 +60,11 @@ extern "C" { break; case AIO_FILTERUDP: break; - case AIO_DNSHOOK: + case AIO_CLRNAME: break; - case AIO_DNSHOST: + case AIO_BYPNAME: break; - case AIO_DNSPORT: + case AIO_ADDNAME: break; case AIO_TCPPORT: break; diff --git a/Redirector/Redirector.vcxproj b/Redirector/Redirector.vcxproj index 1d88782e..20584795 100644 --- a/Redirector/Redirector.vcxproj +++ b/Redirector/Redirector.vcxproj @@ -96,22 +96,17 @@ - + - - - - - diff --git a/Redirector/Redirector.vcxproj.filters b/Redirector/Redirector.vcxproj.filters index b954d1ac..17d9dcda 100644 --- a/Redirector/Redirector.vcxproj.filters +++ b/Redirector/Redirector.vcxproj.filters @@ -17,19 +17,13 @@ Source - - Source - Source - - Source - Source - + Source @@ -37,21 +31,12 @@ Header - - Header - Header - - Header - Header - - Header - Header diff --git a/Redirector/TCPHandler.cpp b/Redirector/TCPHandler.cpp index e2de720b..d21413c4 100644 --- a/Redirector/TCPHandler.cpp +++ b/Redirector/TCPHandler.cpp @@ -1,15 +1,42 @@ #include "TCPHandler.h" -TCPHandler::TCPHandler(USHORT tcpPort) +extern USHORT tcpPort; + +extern mutex tcpLock; +extern map tcpContext; + +void IoConn(SOCKET client, SOCKET remote) { - this->tcpPort = tcpPort; + char buffer[1400]; + + while (true) + { + auto length = recv(client, buffer, 1400, 0); + if (!length) + { + if (length == SOCKET_ERROR) + { + printf("[Redirector][TCPHandler][IoConn] Receive failed: %d\n", WSAGetLastError()); + return; + } + + continue; + } + + auto sended = send(remote, buffer, length, 0); + if (!sended && sended != length) + { + printf("[Redirector][TCPHandler][IoConn] Send failed: %d\n", WSAGetLastError()); + return; + } + } } BOOL TCPHandler::init() { { - this->IPv4Socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (!this->IPv4Socket) + this->SocketIPv4 = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (!this->SocketIPv4) { printf("[Redirector][TCPHandler::init][IPv4] Create socket failed: %d\n", WSAGetLastError()); return FALSE; @@ -17,24 +44,34 @@ BOOL TCPHandler::init() SOCKADDR_IN addr; addr.sin_family = AF_INET; + addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); addr.sin_port = 0; - if (bind(this->IPv4Socket, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) + if (bind(this->SocketIPv4, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN)) == SOCKET_ERROR) { printf("[Redirector][TCPHandler::init][IPv4] Bind socket failed: %d\n", WSAGetLastError()); return FALSE; } - if (listen(this->IPv4Socket, 1024) == SOCKET_ERROR) + if (listen(this->SocketIPv4, 1024) == SOCKET_ERROR) { printf("[Redirector][TCPHandler::init][IPv4] Listen socket failed: %d\n", WSAGetLastError()); return FALSE; } + + int addrLength = 0; + if (getsockname(this->SocketIPv4, (PSOCKADDR)&addr, &addrLength) != NO_ERROR) + { + printf("[Redirector][TCPHandler::init][IPv4] Get local address failed: %d\n", WSAGetLastError()); + return FALSE; + } + + this->ListenIPv4 = addr.sin_port; } { - this->IPv6Socket = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); - if (!this->IPv6Socket) + this->SocketIPv6 = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); + if (!this->SocketIPv6) { printf("[Redirector][TCPHandler::init][IPv6] Create socket failed: %d\n", WSAGetLastError()); return FALSE; @@ -42,28 +79,31 @@ BOOL TCPHandler::init() SOCKADDR_IN6 addr; addr.sin6_family = AF_INET6; + addr.sin6_addr.u.Byte[15] = 1; addr.sin6_port = 0; - if (bind(this->IPv6Socket, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN6)) == SOCKET_ERROR) + if (bind(this->SocketIPv6, (PSOCKADDR)&addr, sizeof(SOCKADDR_IN6)) == SOCKET_ERROR) { printf("[Redirector][TCPHandler::init][IPv6] Bind socket failed: %d\n", WSAGetLastError()); return FALSE; } - if (listen(this->IPv6Socket, 1024) == SOCKET_ERROR) + if (listen(this->SocketIPv6, 1024) == SOCKET_ERROR) { printf("[Redirector][TCPHandler::init][IPv6] Listen socket failed: %d\n", WSAGetLastError()); return FALSE; } + + int addrLength = 0; + if (getsockname(this->SocketIPv6, (PSOCKADDR)&addr, &addrLength) != NO_ERROR) + { + printf("[Redirector][TCPHandler::init][IPv6] Get local address failed: %d\n", WSAGetLastError()); + return FALSE; + } + + this->ListenIPv6 = addr.sin6_port; } - this->tcpLock = CreateMutex(NULL, FALSE, NULL); - if (!this->tcpLock) - { - return FALSE; - } - - this->Started = TRUE; thread(&TCPHandler::IPv4, this).detach(); thread(&TCPHandler::IPv6, this).detach(); return TRUE; @@ -71,56 +111,88 @@ BOOL TCPHandler::init() void TCPHandler::free() { - WaitForSingleObject(this->tcpLock, INFINITE); + lock_guard lg(this->Lock); - if (this->IPv4Socket) + if (this->SocketIPv4) { - closesocket(this->IPv4Socket); - this->IPv4Socket = NULL; + closesocket(this->SocketIPv4); + this->SocketIPv4 = NULL; } - if (this->IPv6Socket) + if (this->SocketIPv6) { - closesocket(this->IPv6Socket); - this->IPv6Socket = NULL; + closesocket(this->SocketIPv6); + this->SocketIPv6 = NULL; } - for (auto& [k, v] : this->tcpContext) - { - continue; - } - this->tcpContext.clear(); + this->Context.clear(); +} - if (this->tcpLock) +void TCPHandler::Create(ENDPOINT_ID id, PNF_TCP_CONN_INFO info) +{ + auto uid = (info->ip_family == AF_INET) ? ((PSOCKADDR_IN)info->localAddress)->sin_port : ((PSOCKADDR_IN6)info->localAddress)->sin6_port; + + auto data = new TCPINFO(); + data->PID = info->processId; + memcpy(data->Client, info->localAddress, NF_MAX_ADDRESS_LENGTH); + memcpy(data->Target, info->remoteAddress, NF_MAX_ADDRESS_LENGTH); + + lock_guard lga(tcpLock); + lock_guard lgb(this->Lock); + tcpContext[id] = data; + this->Context[uid] = id; +} + +void TCPHandler::Delete(ENDPOINT_ID id) +{ + lock_guard lga(tcpLock); + lock_guard lgb(this->Lock); + + if (tcpContext.find(id) != tcpContext.end()) { - CloseHandle(this->tcpLock); - this->tcpLock = NULL; + delete tcpContext[id]; + + tcpContext.erase(id); + } + + USHORT uid = 0; + for (auto i = this->Context.begin(); i != this->Context.end(); i++) + { + if (i->second == id) + { + uid = i->first; + break; + } + } + + if (uid) + { + this->Context.erase(uid); } } void TCPHandler::IPv4() { - while (this->Started && this->IPv4Socket) - { - SOCKADDR_IN addr; - int addrLength = 0; + SOCKADDR_IN addr; + int addrLength = 0; - auto client = accept(this->IPv4Socket, (PSOCKADDR)&addr, &addrLength); + while (this->SocketIPv4) + { + auto client = accept(this->SocketIPv4, (PSOCKADDR)&addr, &addrLength); if (!client) { - printf("[Redirector][TCPHandler::IPv4Handler] Accept client failed: %d\n", WSAGetLastError()); + printf("[Redirector][TCPHandler::IPv4] Accept client failed: %d\n", WSAGetLastError()); return; } - WaitForSingleObject(this->tcpLock, INFINITE); - if (this->tcpContext.find(addr.sin_port) == this->tcpContext.end()) { - ReleaseMutex(this->tcpLock); - - closesocket(client); - continue; + lock_guard lg(this->Lock); + if (this->Context.find(addr.sin_port) == this->Context.end()) + { + closesocket(client); + continue; + } } - ReleaseMutex(this->tcpLock); thread(&TCPHandler::Handle, this, client, addr.sin_port).detach(); } @@ -128,22 +200,43 @@ void TCPHandler::IPv4() void TCPHandler::IPv6() { - while (this->Started && this->IPv6Socket) - { + SOCKADDR_IN6 addr; + int addrLength = 0; + while (this->SocketIPv6) + { + auto client = accept(this->SocketIPv6, (PSOCKADDR)&addr, &addrLength); + if (!client) + { + printf("[Redirector][TCPHandler::IPv6] Accept client failed: %d\n", WSAGetLastError()); + return; + } + + { + lock_guard lg(this->Lock); + if (this->Context.find(addr.sin6_port) == this->Context.end()) + { + closesocket(client); + continue; + } + } + + thread(&TCPHandler::Handle, this, client, addr.sin6_port).detach(); } } void TCPHandler::Handle(SOCKET client, USHORT side) { + tcpLock.lock(); + this->Lock.lock(); + PTCPINFO data = tcpContext[this->Context[side]]; + this->Lock.unlock(); + tcpLock.unlock(); + SOCKADDR_IN addr; addr.sin_family = AF_INET; addr.sin_addr.S_un.S_addr = htonl(INADDR_LOOPBACK); - addr.sin_port = htons(this->tcpPort); - - WaitForSingleObject(this->tcpLock, INFINITE); - auto data = this->tcpContext[side]; - ReleaseMutex(this->tcpLock); + addr.sin_port = htons(tcpPort); auto remote = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if (!remote) @@ -162,4 +255,49 @@ void TCPHandler::Handle(SOCKET client, USHORT side) closesocket(remote); return; } + + if (((PSOCKADDR)data->Target)->sa_family == AF_INET) + { + auto target = (PSOCKADDR_IN)data->Target; + + char buffer[11]; + buffer[0] = 0x01; + memcpy(buffer + 1, &target->sin_addr.S_un.S_addr, 4); + memcpy(buffer + 5, &target->sin_port, 2); + memcpy(buffer + 7, &data->PID, 4); + + if (send(remote, buffer, 11, 0) == SOCKET_ERROR) + { + printf("[Redirector][TCPHandler::Handle] Send request failed: %d\n", WSAGetLastError()); + + closesocket(client); + closesocket(remote); + return; + } + } + else + { + auto target = (PSOCKADDR_IN6)data->Target; + + char buffer[23]; + buffer[0] = 0x04; + memcpy(buffer + 1, target->sin6_addr.u.Byte, 16); + memcpy(buffer + 17, &target->sin6_port, 2); + memcpy(buffer + 19, &data->PID, 4); + + if (send(remote, buffer, 23, 0) == SOCKET_ERROR) + { + printf("[Redirector][TCPHandler::Handle] Send request failed: %d\n", WSAGetLastError()); + + closesocket(client); + closesocket(remote); + return; + } + } + + thread(IoConn, client, remote).detach(); + IoConn(remote, client); + + closesocket(client); + closesocket(remote); } diff --git a/Redirector/TCPHandler.h b/Redirector/TCPHandler.h index d348dad4..600b4acd 100644 --- a/Redirector/TCPHandler.h +++ b/Redirector/TCPHandler.h @@ -3,31 +3,27 @@ #define TCPHANDLER_H #include "Based.h" -typedef struct _TCPINFO { - DWORD PID; - SOCKADDR Target; -} TCPINFO, * PTCPINFO; - typedef class TCPHandler { public: - TCPHandler(USHORT tcpPort); - BOOL init(); void free(); - HANDLE tcpLock = NULL; - map tcpContext; + void Create(ENDPOINT_ID id, PNF_TCP_CONN_INFO info); + void Delete(ENDPOINT_ID id); + + USHORT ListenIPv4 = 0; + USHORT ListenIPv6 = 0; private: void IPv4(); void IPv6(); void Handle(SOCKET client, USHORT side); - USHORT tcpPort = 0; + mutex Lock; + map Context; - BOOL Started = FALSE; - SOCKET IPv4Socket = NULL; - SOCKET IPv6Socket = NULL; + SOCKET SocketIPv4 = NULL; + SOCKET SocketIPv6 = NULL; } *PTCPHandler; #endif diff --git a/Redirector/UDPHandler.cpp b/Redirector/UDPHandler.cpp deleted file mode 100644 index 4b6e4002..00000000 --- a/Redirector/UDPHandler.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include "UDPHandler.h" - -BOOL UDPHandler::init() -{ - return 0; -} - -void UDPHandler::free() -{ - -} diff --git a/Redirector/UDPHandler.h b/Redirector/UDPHandler.h deleted file mode 100644 index a0e0e74c..00000000 --- a/Redirector/UDPHandler.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once -#ifndef UDPHANDLER_H -#define UDPHANDLER_H -#include "Based.h" - -typedef struct _UDPINFO { - SOCKET Socket; -} UDPINFO, * PUDPINFO; - -typedef class UDPHandler -{ -public: - BOOL init(); - void free(); -} *PUDPHandler; - -#endif diff --git a/Redirector/Utils.cpp b/Redirector/Utils.cpp deleted file mode 100644 index bbd9f881..00000000 --- a/Redirector/Utils.cpp +++ /dev/null @@ -1 +0,0 @@ -#include "Utils.h" diff --git a/Redirector/Utils.h b/Redirector/Utils.h deleted file mode 100644 index b1bddcfe..00000000 --- a/Redirector/Utils.h +++ /dev/null @@ -1,5 +0,0 @@ -#pragma once -#ifndef UTILS_H -#define UTILS_H - -#endif