Guest User

Client.cpp

a guest
Dec 22nd, 2025
36
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 13.00 KB | None | 0 0
  1. #define DEBUG_EXCCLIENT 1
  2. #define BUFFLEN 1024
  3.  
  4. #define ADAPTER_NAME "ExCClientTUNAdapter"
  5. #define ADAPTER_NAMEW L"ExCClientTUNAdapter"
  6.  
  7. #ifndef WIN32_LEAN_AND_MEAN
  8. #define WIN32_LEAN_AND_MEAN
  9. #endif
  10. #include <windows.h>
  11. #include <winsock2.h>
  12. #include <ws2tcpip.h>
  13. #include <iphlpapi.h>
  14. #include <iostream>
  15. #include <map>
  16. #include <string>
  17. #include <thread>
  18. #include <vector>
  19. #include <Objbase.h>
  20. #include "wintun.h"
  21. #include "md5.h"
  22.  
  23. static WINTUN_CREATE_ADAPTER_FUNC* WintunCreateAdapter;
  24. static WINTUN_CLOSE_ADAPTER_FUNC* WintunCloseAdapter;
  25. static WINTUN_OPEN_ADAPTER_FUNC* WintunOpenAdapter;
  26. static WINTUN_GET_ADAPTER_LUID_FUNC* WintunGetAdapterLUID;
  27. static WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC* WintunGetRunningDriverVersion;
  28. static WINTUN_DELETE_DRIVER_FUNC* WintunDeleteDriver;
  29. static WINTUN_SET_LOGGER_FUNC* WintunSetLogger;
  30. static WINTUN_START_SESSION_FUNC* WintunStartSession;
  31. static WINTUN_END_SESSION_FUNC* WintunEndSession;
  32. static WINTUN_GET_READ_WAIT_EVENT_FUNC* WintunGetReadWaitEvent;
  33. static WINTUN_RECEIVE_PACKET_FUNC* WintunReceivePacket;
  34. static WINTUN_RELEASE_RECEIVE_PACKET_FUNC* WintunReleaseReceivePacket;
  35. static WINTUN_ALLOCATE_SEND_PACKET_FUNC* WintunAllocateSendPacket;
  36. static WINTUN_SEND_PACKET_FUNC* WintunSendPacket;
  37.  
  38. #pragma comment(lib, "Ws2_32.lib")
  39. #pragma comment(lib, "iphlpapi.lib")
  40. #pragma warning(disable : 4996)
  41.  
  42. using std::cout, std::map, std::string, std::to_string, std::vector;
  43.  
  44. string seckey;
  45.  
  46. inline bool cstrcmp(char* s1, char* s2, size_t len) {
  47.     for (size_t i = 0; i < len; i++) if (s1[i] != s2[i]) return false;
  48.     return true;
  49. }
  50.  
  51. template<typename S>
  52. inline void addstr(S dest, S src, size_t len, size_t offset = 0) {
  53.     if (!dest || !src || len == 0) return;
  54.     for (size_t i = 0; i < len; i++) {
  55.         dest[i + offset] = src[i];
  56.     }
  57. }
  58.  
  59. template<typename I>
  60. I strtoint(char* data, size_t len, bool u = false) {
  61.     using uI = typename std::make_unsigned<I>::type;
  62.     uI output = 0;
  63.     bool fbit = data[len - 1] == 1;
  64.     for (size_t i = 0; i < len - (u ? 0 : 1); i++) {
  65.         output |= ((uI)(BYTE)(data[i])) << (i * 8);
  66.     }
  67.     if (!u && fbit) return 0 - ((I)output);
  68.     return (I)output;
  69. }
  70.  
  71. template<typename I>
  72. char* inttostr(I data, size_t len, bool u = false) {
  73.     using uI = typename std::make_unsigned<I>::type;
  74.     uI d = (data < 0) ? 0 - ((uI)data) : data;
  75.     bool fbit = data < 0;
  76.     BYTE* str = new BYTE[len];
  77.     for (size_t c = 0; c < len - (u ? 0 : 1); c++) {
  78.         str[c] = (BYTE)(d % 256);
  79.         d = (d - str[c]) / 256;
  80.     }
  81.     if (!u) str[len - 1] = fbit;
  82.     return (char*)str;
  83. }
  84.  
  85. int recv_all(SOCKET sock, char** buff, size_t len) {
  86.     size_t c = len;
  87.     char* buf = new char[BUFFLEN];
  88.     *buff = new char[len];
  89.     while (c > 0) {
  90.         int res = recv(sock, buf, min(BUFFLEN, c), 0);
  91.         if (res == SOCKET_ERROR) return WSAGetLastError();
  92.         if (res == 0) return -1;
  93.         addstr(*buff, buf, res, len - c);
  94.         c -= res;
  95.     }
  96.     delete[] buf;
  97.     return 0;
  98. }
  99.  
  100. int recv_wrapper(SOCKET sock, char** buff, size_t* len) {
  101.     char* buf;
  102.     int res = recv_all(sock, &buf, 8);
  103.     if (res != 0) return res;
  104.     size_t c = strtoint<size_t>(buf, 8, true);
  105.     res = recv_all(sock, &buf, c);
  106.     if (res != 0) return res;
  107.     *buff = buf;
  108.     *len = c;
  109.     return 0;
  110. }
  111.  
  112. int send_wrapper(SOCKET sock, char* buff, size_t len) {
  113.     char* packetlen = inttostr(len, 8, true);
  114.     char* buf = new char[len + 8];
  115.     addstr(buf, packetlen, 8);
  116.     addstr(buf, buff, len, 8);
  117.     size_t sent = 0;
  118.     while (sent < len + 8) {
  119.         int n = send(sock, buf + sent, len + 8 - sent, 0);
  120.         if (n == SOCKET_ERROR) return WSAGetLastError();
  121.         sent += n;
  122.     }
  123.     delete[] packetlen;
  124.     delete[] buf;
  125.     return 0;
  126. }
  127.  
  128. HMODULE
  129. InitializeWintun(void)
  130. {
  131.     HMODULE Wintun =
  132.         LoadLibraryExW(L"wintun.dll", NULL, LOAD_LIBRARY_SEARCH_APPLICATION_DIR | LOAD_LIBRARY_SEARCH_SYSTEM32);
  133.     if (!Wintun)
  134.         return NULL;
  135. #define X(Name) ((*(FARPROC *)&Name = GetProcAddress(Wintun, #Name)) == NULL)
  136.     if (X(WintunCreateAdapter) || X(WintunCloseAdapter) || X(WintunOpenAdapter) || X(WintunGetAdapterLUID) ||
  137.         X(WintunGetRunningDriverVersion) || X(WintunDeleteDriver) || X(WintunSetLogger) || X(WintunStartSession) ||
  138.         X(WintunEndSession) || X(WintunGetReadWaitEvent) || X(WintunReceivePacket) || X(WintunReleaseReceivePacket) ||
  139.         X(WintunAllocateSendPacket) || X(WintunSendPacket))
  140. #undef X
  141.     {
  142.         DWORD LastError = GetLastError();
  143.         FreeLibrary(Wintun);
  144.         SetLastError(LastError);
  145.         return NULL;
  146.     }
  147.     return Wintun;
  148. }
  149. HMODULE Wintun;
  150. WINTUN_ADAPTER_HANDLE adapter;
  151. WINTUN_SESSION_HANDLE session;
  152. SOCKET sock;
  153. bool w = true, r = true, s = true;
  154.  
  155. inline bool waitForThreads() {
  156.     if (w) return false;
  157.     while (!r && !s) Sleep(50);
  158.     return true;
  159. }
  160.  
  161. static BOOL WINAPI
  162. CtrlHandler(_In_ DWORD CtrlType)
  163. {
  164.     switch (CtrlType)
  165.     {
  166.     case CTRL_C_EVENT:
  167.     case CTRL_BREAK_EVENT:
  168.     case CTRL_CLOSE_EVENT:
  169.     case CTRL_LOGOFF_EVENT:
  170.     case CTRL_SHUTDOWN_EVENT:
  171.         w = false;
  172.         cout << "I: Stopping...\n";
  173.         waitForThreads();
  174.         return TRUE;
  175.     }
  176.     return FALSE;
  177. }
  178.  
  179. size_t encrypt(BYTE* i, BYTE** o, size_t len) {
  180.     *o = i;
  181.     return len;
  182. }
  183.  
  184. size_t decrypt(BYTE* i, BYTE** o, size_t len) {
  185.     *o = i;
  186.     return len;
  187. }
  188.  
  189. void recv_thread() {
  190.     while (w) {
  191.         char* buff;
  192.         size_t len;
  193.         int res = recv_wrapper(sock, &buff, &len);
  194.         if (res == -1) {
  195.             cout << "F: Recv thread error: connection closed\n";
  196.             break;
  197.         }
  198.         if (res > 0) {
  199.             cout << "F: Recv thread error: " << res << "\n";
  200.             break;
  201.         }
  202.         if (len > 0 && buff) {
  203.             BYTE* p = WintunAllocateSendPacket(session, (DWORD)len);
  204.             if (p) {
  205.                 BYTE* data = (BYTE*)buff;
  206.                 len = decrypt(data, &data, len);
  207.                 addstr(p, data, len);
  208.                 delete[] data;
  209.                 WintunSendPacket(session, p);
  210.                 cout << "I: Recv " << len << "bytes\n";
  211.             }
  212.             delete[] buff;
  213.         }
  214.     }
  215.     w = false;
  216.     r = false;
  217. }
  218.  
  219. void send_thread() {
  220.     HANDLE ev = WintunGetReadWaitEvent(session);
  221.     while (w) {
  222.         DWORD psize;
  223.         BYTE* p = WintunReceivePacket(session, &psize);
  224.         if (p) {
  225.             BYTE* data1 = new BYTE[psize];
  226.             addstr(data1, p, psize);
  227.             psize = encrypt(data1, &data1, psize);
  228.             int res = send_wrapper(sock, (char*)data1, psize);
  229.             delete[] data1;
  230.             WintunReleaseReceivePacket(session, p);
  231.             if (res == -1) {
  232.                 cout << "F: Send thread error: connection closed\n";
  233.                 break;
  234.             }
  235.             if (res > 0) {
  236.                 cout << "F: Send thread error: " << res << "\n";
  237.                 break;
  238.             }
  239.             cout << "I: Send " << psize << "bytes\n";
  240.         }
  241.         else {
  242.             WaitForSingleObject(ev, INFINITE);
  243.         }
  244.     }
  245.     w = false;
  246.     s = false;
  247. }
  248.  
  249. inline void freep(USHORT stage = 5) {
  250.     if (stage > 4) {
  251.         WintunEndSession(session);
  252.     }
  253.     if (stage > 3) {
  254.         closesocket(sock);
  255.     }
  256.     if (stage > 2) {
  257.         WSACleanup();
  258.     }
  259.     if (stage > 1) {
  260.         WintunCloseAdapter(adapter);
  261.     }
  262.     if (stage > 0) {
  263.         FreeLibrary(Wintun);
  264.     }
  265.     SetConsoleCtrlHandler(CtrlHandler, FALSE);
  266. }
  267.  
  268. int main(int argc, char* argv[])
  269. {
  270.     int res;
  271.     SetConsoleCtrlHandler(CtrlHandler, TRUE);
  272.     map<string, string> args;
  273.     for (int i = 1; i < argc; i++) {
  274.         string x = argv[i];
  275.         size_t pos = x.find_first_of("=");
  276.         if (pos == string::npos) {
  277.             args.insert(std::pair(x, ""));
  278.         }
  279.         args.insert(std::pair(x.substr(0, pos), x.substr(pos + 1, x.size() - pos - 1)));
  280.     }
  281. #if DEBUG_EXCCLIENT == 1
  282.     args.insert(std::pair("--ip", "127.0.0.1"));
  283.     args.insert(std::pair("--port", "80"));
  284.     args.insert(std::pair("--seckey", "OlwCTg9KQa5Fbu1PzeVYh0LWs6Gni2Ax"));
  285. #endif
  286.     cout << "ExC Client\nArgs:\n";
  287.     if (args.empty())
  288.         cout << " - No args\n";
  289.     else for (auto& p : args) {
  290.         cout << " - \"" << p.first << "\"=\"" << p.second << "\"\n";
  291.     }
  292.     if (!args.contains("--ip")) {
  293.         cout << "F: no ip\n";
  294.         freep(0);
  295.         return 1;
  296.     }
  297.     if (!args.contains("--port")) {
  298.         cout << "F: no port\n";
  299.         freep(0);
  300.         return 1;
  301.     }
  302.     if (!args.contains("--seckey")) {
  303.         cout << "F: no secure key\n";
  304.         freep(0);
  305.         return 1;
  306.     }
  307.     seckey = args["--seckey"];
  308.     if ((Wintun = InitializeWintun()) == NULL) {
  309.         cout << "F: wintun can't be loaded. Check wintun.dll or it is corrupted: " << GetLastError() << "\n";
  310.         freep(0);
  311.         return 1;
  312.     }
  313.     GUID AdapterGuid = { 0xDEADDEAD, 0x0012, 0x0030, { 0xA1, 0xB2, 0xC3, 0xD4, 0xF5, 0x6A, 0x7B, 0x8C } };
  314.     adapter = WintunCreateAdapter(ADAPTER_NAMEW, L"TUN", &AdapterGuid);
  315.     if (!adapter)
  316.     {
  317.         res = GetLastError();
  318.         if (res != ERROR_ALREADY_EXISTS) {
  319.             cout << "F: failed to create TUN adapter: " << res << "\n";
  320.             freep(1);
  321.             return 1;
  322.         }
  323.         adapter = WintunOpenAdapter(ADAPTER_NAMEW);
  324.         if (!adapter) {
  325.             cout << "F: failed to open TUN adapter: " << GetLastError() << "\n";
  326.             freep(1);
  327.             return 1;
  328.         }
  329.     }
  330.     cout << "I: TUN adapter:\nName=" << ADAPTER_NAME << "\nType=TUN\nGUID={" << std::hex << AdapterGuid.Data1 << "-"
  331.         << AdapterGuid.Data2 << "-" << AdapterGuid.Data3 << "-" << (short)AdapterGuid.Data4[0] << (short)AdapterGuid.Data4[1] << "-"
  332.         << (short)AdapterGuid.Data4[2] << (short)AdapterGuid.Data4[3] << (short)AdapterGuid.Data4[4] << (short)AdapterGuid.Data4[5]
  333.         << (short)AdapterGuid.Data4[6] << (short)AdapterGuid.Data4[7] << std::dec << "}\n";
  334.     MIB_UNICASTIPADDRESS_ROW AddressRow;
  335.     InitializeUnicastIpAddressEntry(&AddressRow);
  336.     WintunGetAdapterLUID(adapter, &AddressRow.InterfaceLuid);
  337.     AddressRow.Address.Ipv4.sin_family = AF_INET;
  338.     AddressRow.Address.Ipv4.sin_addr.S_un.S_addr = htonl((192 << 24) | (168 << 16) | (0x12 << 8) | (0x30 << 0));
  339.     AddressRow.OnLinkPrefixLength = 24;
  340.     AddressRow.DadState = IpDadStatePreferred;
  341.     res = CreateUnicastIpAddressEntry(&AddressRow);
  342.     if (res != ERROR_SUCCESS && res != ERROR_OBJECT_ALREADY_EXISTS)
  343.     {
  344.         cout << "F: failed to set IP address: " << res << "\n";
  345.         freep(2);
  346.         return 1;
  347.     }
  348.     cout << "I: local IP address: 192.168.18.48\n";
  349.     WSADATA wsad;
  350.     res = WSAStartup(MAKEWORD(2, 2), &wsad);
  351.     if (res != 0) {
  352.         cout << "F: WSAStartup failed: " << res << "\n";
  353.         freep(2);
  354.         return 1;
  355.     }
  356.     addrinfo* result = NULL, hints;
  357.     ZeroMemory(&hints, sizeof(hints));
  358.     hints.ai_family = AF_UNSPEC;
  359.     hints.ai_socktype = SOCK_STREAM;
  360.     hints.ai_protocol = IPPROTO_TCP;
  361.     res = getaddrinfo(args["--ip"].c_str(), args["--port"].c_str(), &hints, &result);
  362.     if (res != 0) {
  363.         cout << "F: getaddrinfo failed: " << res << "\n";
  364.         freep(3);
  365.         return 1;
  366.     }
  367.  
  368.     sock = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  369.     if (sock == INVALID_SOCKET) {
  370.         cout << "F: error at socket(): " << WSAGetLastError() << "\n";
  371.         freep(3);
  372.         return 1;
  373.     }
  374.     if (connect(sock, result->ai_addr, (int)result->ai_addrlen) == SOCKET_ERROR) {
  375.         cout << "F: connect failed with error: " << WSAGetLastError() << "\n";
  376.         freep(4);
  377.         return 1;
  378.     }
  379.     cout << "I: connect to " << args["--ip"] << ":" << args["--port"] << "\n";
  380.     freeaddrinfo(result);
  381.     session = WintunStartSession(adapter, 0x400000);
  382.     if (!session)
  383.     {
  384.         cout << "F: failed to start adapter session";
  385.         freep(4);
  386.         return 1;
  387.     }
  388.     string hash = MD5::hash(seckey);
  389.     if ((res = send_wrapper(sock, hash.data(), hash.size())) != 0) {
  390.         cout << "F: failed to start adapter session";
  391.         freep();
  392.         return 1;
  393.     }
  394.  
  395.     char* skresp;
  396.     size_t len;
  397.     if ((res = recv_wrapper(sock, &skresp, &len)) == -1) {
  398.         cout << "F: Connection closed: secure key\n";
  399.         freep();
  400.         return 1;
  401.     }
  402.     else if (res > 0) {
  403.         cout << "F: Connection error: secure key recv " << res << "\n";
  404.         freep();
  405.         return 1;
  406.     }
  407.     if (skresp[0] == 1) {
  408.         cout << "F: Connection error: secure key lenght\n";
  409.         freep();
  410.         return 1;
  411.     }
  412.     else if (skresp[0] == 2) {
  413.         cout << "F: Connection error: secure key data\n";
  414.         freep();
  415.         return 1;
  416.     }
  417.     cout << "I: Secure key is ok\n";
  418.     std::thread rth{ recv_thread },
  419.         sth{ send_thread };
  420.     rth.detach();
  421.     sth.detach();
  422.  
  423.     while (!waitForThreads()) Sleep(50);
  424.  
  425.     cout << "I: Cleanup...\n";
  426.     freep();
  427.     return 0;
  428. }
Advertisement
Add Comment
Please, Sign In to add comment