Вход на хостинг
IT-новости
20.04.2016 iPhone 2017 года поместят в водонепроницаемый корпус из стекла
Линейка iPhone в новом году серьезно поменяется. В этом уверен аналитический исследователь Мин Чи Ку......
30.07.2015 Ищем уникальный контент для сайта
Ищем уникальный контент для сайта Без уникального контента Ваш сайт обречен на то, что его страницы......
Остается подготовить структуру STARTUPINFO, сопоставив дескрипторы стандартного ввода/вывода наследуемым каналам, и ни в коем случае не забыть взвести флаг STARTF_USESTDHANDLES, иначе факт переназначения стандартных дескрипторов будет наглым образом проигнорирован.
Однако это еще не все, и самое интересное нас ждет впереди! Для связывания каналов с сокетом удаленного терминала нам потребуется реализовать специальный резидентный диспетчер, считывающий поступающие данные и перенаправляющий их в сокет или канал. Вся сложность в том, что проверка наличия данных в сокете (канале) должна быть неблокируемой, в противном случае нам потребуются два диспетчера, каждый из которых будет выполняться в «своем» потоке, что, согласитесь, громоздко, некрасиво и неэлегантно.
Обратившись к Platform SDK, мы найдем две полезные функции: PeerkNamePipe и ioctlsocket. Первая отвечает за неблокируемое измерение «глубины» канала, а вторая обслуживает сокеты. Теперь диспетчеризация ввода/вывода становится тривиальной.
Листинг 8. Ключевой фрагмент полноценного удаленного shell вместе с диспетчером ввода/вывода
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.bInheritHandle = TRUE; // allow inheritable
// handles
// create stdin pipe
if (!CreatePipe(&cstdin, &wstdin, &sa, 0)) return -1;
// create stdout pipe
if (!CreatePipe(&rstdout, &cstdout, &sa, 0)) return -1;
// cset startupinfo for the spawned process
GetStartupInfo(&si);
si.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
si.wShowWindow = SW_HIDE;
si.hStdOutput = cstdout;
si.hStdError = cstdout; // set the new handles for the child process
si.hStdInput = cstdin;