|
С/C++
Xakep, номер #048, стр. 048-087-3 //сообщаем, что к нам могут коннектиться с любого адреса addr_Sock.sin_addr.s_addr = htonl(INADDR_ANY); //говорим, что будем слушать порт 7766, можешь написать любой addr_Sock.sin_port = htons(7766); Если бы мы хотели ограничить возможные коннекты к нашему трояну каким-то ip, то написали бы inet_addr("127.0.0.1") вместо INADDR_ANY. inet_addr - очень полезная функция, которая наверняка тебе еще пригодится для программирования сокетов. Она превращает строку с адресом в формате "a.b.c.d" в long число, чтобы его впоследствии можно было использовать для свойств и т.п. Функция htons превращает целое число в удобочитаемое машиной, и если присвоить addr_Sock.sin_port не функцию htons, а только ее параметр 7766, то программа откроет любой порт, но только не тот, что мы хотим =). С помощью функции bind мы склеим созданный нами сокет listet_Sock и его свойства addr_Sock (в умных книжках эти свойства зовутся локальным адресом). Если функция вернет значение, отличное от нуля, значит, произошла какая-то ошибка, или порт уже занят другой программой, или еще что-то. В случае ошибки троян закроется с помощью команды return 0, которая говорит программе, чтобы текущая функция вернула значение 0 и вырубилась, а так как у нас функция одна, то она и вырубается вместе с нашим бедным сервером. if(bind(listet_Sock,(LPSOCKADDR)&addr_Sock, sizeof(struct sockaddr))) return 0; А этой строкой мы, наконец, начнем СЛУШАТЬ порт, то есть откроем его для соединений. Если быть точным, для одного соединения. В первом параметре мы передаем переменную-сокет, который открываем, а во втором - количество возможных коннектов, нам больше одного не надо. Как и в случае с bind`ом, при ошибке отключаем троян. if(listen(listet_Sock, 1)) return 0; Функции трояна Для того чтобы начинать принимать команды от клиента к серверу, потребуется сначала разрешить клиенту приконнектиться функцией accept. Эта функция ждет, пока кто-нибудь не присоединится к созданному нами сокету, и возвращает новый сокет, из которого мы и будем получать команды. Чтобы после первого же дисконнекта троян у нас не падал, мы должны засунуть эту функцию в бесконечный цикл while(true). В этом цикле мы будем ждать коннекта, затем запускать новый бесконечный цикл (авторы BO2K назвали этот цикл CommandLoop) для обработки получаемых от клиента команд, из которого выйдем только в случае ошибки при приеме данных. 1) Ждем коннекта 2) Обрабатываем команды 3) При ошибке закрываем существующие соединения 4) Возвращаемся к п.1 Команды будут приниматься в виде строки, первый символ которой - собственно, выбор функции, второй - разделитель, любой, а остальные - это аргумент, который мы передаем функции нашего трояна. Вот пример команды, посылаемой клиентом: "m Привет". Троян сначала примет первые два символа и проверит, есть ли у нас функция, назначенная на символ m (у нас это вывод сообщения). Затем примет еще 126 символов и загрузит нашу функцию. То есть троян в цикле принимает с помощью функции recv из созданного после коннекта сокета hack_Sock данные два раза, в первый буфер 2 байта, и во второй 126. В случае, если данные получить не удалось, CommandLoop завершится командой break, сокет закроется и сервер снова будет ждать коннекта. |