Трояны в последнее время очень актуальны, так как используются повсеместно . А главное очень эффективны и просто не заменимы в натягивании ламерюг . Но обычно все используют уже готовые, непонятно как сделанные и кривые трояны, которые выкачиваются где-то в инете… Но при желании можно написать троян и самому, как именно — читай дальше. Надоело тянуть файлы с помощью MAPI с удаленного компьютера? Придется писать троян, но уже управляемый по протоколу TCP/IP. Эта статья тебе в этом и поможет. В ней приведены основные приемы, используемые для «изготовления вируса в домашних условиях» в Delphi. Сразу оговоримся, что не описано в данном материале: — как пользоваться MAPI и прятать приложение от посторонних глаз (доходи сам или посмотри Хакер намбер 4) — описания обработки исключительных ситуации (EXCEPTIONS) — try..except..finally и F1 — как сделать крутой юзерский интерфейс (DELPHIDEMOS — там этого добра полно) — как клепать троян для WinNT/Win2000 (некоторые фичи нашего трояна будут работать под NT, а некоторые — нет, программа рассчитана на 95/98, если разберешься — без проблем будет написать под другие ОС) Просто если описывать всё, то статья будет весить больше, чем твоя операционная система . Серверная часть С чего начать писать троянский вирус — естественно с серверной части (это та, которая отправляется жертве). Отркрываем Дельфи. Если у тебя при входе в Help-About появляется что-то типа этого 1.jpg (99421 bytes) то скорее всего, компиляция пройдет без багов. В остальных случаях приедтся провести «косметический ремонт» из-за несоответствия вресий. Что же нужно хорошему трояну ? Правильно, язык. Он нужен для того, чтобы общаться с клиентской частью. Этот самый язык описан в файле link.pas, который можно найти в архиве. Короче в uses добавляй link.pas. Открыв этот файл, ты увидишь там описание двух классов — TTrojanServerSocket и TTrojanClientSocket. Оба они были переделаны соотвественно из TClientSocket и TServerSocket. Зачем? Метод Create стандартных дельфийских сокетов как параметр использует AOwner: TComponent. В самом методе есть строка inherited Create, означающая вызов Create с обращением к предку, то есть к AOwner. Но в трояне очень часто не бывает формы, и поэтому пришлось переделать описание этих двух классов так, чтобы они не юзали «предка». Класс TTrojanClientSocket был описан на всякий случай — вдруг тебе захочется сделать вирус, который сам кем-нибудь управляет… Нас интересует весьма ограниченный набор возможностей стандартного виндового сокета, а именно чтение/запись события OnConnect/OnDisconnect. Поэтому и обращать внимание стоит только на эти элементы. Можно начинать маскироваться… Куда полез? Форму прибивать? Нет, мы обойдемся без убийств и криминала. Открой файл проекта (*.dpr). Нажми на клавишу View Unit. Выбираешь имя проекта и видишь что-то типа: Код: program Project1; uses Forms, Unit1 in ‘Unit1.pas’ {Form1}; {$R *.RES} begin Application.Initialize; Application.CreateForm(TForm1, Form1); Application.Run; end. Увидел? Молодец! Теперь между Application.Initialize; и Application.CreateForm(TForm1, Form1); вставь такую строку : Application.ShowMainForm := False; Вот тебе и маскировка. Теперь главная форма (Form1 в Unit1) будет существовать, но об этом уже никто не узнает. Даже операционная система, которая не сможет передать фокус невидимому окну . Маленькая загвоздка — операционная система будет прекрасно знать о существовании самого приложения. Догадываешься что делать? Правильно! Как скрыть узнай сам в инете. Проще загуглить.Но если ты запустишь вирь под энтей или 2000, то в окне TaskManager ты увидишь 3.jpg (138830 bytes) Предложение таково — назови серверную часть как-нибудь типа: sysapp32.exe, только будь внимателен — вдруг такой файл уже существует. Когда троян пропал из поля видимости немного отмороженной таблички CTRL+ALT+DEL’a, можно приступать к действиям «под покровом ночи». «Почему бы не построить весь механизм соединения на TPowersock» — спросишь ты. Были и такие мысли, но потом было решено, что TPowersock не есть рулез. Но и не есть SUXX. В Delphi 5 все компоненты от NetMasters впечатали в так называемые DCU (*.dcu, Delphi Compiled Unit). Delphi их понимает, а программист — нет. Если хочешь, можешь конечно попробовать разобраться в файле в двоичном коде . Поэтому смело варим (объявляем в секции var) переменную типа TTrojanServer. Прежде чем юзать эту переменную, нужно ее заинитить. А вот здесь — стоп! Многие привыкли инициализировать все при событий OnFormShow. Не забудь, что это событие в нашем случае не наступит никогда (Application.ShowMainForm := False). Поэтому все пишем в OnFormCreate. Пусть переменная, которую ты объявил, называется v1. Тогда в OnFormCreate ты должен написать : v1 := TTrojanServerSocket.Create(nil); Nil — это указатель на компонент-родитель, которого не существует. Аналог C++ NULL если интересно. Теперь нужно указать порт, по которому троян будет связываться с клиентской частью. Если ты думаешь, что это тоже самое, что COM1, COM2, LPT1 и так далее, то ты ошибаешься. Это порт виндового сокета, номер которого можно выбирать как угодно. Например, можно установить порт равным своему возрасту, или возрасту любимой бабушки. Но учти, что порт 25 занят SMTP, а порт 110 занят POP3. Поэтому лучше скачай себе RFC и выбери там свободный порт. В примере порт равен 4456 : v1.Port := 4456; Все готово к приему данных… Вернее почти все. Осталась самая малость — открыть сокет и подготовить его к приему данных. Это можно сделать двумя способами : 1) v1.Open; 2)v1.Active := True; Теперь тебе нужно подготовить остальные системы трояна к обработке поступившей информации. Сделать это можно используя событие OnClientRead. v1.OnClientRead := v1.ServRead; Заметь, что ServRead — это метод, подходящий под определение TSocketNotifyEvent, а не обычная процедура. ServRead, описание которого также приведено в link.pas, автоматически будет связываться с процедурой из другого модуля. Иными словами, при получении данных активизируется событие, к которому мы привязываем механизм отправки поступивших данных в механизм, который их проанализирует. Вот как описан метод ServRead в Link.pas: Код: procedure TTrojanServerSocket.ServRead(Sender: TObject; Socket: TCustomWinSocket); begin RecognizeCommand(Socket.ReceiveText); end; То есть вызывается некая процедура RecognizeCommand, как единственный параметр которой передается полученная информация. К описанию RecognizeCommand мы вернемся поздее. Вот еще одна важная функция: Код: procedure SendMsgToClient(msg : ShortString); begin MainSock.Connections[0].SendText(msg); end; Здесь все ясно. Она служит для обратной связи. Через нее идут все данные к клиентской части. Данные получены, осталось их обработать. Как наименее безболезненно определить, что требуется от виря? Куча if-ов только будет загромождать исходник, а эффективность не такая уж высокая. Намного удобнее использовать индексы команд. Т.е. 1 — команда A, 2 — команда B, 3 — команда C и т.д. Чем проще? А тем, что если команды пронумерованы, можно использовать функцию case. На этом и построена RecognizeCommand (utils.pas). Вот ее код: Код: procedure RecognizeCommand(Directive : String); var cn : Integer; funcParams : ShortString; TTU : TTrojanUtilites; begin cn := StrToInt(SelectChars(Directive,0,0)); funcParams := SelectChars(Directive,1,Length(Directive)); case cn of 1 : TTU.RestartMachine; 2 : TTU.SendFile(funcParams); 3 : TTU.ReadRegistry(funcParams); 4 : TTU.WriteRegistry(funcParams); 5 : TTU.OperateCD; 6 : TTU.ExecuteFile(funcParams); 7 : TTU.DeleteFile(funcParams); 8 : TTU.DeleteMouse; 9 : TTU.SwapMouseButtons; else SendMsgToClient(‘ERR: Command not recognized or invalid !’) ; end; end; Здесь применяется функция SelectChars, описанная в utils.pas. Она выбирает n символов из заданной строки с позиции x. Если программировал(уешь) на Бейсике, то это всего-навсего MID$. Вернемся к RecognizeCommand. Первая строка извлекает из пришедших данных первый символ и переводит его в Integer, чтобы case мог с ним работать. Вторая строка загоняет все остальное в переменную funcparams. Далее идет выбор команды, и соотвественно, выполнение процедуры. Если процедур