Там, дзе вечар на зямлю сыпле зор манiсты, Я злаyлю, цябе злаyлю, выпуск наравiсты. Праз палеткi i лясы, праз лугi, паляны, Ты нясi, яго нясi, Iнэт незацугляны. Ты нясi, яго нясi, Iнэт незацугляны. Что у нас сегодня? Спасибо всем, кто посетил наш сайт и оставил в Гостевой книге информацию! Многие жалуются, что страница стала загружаться дольше. Что ж, я "ужал" все, что можно было. Ко мне приходит много писем с просьбой подсказать где найти ту или иную информацию. Друзья мои! Ну не знаю я, где можно все найти. Могу подсказать два адреса (один из которых был опубликован в предыдущем выпуске): Надеюсь, там вы найдете то, что вам нужно. Вот письмо (отрывок) от подписчика Сани, который в прошлом выпуске просил помощи по BIOS: Если есть какая возможность и тебя это не затруднит, поблагодари всех, кто откликнулся на мою просьбу о помощи!!! С уважением, Саня. Всем спасибо! Сегодня рассылка небольшая, но информативная. Из нее вы узнаете, как поместить вирус временно в память, как передать ему управление, как пытаться найти файл... Ну что, поехали писать вирус... Мы будем заражать ТОЛЬКО *.COM-файлы! Если будет время и желание у вас, то можем написать вирус, заражающий и *.EXE-файлы.
Как вы знаете, com-файл сразу начинается с кода, первый байт которого располагается в свободном сегменте по смещению 100h. Следовательно, нам нужно будет сохранить в теле нашего вируса первые три байта "файла-жертвы", записать наш вирус в "хвост" файла и вместо сохраненных трех байт установить команду jmp на начало нашего вируса (т.е. передать ему первому управление). После того, как вирус отработал свое, восстановить сохраненные три байта (записать их в памяти по адресу 100h) и передать им управление. На практике все будет понятней... Получается примерно так: Программа до заражения (следите за адресами): ________ 1234:0100h mov ax,34 ; код программы до заражения, расположенный по адресу 100h 1234:0103h mov dx,15 ; здесь может быть все, что угодно... Но нам-то все равно... 1234:0106h add ax,bx 1234:0108h .... и т.д. ... 1234:0500h int 20h ; последний байт программы 1234:0502h --- здесь идет уже свободная память... Программа после заражения: ___________ 1234:0100h jmp 0502h ;прыгаем на начало нашего вируса (заменили мы байты здесь) 1234:0103h mov dx,15 ;а это байты "файла-жертвы" 1234:0106h add ax,bx ... 1234:0500h int 20h 1234:0502h --- а здесь уже начинается код нашего вируса. ... --- здесь тело вируса. Делаем, что хотим... 1234:0700h mov word ptr cs:[0100h], First_bytes_1 ;восстановим первые два байта "файла-жертвы" 1234:0705h mov byte ptr cs:[0102h], First_bytes_2 ;восстановим третий байт "файла-жертвы"... ; Теперь по адресу 100h первые два байта не jmp 502h, а mov ax,34 (т.е. оригинальный код программы) ; Вспоминаем из прошлых выпусков о том, что в Ассемблере можно менять код программы "на лету"... ; Все это меняется только в памяти, а не на диске! 1234:0709h jmp 0100h ; ...и перейдем по адресу 100h, т.е. передадим управление программе ___________ Сложновато? Сравните два куска кода: незараженной программы и зараженной. Должно быть все понятно... Сейчас будем практиковаться... Возьмите, пожалуйста, файл здесь: http://www.Kalashnikoff.ru/Assembler/Programs/Lessons/Virus13.rar Если у вас нет выхода в Сеть, то напишите мне письмо с просьбой выслать. Я также включу ваш адрес в базу данных. Затем перед выходом очередной рассылки вы получите этот файл по почте. Первая строка - .286 - указывает Ассемблеру, что будем использовать инструкции (команды, операторы) 286 процессора. Т.е. на 8086 компьютере наш вирус уже работать не будет! С первого же байта перейдем на метку Init (инициализации нашего вируса). Сразу же возникает проблема: при поиске файла функцией DOS мы затираем DTA "программы-жертвы". И тут же возникает вторая проблема, точнее, вопрос: что такое DTA и для чего оно нужно? Полную информацию об этом можно найти в программе helpassm, которую я рекомендую скачать с нашего сайта. В этой рассылке мы рассмотрим только то, что нас интересует (пока!). Как вы помните, все *.com-программы начинаются с адреса 100h (org 100h). Что же находится в памяти от 0 до 100h? Там расположен PSP (Program Segment Prefix - префикс программного сегмента). По адресу 80h находится по умолчанию DTA (Data Transfer Area - область переноса данных). В DTA записывается информация, когда функция поиска файла (4Eh и 4Fh) находит очередной файл. Все вроде бы и ничего, но проблема в том, что по этому адресу (80h) располагается изначально командная строка. Например: format.com c:/s/u По адресу CS:0080h будет находится: L_c:/s/u, где L - длина командной строки, а _ - символ пробела. Для того, чтобы удостовериться, запустите отладчик AFD так: afd.exe format c:/s/u Затем посмотрите, что будет находиться по адресу CS:0080h. К чему все это? Да к тому, что когда мы попробуем искать первый файл, то, найдя его, мы затрем командную строку (L_c:/s/u). Получается, что "программа-жертва", к которой мы "подцепились" не сможет прочитать те параметры, которые ей передал пользователь. В данном случае - это L_/s/u. Есть два способа обойти это. 1. Сохранить PSP программы перед поиском файла. А затем, как наш вирус отработал, восстановить его. 2. Установить DTA на другую область памяти, а затем восстановить его. Это позволяет сделать функция 1Ah прерывания 21h:
Мы выберем второй путь. Далее возникает еще одна проблема: мы теряемся в адресах. Т.е. мы занесем наш сассемблированный код в конец программы, при этом смещения все поменяются. Например: mov dx,offset String Ассемблер занесет в DX смещение строки String в памяти. Фактически - после ассемблирования - это будет выглядеть так: mov dx,125h --- какое именно число - не важно. Главное, что в DX будет находиться адрес (смещение) строки в памяти, отсчитывающееся от 0. Но мы-то запишем код нашего вируса в конец программы, включая все строки и прочие области данных! Получается, что строка в памяти будет находится по одному адресу, а в регистры будет загружаться совсем другой адрес! Вот пример: 1234:0100h mov dx,400h --- в неассемблированном варианте это выглядит, как mov dx,offset String. Т.е. Ассемблер заменит offset String на адрес (смещение) этой строки в памяти, начиная от нуля. ... 1234:0400h 'Строка' --- а вот и строка, которая расположиться по такому адресу. Она может расположиться и по любому другому (надеюсь, вы понимаете почему?), но суть не в этом. Теперь, представим, что "файл-жертва" занимает 100h байт. Мы записываем наш код в конец файла. Получается, что строка будет находиться по такому адресу: 1234:0400h + 100h = 1234:0500h! Хорошо бы было, если бы все файлы имели одну длину. Но один файл может быть 100 байт, а другой 23000 байт! В итоге, обращаясь к строке в зараженной программе, мы получаем: 1234:0200h mov dx,400h --- 200h потому, что 100h байт занимает "файл-жертва", а мы в "хвосте" у него... ... 1234:0400h --- все, что угодно, но только не наша строка. ... 1234:0500h 'Строка' --- вот, где она будет! Можно, конечно, перед заражением получить длину "файла-жертвы" и затем заменить mov dx,400h на mov dx,500h. Но что делать, если таких ссылок много? Представляете, до каких размеров разрастется наш вирус?! Мы поступим иначе: просто возьмем и перенесем вирус (и только вирус!) с "хвоста" "файла-жертвы" в свободный сегмент со смещения 100h. Вот, что получится: До перемещения: 1234:0200h mov dx,400h --- мы в хвосте программы .... 1234:0500h 'Строка' ____________ После перемещения: 5678:0100h mov dx,400h --- перебросили себя в сегмент 5678h, по смещению 0100h .... 5678:0400h 'Строка' --- строка стала на свое место (смещение)!!! ____________ Еще вопрос: где гарантия того, что в данном сегменте никого нет, и мы не затрем код какой-нибудь программы? Я предлагаю временно (т.е. на тот момент, пока работает вирус) переслать наш вирус в адрес 8-ой страницы дисплея. Видеокарта имеет достаточно памяти для размещения восьми страниц. Эти страницы, кроме первой или нулевой, если отсчет вести с нуля), почти никогда не используются программами. Более того известны точные сегменты этих страниц. Вот они: __________________ 0B800 - нулевая 0B900 - первая 0BA00 - вторая 0BB00 - третья 0BC00 - четвертая 0BD00 - пятая 0BE00 - шестая 0BF00 - седьмая __________________ Давайте посчитаем размер одной страницы. Хватит ли нам места для того, чтобы разместить на ней код вируса? Наш вирус будет занимать не более 300-400 байт. Возьмем известный вам режим 3: в одной строке 80 символов, строк на экране 25. Один символ занимает два байта (атрибут / смещение). Получаем: 80 x 25 x 2 = 4000 байт. Хватит ли нам этого? Конечно хватит! Даже, если бы не хватало, ты мы могли бы использовать две, три, четыре страницы. Т.о. пересылаем себя в область седьмой (если считать с нуля) видеостраницы, что мы и делаем сразу же за меткой Init. Код нашего вируса на экране не будет отображаться, т.к. обычно текущей стоит 0-ая страница. Хотя, если хотите, можете проверить это... Думаю, что вам не составит труда разобраться в новом операторе movs. Принцип его работы полностью соответствует команде stos. Вот его описание:
При этом DS:SI указывает на то, откуда брать данные, ES:DI куда их копировать, а CX - количество пересылаемых байт / слов. Вот примеры: _________________ ... mov cx,10 ;количество пересылаемых байт mov si,offset Str1 ; откуда будем брать mov di,offset Str2 ; куда копировать rep movsb ; Пересылаем побайтно, т.к. movsB. Теперь Str1 = Str2 ... Str1 db '0123456789' Str2 db '9876543210' _________________ Можно так: _________________ ... mov cx,5 ;количество пересылаемых слов (два байта) mov si,offset Str1 ; откуда будем брать mov di,offset Str2 ; куда копировать rep movsw ; Пересылаем пословно (по два байта), т.к. movsW. Теперь Str1 = Str2 ... Str1 db '0123456789' Str2 db '9876543210' _________________ Итак, теперь наш вирус есть в двух местах в памяти: 1. сразу за "программой-жертвой"; 2. в области 7-ой страницы (0BF00:0100h). Нам осталось прыгнуть на адрес 0BF00:IP. Как известно, CS:IP всегда показывают текущее операцию (адрес текущей операции). Обратите внимание, как мы прыгаем: jmp dword ptr cs:[Off_move] Посмотрите, что содержит переменная Off_move, а также посмотрите в отладчике, что будет происходить с регистрами CS:IP. Все станет на свои места... Подсказка: начиная с метки Lab_jmp мы работаем в области 7-ой видеостраницы... Затем мы устанавливаем DTA в область 7-ой видеостраницы со смещения 0. Туда будет записываться информация о найденных файлах для заражения. Теперь можно попробовать найти первый *.com-файл в текущем каталоге. Для этого используется функция 4Eh прерывания 21h:
CF - это флаг переноса. Если написано CF=1, то это значит, что флаг переноса установлен (равен 1), а если CF=0, то сброшен (равен 0). Флаг переноса используется DOS для индикации ошибки функции или для других целей. В данном случае, если функция 4Eh установила флаг переноса, то это значит, что файлов, удовлетворяющих условию (маске поиска), не было найдено. Если флаг переноса сброшен (равен нулю), то в DTA заносится информация о файле. Ее мы рассмотрим в последующих выпусках. Если CF = 0 (сброшен флаг переноса), то можно что-нибудь сделать с найденным файлом. Для того, чтобы найти следующий файл, удовлетворяющий нашему условию (маске поиска), необходимо воспользоваться функцией 4Fh прерывания 21h:
Все также, как у функции 4Eh. Хочу заметить, что вирус у нас пока неработоспособный. Т.е. он ничего не заражает вообще! Можете спокойно его ассемблировать и запускать. Только мало что увидите на экране. Лучше это дело смотреть под отладчиком. Дальше все просто! Я думаю, что описаний в программе достаточно для того, чтобы понять принцип работы программы. До встречи через неделю! С уважением,
|