В общем, сегодня мне в аську постучал один человек и начал расспрашивать, почему у него ничего не получается. Он сделал фейк контакта и хотел прописать его в файле hosts, но его сайт хостится на виртуальной площадке (на одном ip закреплены кучи сайтов, а за распределение адресов отвечает веб сервер) в общем, тупая подмена ip ему не светила. Немного подумав, я придумал, а что если сделать локальный сервер, который бы при подключении выдавал бы нам нужную страницу? Идея заключается в следующем в файле хост прописывается IP сервера и подменяемый адрес: 127.0.0.2 vkontakte.ru Запускается сервер, который вешается на 127.0.0.2:80 и оправляет валидный HTTP ответ на GET запрос обозревателя. Сначала я брал HTTP ответ из файлика (в принципе и сейчас так, потому что я не смог решить проблему с динамическим изменением размера выделяемой памяти для всего ответа) потом подумав немного написал автоматический запрос подложного ответа с фейкового сайта. Потом я начал мыслить дальше, а что если записывать не в файл, а сделать потоки чтения и отправки (типа прокси-сервера) потом вообще подумал, может написать прокси-сервер который подменял бы на лету HTTP заголовки host и перенаправлял бы нужные на фейковые страницы.... но писать прокси это о-го-го.... да и что заморачиватся. Code: #include <stdio.h> #include <winsock2.h> #include <windows.h> #define GS_PORT 80 //порт сервера #define GS_IP "127.0.0.2" //IP сервера //фейковые данные #define GS_FAKE_HOST "zona-chat.narod.ru" #define GS_FAKE_PATH "\/" #define GS_FAKE_PORT 80 #define GS_FAKE_FILE "~http" #define GET "GET %s HTTP/1.0\n\ User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)\n\ Host: %s\n\ Accept: text\/\*;q=0,9\n\ Connection: close\n\n" unsigned char * fake; size_t file_size; int GetFakeContent(); //функция запроса фейкового ответа int SexToClient(void * client_socket); // :) // отправить ВСЕ - правильная функция int sendall(SOCKET s, char * buf, int len, int flags) { int total = 0; int n; while (total < len) { n = send(s, buf + total, len - total, flags); if (n == -1) { break; } total += n; } return (n == -1 ? -1 : total); } int main(int argc, char * argv[]) { char buff[1024]; SOCKET mysocket; struct sockaddr_in local_addr; SOCKET client_socket; struct sockaddr_in client_addr; int client_addr_size = sizeof(client_addr); if (WSAStartup(0x0202, (WSADATA * ) & buff[0])) { printf("Error WSAStartup %d\n", WSAGetLastError()); return - 1; } printf("Get fake data http:\/\/%s%s:%d...\n", GS_FAKE_HOST, GS_FAKE_PATH, GS_FAKE_PORT); if (GetFakeContent() == -1) { WSACleanup(); return - 1; } if ((mysocket = socket(AF_INET, SOCK_STREAM, 0)) < 0) { printf("Error socket %d\n", WSAGetLastError()); WSACleanup(); return - 1; } local_addr.sin_family = AF_INET; local_addr.sin_port = htons(GS_PORT); local_addr.sin_addr.s_addr = inet_addr(GS_IP); if (bind(mysocket, (struct sockaddr * ) & local_addr, sizeof(local_addr))) { printf("Error bind %d\n", WSAGetLastError()); closesocket(mysocket); WSACleanup(); return - 1; } if (listen(mysocket, 0x100)) { // Ioeaea ! printf("Error listen %d\n", WSAGetLastError()); closesocket(mysocket); WSACleanup(); return - 1; } printf("Waiting for connections %s:%d...\n", GS_IP, GS_PORT); while ((client_socket = accept(mysocket, (struct sockaddr * ) & client_addr, & client_addr_size))) { SexToClient( & client_socket); } free(fake); WSACleanup(); return 0; } int GetFakeContent() { SOCKET sock; HOSTENT * hst; FILE * f; struct sockaddr_in sin; int bytes_recv; char buff[20 * 1024]; sin.sin_family = AF_INET; sin.sin_port = htons(GS_FAKE_PORT); if (hst = gethostbyname(GS_FAKE_HOST)) { ((unsigned long * ) & sin.sin_addr)[0] = ((unsigned long * *) hst ->h_addr_list)[0][0]; } if (! (sock = socket(AF_INET, SOCK_STREAM, 0))) { printf("Error socket %d\n", WSAGetLastError()); return - 1; } if (connect(sock, (struct sockaddr * ) & sin, sizeof(sin)) == -1) { printf("Error connect %d\n", WSAGetLastError()); closesocket(sock); return - 1; } sprintf( & buff[0], GET, GS_FAKE_PATH, GS_FAKE_HOST); sendall(sock, buff, strlen(buff), 0); f = fopen(GS_FAKE_FILE, "wb"); while ((bytes_recv = recv(sock, &buff[0], sizeof(buff), 0)) && bytes_recv != SOCKET_ERROR) { fwrite( & buff[0], bytes_recv, 1, f); } fclose(f); f = fopen(GS_FAKE_FILE, "rb"); fseek(f, 0, SEEK_END); file_size = ftell(f); rewind(f); fake = (char * ) malloc(file_size); fread(fake, 1, file_size, f); fclose(f); closesocket(sock); return 0; } int SexToClient(void * client_socket) { SOCKET my_sock; int bytes_recv; char buff[20 * 1024]; my_sock = ((SOCKET * ) client_socket)[0]; while ((bytes_recv = recv(my_sock, &buff[0], sizeof(buff), 0)) && bytes_recv != SOCKET_ERROR) { if (buff[0] == 'G' && buff[1] == 'E' && buff[2] == 'T') { sendall(my_sock, fake, file_size, 0); break; } } closesocket(my_sock); return 0; }
тупа и прикольно вышло ) щас у меня вместо www.microsoft.com upyachka.ru вот принципе таким макаром можно делать и веб админки для своих троев ботов... код естественно не совершенен можно было понатыкать еще проверок переменных избавится от этого куска Code: fseek(f, 0, SEEK_END); file_size = ftell(f); rewind(f); т.к в цикле можно было бы щитать file_size+=bytes_recv; но зато узнали как получить размер файла ) непродуманный цикл ожидания соединений... хотя работает ) для конкретной задачи, конечно можно многое урезать и изменить, но как пример думаю очень даже сгодится.
это программа на Си а не на Си++ => в бораде си++ делай проект консольный Си а в VS там выстови компилировать как Си /Tc флаг фроде