b8h ... mov ax, "primy operand" b9h ... mov cx, "primy operand" bah ... mov dx, "primy operand" bbh ... mov bx, "primy operand" bch ... mov sp, "primy operand" bdh ... mov bp, "primy operand" beh ... mov si, "primy operand" bfh ... mov di, "primy operand"Tuto podobnost vyu₧φvß nap°. virus One Half (podrobn∞ji viz dßle) pro v²b∞r dek≤dovacφho registru. Prost² souΦet hodnoty b8h a hodnoty nßhodnΘho Φφsla v rozsahu 0 a₧ 7 generuje p°φsluÜn² registr. K≤d bch b²vß viry zapov∞zen, nebo¥ ukazatel na zßsobnφk je z pochopiteln²ch d∙vod∙ tabu.
50h ... push ax 58h ... pop ax 51h ... push cx 59h ... pop cx 52h ... push dx 5ah ... pop dx 53h ... push bx 5bh ... pop bx 54h ... push sp 5ch ... pop sp 55h ... push bp 5dh ... pop bp 56h ... push si 5eh ... pop si 57h ... push di 5fh ... pop di
000 ... add 001 ... add 010 ... add 011 ... add 100 ... add 101 ... add 110 ... add 111 ... addVymaskovßnφ, resp. nastavenφ bit∙ YYY na hodnotu nßhodnΘho Φφsla z intervalu 0 a₧ 7 op∞t generuje p°φsluÜnou instrukci.
init_rnd: push dx ; uschova registru push cx push bx mov ah, 2ch ; sluzba "Cti systemovy cas" int 21h ; Obsazeni registru po provedeni sluzby: ; CH ... hodiny (0 az 23) ; CL ... minuty (0 az 59) ; DH ... sekundy (0 az 59) ; DL ... setiny sekund (0 az 99)Pro n∞kterΘ viry je generßtor pseudonßhodn²ch Φφsel tvo°en pouze tφmto volßnφm. Virus Brain nap°. pou₧φvß pro k≤dovßnφ xor-konstantu pouze hodnotu registru dl. Z rozsahu setin sekund je z°ejmΘ, ₧e virus m∙₧e vygenerovat sto r∙zn∞ k≤dovan²ch tvar∙ virovΘho t∞la.
in al, 40h ; nacteni casovace mov ah, al in al, 40h ; nacteni casovace xor ax, cx ; rozsireni na cely rozsah cisla integer xor dx, ax ; jmp short rnd_done ; skok na konec generatoruV²poΦet pseudonßhodnΘho Φφsla.
get_rnd: push dx ; uschova registru push cx push bx in al, 40h ; nacteni casovace db 05h ; add ax, hodnota patch1 patch1 dw 0 ; prvni rekurentni konstanta db 0bah ; mov dx, hodnota patch2 patch2 dw 0 ; druha rekurentni konstanta mov cx, 7 ; sedmipruchodova rnd_loop: ; smycka shl ax, 1 ; pro rcl dx, 1 ; vypocet mov bl, al ; pseudonahodneho xor bl, dh ; cisla jns lbl ; inc al ; lbl: loop rnd_loop rnd_done: ; ukonceni generovani mov patch1, ax ; naplneni mov patch2, dx ; rekurentnich konstant mov al, dl ; "doladeni" vysledku pop bx ; obnova registru pop cx pop dx retn ; pseudonahodne cislo je v registru AXV t∞le polymorfnφ Φßsti viru je pak generßtor volßn instrukcemi "call init_rnd" pro poΦßteΦnφ nastartovßnφ generßtoru a "call get_rnd" pro zφskßnφ pseudonßhodnΘho Φφsla. ZφskanΘ pseudonßhodnΘ Φφslo je pak pro pot°ebu danΘho maximßlnφho rozsahu 0 a₧ MAX o°ezßno instrukcφ "and ax, MAX", resp. "and al, MAX".
ff xor a1 = 5e ... k≤dovßnφ 5e xor a1 = ff ... dek≤dovßnφJak je vid∞t, po dvojφ aplikaci stejnΘho k≤dovacφho klφΦe obdr₧φme v²chozφ bajt. U t∞chto vir∙ m∙₧eme nejΦast∞ji nalΘzt tuto typickou posloupnost instrukcφ, plnφcφ funkci dek≤dovacφ rutiny:
mov bx, adresa pocatku zakodovaneho tela mov dl, (od)kodovaci xor-konstanta mov cx, delka zakodovaneho tela v bajtech vlasti_smycka: xor cs:[bx], dl ; vlastni odkodovani inc bx ; posun na dalsi zakodovany bajt loop vlastni_smyckaSamoz°ejm∞, m∙₧e se liÜit pou₧itφ n∞kter²ch registr∙ Φi lze p°φpadn∞ dek≤dovat mφsto bajt∙ slova, ale princip v₧dy z∙stßvß tent²₧. Uvedenß metoda je navφc velice v²hodnß z d∙vodu univerzßlnosti tΘto rutiny jak pro k≤dovßnφ tak i pro dek≤dovßnφ.
start: ; puvodni program (virovy lapac) jmp go db 1536 dup (0) ; velikostni vypln (1536=600h) go: int 20hInfikovan² program, tvo°en² v naÜem p°φpad∞ pouze velikostnφ v²plnφ, je nßv∞Ütφmi dekodΘru tvrd∞ p°epsßn. P°epsanΘ Φßsti jsou uschovßny v zak≤dovanΘm t∞le viru a p°ed pozd∞jÜφm p°edßnφm °φzenφ infikovanΘmu programu virus zajiÜ¥uje jejich obnovu, tak₧e u₧ivatel za b∞₧n²ch okolnostφ nic nepoznß. Tento postup navφc vy°azuje z Φinnosti odvirovacφ programy pracujφcφ na principu univerzßlnφho cleanu. LΘΦba takto zavirovan²ch program∙ b²vß realizovßna zejmΘna jedno·Φelov²mi programy.
start: ; zavirovany tvar jmp lbl_5 ; skok na vstupni navesti dekoderu
db 542 dup (0) ; cast zavirovaneho programu
lbl_1: ; vlastni dekodovani ss: xor [si], di ; xor [indexovaci registr], dekodovaci registr nop jmp lbl_4
db 18 dup (0) ; cast zavirovaneho programu
lbl_2: ; otestovani priznaku ukonceni dekodovani jnz lbl_1 ; jne lbl_1 nebo jnz lbl_1 stc cs: std jmp virus_entry ; ukonceni dekodovani
db 47 dup (0) ; cast zavirovaneho programu
lbl_3: pop ds ; pouze moznost pop ds nop jmp lbl_10
db 71 dup (0) ; cast zavirovaneho programu
lbl_4: ; akutualizace dekodovaci konstanty add di, 2eefh ; add dekodovaci registr, konstanta jmp short lbl_6
db 38 dup (0) ; cast zavirovaneho programu
lbl_5: push ax ; pouze moznost push ax stc cld jmp lbl_9
db 33 dup (0) ; cast zavirovaneho programu
lbl_6: ; posun na dalsi zakodovane slovo ds: stc cs: inc si ; inc indexovaci registr jmp short lbl_7
db 9 dup (0) ; cast infikovaneho programu
lbl_7: ; test, je-li vse dekodovano cmp si, 14ddh ; cmp indexovaci registr, ; offset pocatek_zakodovaneho_viru + delka viru jmp lbl_2
db 142 dup (0) ; cast infikovaneho programu
lbl_8: ; uvodni naplneni dekodovaciho registru mov di, 0ce3bh ; vyber dekodovaciho registru ax, bx, cx, dx, bp, si, di ; s ohledem na kolizi s indexovacim registrem ; a jeho naplneni pocatecni dekodovaci konstantou cld sti cld jmp lbl_1
db 50 dup (0) ; cast infikovaneho programu
lbl_9: cld cmc push ss ; push cs nebo push ss clc jmp lbl_3
db 354 dup (0) ; cast infikovaneho programu
lbl_10: ; nastaveni pocatecniho mista pro dekodovani mov si, 705h ; vyber indexovaciho registru bx, si, di ; a jeho naplneni hodnotou offset pocatek_zakodovaneho_viru jmp lbl_8
db 164 dup (0) ; cast infikovaneho programuVelikostnφ souΦet db-v²plnφ infikovanΘho programu Φinφ 1468 bajt∙, zbyl²ch 68 bajt∙ je dΘlka samotnΘho dekodΘru.
go: int 20h ; zbytek infikovaneho programu
pocatek_zakodovaneho_viru: Zakodovane telo viru One HalfPln∞ polymorfnφ mechanismus, na rozdφl od semi-polymorfnφch p°edch∙dc∙, zcela odsouvß do role statisty antivirovΘ scannery pracujφcφ na principu virov²ch identifikaΦnφch °etezc∙. KlφΦem k detekci polymorfnφch vir∙ je heuristickß metoda anal²zy k≤du programu.
P°φklad souboru p°ed zavirovßnφm... |
...a po zavirovßnφ virem OneHalf.3544. VÜimn∞te si deseti krßtk²ch programk∙, kterΘ jsou nßhodn∞ rozneseny p°ed samotn²m virem. Tyto progrßmky jsou navzßjem propojeny skoky, a dohromady tvo°φ dek≤dovacφ rutinu. Na zmatenφ antivir∙ jsou tyto krßtkΘ progrßmky plnΘ nic ned∞lajφcφch instrukcφ jako: nop, stc, clc, sti, cs:, ss:, ds:, cld, std, cmc. |
inc ax inc ax add ax,4 inc ax add ax, 1 sub ax,2Stejn∞ tak i plnφcφ instrukci "mov ax, 606h" lze realizovat zaml₧ujφcφm postupem:
mov ax, 202h ; AX=202h mov bx, 101h ; BX=101h add ax, bx ; AX=303h shl ax, 1 ; nasobeni dvema => AX=606hObdobn²m zp∙sobem mohou nereverzibiln∞ zam∞°enΘ viry modifikovat pou₧itφ skokov²ch instrukcφ prost°ednictvφm skok∙ p°es pomocnß nßv∞Ütφ, p°φp. instrukci cyklu "loop" mohou nahradit posloupnostφ instrukcφ "dec cx" a "jnz navesti_smycky" apod. Dß se °φci, ₧e mo₧nosti jsou omezeny pouze fantaziφ a schopnostmi virov²ch pisatel∙.
start: dec bp ; priznak zavirovaneho souboru jmp dekoder ... infikovany program ...
dekoder: mov bp, 0a16ch ; bp=a16c mov cl, 3 ror bp, cl ; bp=942d mov cx, bp mov bp, 856eh ; bp=856e or bp, 740fh ; bp=f56f mov si, bp mov bp, 3b92h ; bp=3b92 add bp, si ; bp=3101 xor bp, cx ; bp=a52c sub bp, 0b10ch ; bp=f420Uvodnφ Φßst dekodΘru pouze maskuje v²znamov∞ jedinou instrukci "mov bp, 0f420h". Tato hodnota slou₧φ v nßsledujφcφ smyΦce k bßzovΘ Φßsti adresy zak≤dovanΘho t∞la viru.
smycka: mov bx, [bp + 0d23h] ; poprve - mov bx, [0143] add bx, 9d64h ; vlastni dekodovani xchg [bp + 0d23h], bx ; a opetovne ulozeni zpracovaneho slovaVirus refinovan∞ vyu₧φvß p°eteΦenφ v²sledku souΦtu hodnot bp a 0d23h; nastavenφ p°φznaku CF je v tomto p°φpad∞ nepodstatnΘ.
mov bx, 8f31h sub bx, bp ; 9b11 mov bp, 8f33h sub bp, bx ; bp=f422 (tj. add bp,2) jnz smyckaInstrukce posunu algoritmu na dalÜφ zak≤dovanΘ slovo ("add bp, 2") je op∞t zamaskovßna. PoΦßteΦnφ bßzovß hodnota f420h nenφ nßhodnß, ale je vybrßna s ohledem na po₧adovan² poΦet 1520 iteracφ, co₧ odpovφdß, vzhledem ke slovnφm operacφm, velikosti 3040 B zak≤dovanΘ Φßsti viru. Hodnota je dßna v²razem (64 kB - f420 + 1) / 2 = 1520.
mov bx, bp mov cl, 3 ror bx, clZßv∞reΦnß Φßst dekodΘru je slo₧ena z nev²znamn²ch instrukcφ, pomocφ nich₧ virus dosahuje prom∞nnΘ dΘlky svΘho t∞la. Je zajφmavΘ sledovat, ₧e nev²znamn²mi instrukce nejsou pouze jednobajtovΘ instrukce typu "nop" Φi "cmc", ale podstatn∞ komplikovan∞jÜφ konstrukce.
segment:0143 ... zakodovana cast tela viru Pogue ...
Zdroj: Computer Press, ???